Skip to content

Instantly share code, notes, and snippets.

@rseon
Last active November 9, 2018 10:25
Show Gist options
  • Save rseon/2f3c84a6cf97dd9ee14f636670d02565 to your computer and use it in GitHub Desktop.
Save rseon/2f3c84a6cf97dd9ee14f636670d02565 to your computer and use it in GitHub Desktop.
Convert numbers and strings into Shadok
<?php
/**
* Shadok 1.2
*
* This class converts numbers and strings into Shadok.
* Only for fun.
*
* @changelog
* 1.2 - Support strings
* 1.1 - Add Shadok alphabet
* 1.0 - First version (convert numbers)
*
* @example Converts strings (only ASCII, without accents and special characters) :
* Shadok::stringFromHuman('RSeon'); // BUBUGAZO BUBUGAMEU BUZOBUBU BUZOMEUMEU BUZOMEUZO
* Shadok::stringToHuman('BUBUGAZO BUBUGAMEU BUZOBUBU BUZOMEUMEU BUZOMEUZO'); // RSeon
*
* @example With Shadok alphabet :
* Shadok::stringFromHuman('RSeon', true); // −−O⨼ −−O◿ −⨼−− −⨼◿◿ −⨼◿⨼
* Shadok::stringToHuman('−−O⨼ −−O◿ −⨼−− −⨼◿◿ −⨼◿⨼'); // RSeon
*
* @example Converts numbers (only integers) :
* Shadok::numberFromHuman(2018); // BUMEUMEUZOGAZO
* Shadok::numberToHuman('BUMEUMEUZOGAZO'); // 2018
*
* @example With Shadok alphabet :
* Shadok::numberFromHuman(2018, true); // −◿◿⨼O⨼
* Shadok::numberToHuman('−◿◿⨼O⨼'); // 2018
*
* @link https://www.dcode.fr/numeration-shadok
* @link http://www.fil.univ-lille1.fr/~wegrzyno/portail/Info/Doc/HTML/tp_numeration_shadok.html
*/
class Shadok {
protected static $base = ['GA', 'BU', 'ZO', 'MEU'];
protected static $alphabet = ['O', '−', '⨼', '◿'];
/**
* Get alphabet [Human => Shadok] or [Shadok => Human]
*
* @param bool
* @return array
*/
public static function getShadokAlphabet($reverse = false) {
if($reverse) {
return array_combine(self::$alphabet, self::$base);
}
return array_combine(self::$base, self::$alphabet);
}
/**
* Convert Shadok string to Human
*
* @param string
* @return string
*/
public static function stringToHuman($shadok) {
$shadok = strtoupper(str_replace(' ', '', $shadok));
$infos_number = self::_getShadokNumberInfos($shadok);
$octets = [];
$oi = 0;
foreach($infos_number['matches'] as $i => $m) {
if($i % 4 === 0) {
++$oi;
}
if(!isset($octets[$oi])) {
$octets[$oi] = '';
}
$octets[$oi] .= $m;
}
$string = '';
foreach($octets as $o) {
$string .= chr(self::numberToHuman($o));
}
return $string;
}
/**
* Convert human string to Shadok
*
* @param string
* @param bool If true, uses Shadok alphabet
* @return string
*/
public static function stringFromHuman($string, $use_alphabet = false) {
$ascii = unpack("C*", $string);
$shadok = '';
foreach($ascii as $ord) {
$shadok .= self::numberFromHuman($ord, $use_alphabet) . ' ';
}
$shadok = substr($shadok, 0, -1);
return $shadok;
}
/**
* Convert Shadok number to human number.
*
* @param string
* @return int
*/
public static function numberToHuman($shadok) {
$shadok = strtoupper(str_replace(' ', '', $shadok));
$infos_number = self::_getShadokNumberInfos($shadok);
$tmp = array_reverse($infos_number['matches']);
$number = 0;
$base = $infos_number['use_alphabet'] ? self::$alphabet : self::$base;
foreach($tmp as $i => $letter) {
$number += (array_search($letter, $base)) * 4**$i;
}
return $number;
}
/**
* Convert human number (base 10) to Shadok number
*
* @param int
* @param bool If true, uses Shadok alphabet
* @return string
*/
public static function numberFromHuman($number, $use_alphabet = false) {
if(!is_int($number)) {
throw new Exception('Please use real number');
}
$tmp = str_split(base_convert($number, 10, 4));
$shadok = '';
$base = $use_alphabet ? self::$alphabet : self::$base;
foreach($tmp as $i => $n) {
$shadok .= $base[$n];
}
return $shadok;
}
/**
* Get infos from shadok number (each character and if uses Shadok alphabet)
*
* @param string
* @return array
*/
protected static function _getShadokNumberInfos($string) {
preg_match_all('/GA|BU|ZO|MEU/', $string, $matches);
$use_alphabet = false;
if(!isset($matches[0]) || empty($matches[0])) {
preg_match_all('/O|−|⨼|◿/', $string, $matches);
if(!isset($matches[0]) || empty($matches[0])) {
throw new Exception('Please use shadok numbers ('.implode(' ', self::$base).' or '.implode(' ', self::$alphabet).')');
}
$use_alphabet = true;
}
return [
'matches' => $matches[0],
'use_alphabet' => $use_alphabet
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment