Skip to content

Instantly share code, notes, and snippets.

@sogrbilja
Last active March 14, 2024 18:00
Show Gist options
  • Save sogrbilja/dc40415ca36a3318000ca82318b839c2 to your computer and use it in GitHub Desktop.
Save sogrbilja/dc40415ca36a3318000ca82318b839c2 to your computer and use it in GitHub Desktop.
PseudoCrypt with user friendly 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