Last active
November 9, 2018 10:25
-
-
Save rseon/2f3c84a6cf97dd9ee14f636670d02565 to your computer and use it in GitHub Desktop.
Convert numbers and strings into Shadok
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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