Last active
March 14, 2024 18:00
-
-
Save sogrbilja/dc40415ca36a3318000ca82318b839c2 to your computer and use it in GitHub Desktop.
PseudoCrypt with user friendly characters
This file contains 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 | |
//I want to use set of characters that are easy to spell out -> 123456789ABCDEFGHIJKLMNPRSTUVZ | |
class PseudoCrypt { | |
/* Key: Next prime greater than 62 ^ n / 1.618033988749894848 */ | |
/* Value: modular multiplicative inverse */ | |
/* | |
//usage: | |
PseudoCrypt::useHumanFriendlyChars(); | |
$str = '5'; | |
echo $str . ' '; | |
$str = PseudoCrypt::hash($str); | |
echo $str . ' '; | |
$str = PseudoCrypt::unhash($str); | |
echo $str; | |
// will output: 5 3M5M6 5 | |
*/ | |
private static $golden_primes = array( | |
'1' => '1', | |
'41' => '59', | |
'2377' => '1677', | |
'147299' => '187507', | |
'9132313' => '5952585', | |
'566201239' => '643566407', | |
'35104476161' => '22071637057', | |
'2176477521929' => '294289236153', | |
'134941606358731' => '88879354792675', | |
'8366379594239857' => '7275288500431249', | |
'518715534842869223' => '280042546585394647' | |
); | |
/* Ascii : 0 9, A Z, a z */ | |
/* $chars = array_merge(range(48,57), range(65,90), range(97,122)) */ | |
private static $chars = array( | |
0 => 48, 1 => 49, 2 => 50, 3 => 51, 4 => 52, 5 => 53, 6 => 54, 7 => 55, 8 => 56, 9 => 57, 10 => 65, | |
11 => 66, 12 => 67, 13 => 68, 14 => 69, 15 => 70, 16 => 71, 17 => 72, 18 => 73, 19 => 74, 20 => 75, | |
21 => 76, 22 => 77, 23 => 78, 24 => 79, 25 => 80, 26 => 81, 27 => 82, 28 => 83, 29 => 84, 30 => 85, | |
31 => 86, 32 => 87, 33 => 88, 34 => 89, 35 => 90, 36 => 97, 37 => 98, 38 => 99, 39 => 100, 40 => 101, | |
41 => 102, 42 => 103, 43 => 104, 44 => 105, 45 => 106, 46 => 107, 47 => 108, 48 => 109, 49 => 110, | |
50 => 111, 51 => 112, 52 => 113, 53 => 114, 54 => 115, 55 => 116, 56 => 117, 57 => 118, 58 => 119, | |
59 => 120, 60 => 121, 61 => 122 | |
); | |
public static function useHumanFriendlyChars() { | |
$charString = "123456789ABCDEFGHIJKLMNPRSTUVZ"; | |
self::$chars = array(); // Initialize as empty array | |
foreach (str_split($charString) as $index => $char) { | |
self::$chars[$index] = ord($char); | |
} | |
//30 base | |
self::$golden_primes = array( | |
'1' => '1', | |
'19' => '19', | |
'557' => '593', | |
'16691' => '5411', | |
'500629' => '465469', | |
'15018247' => '2946583', | |
'450546781' => '726829621', | |
'13516403347' => '20577062683', | |
'405492100019' => '605156531579', | |
'12164763000569' => '2306086771529', | |
'364942890016937' => '50936189822873' | |
); | |
} | |
public static function baseConvert($int) { | |
$key = ""; | |
$base = count(self::$chars); | |
while (bccomp($int, 0) > 0) { | |
$mod = bcmod($int, $base); | |
$key .= chr(self::$chars[$mod]); | |
$int = bcdiv($int, $base); | |
} | |
return strrev($key); | |
} | |
public static function hash($num, $len = 5) { | |
$base = count(self::$chars); | |
$ceil = bcpow($base, $len); | |
$primes = array_keys(self::$golden_primes); | |
$prime = $primes[$len]; | |
$dec = bcmod(bcmul($num, $prime), $ceil); | |
$hash = self::baseConvert($dec); | |
return str_pad($hash, $len, "0", STR_PAD_LEFT); | |
} | |
public static function unbaseConvert($key) { | |
$base = count(self::$chars); | |
$int = 0; | |
foreach (str_split(strrev($key)) as $i => $char) { | |
$dec = array_search(ord($char), self::$chars); | |
$int = bcadd(bcmul($dec, bcpow($base, $i)), $int); | |
} | |
return $int; | |
} | |
public static function unhash($hash) { | |
$base = count(self::$chars); | |
$len = strlen($hash); | |
$ceil = bcpow($base, $len); | |
$mmiprimes = array_values(self::$golden_primes); | |
$mmi = $mmiprimes[$len]; | |
$num = self::unbaseConvert($hash); | |
$dec = bcmod(bcmul($num, $mmi), $ceil); | |
return $dec; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment