· 7 years ago · Jul 31, 2018, 07:28 PM
1Convert auto increment ID to 9 digit random serial number
2serial = id^base mod p
3serial = 42^17 % 27407 = 24978
4
5id = serial^inv mod p
6id = 24978^12897 % 27407 = 42
7
8$secretKey = 'oh no nobody will guess this';
9$userId = 312;
10$serialNumber = hash('sha256', $secretKey . $userId);
11
12$hash = sha1("secretanswer".$userid);
13$trimmedhash = substr($has,0,9); //get a 9 digit random hash
14
15$userid = "getthissomehow";
16 $hash = sha1("secretanswer".$userid);
17 $trimmedhash = substr($has,0,9);
18
19 $prevhash = "asfaf23rfs"; //get previously stored hash somehow
20 if($trimmedhash == $prevhash) {
21 //valid
22 }
23
24$test_limit = 25;
25$test_ids = array(1, 99999999999);
26for($i=0; $i<($test_limit-2); $i++) $test_ids[] = mt_rand(1, 99999999999);
27
28foreach($test_ids as $tii=>$ti)
29{
30 $serial = getSerialUsingId($ti);
31 $id = getIdUsingSerial($serial);
32 if($id!=$ti) echo 'Test '.($tii+1).' (id: '.$ti.') FAILED! (serial: '.$serial.")n";
33 else echo 'Test '.($tii+1).' (id: '.$ti.') was a success! (serial: '.$serial.")n";
34}
35
36
37function getMask($index, $places=8)
38{
39 $masks = array
40 (
41 0xac976f4,
42 0x1c70f81,
43 0x441f67f,
44 0x5fb0b87,
45 0xf1542d2,
46 0xfa28851,
47 0x91bbd8c,
48 0x30a5448,
49 0x46a2708,
50 0x5856fbf,
51 0x65fa462,
52 0xf24337b,
53 0xea2c390,
54 0x8561da4,
55 0x9f77b25
56 );
57
58 if($places==4) return $masks[$index] & 0x0000FFFF;
59 else return $masks[$index];
60
61}// getMask
62
63
64function getSerialUsingId($id)
65{
66
67 $prepend = '';
68 $mask_index = mt_rand(0, 14);
69
70 // 8 hex places can only handle up to 4294967295
71 // If the number is greater than than that then get the additional bytes and treat separate
72 if($id>0xffffffff)
73 {
74 $packed = pack('d', $id);
75 $hex_pack = unpack('H*', $packed);
76 $hex_string = substr($hex_pack[1],4);
77 $bytes = array_reverse(explode("n", chunk_split($hex_string, 2, "n")));
78 foreach($bytes as $bi=>$b) if(!$b) unset($bytes[$bi]);
79 $truncated_bytes = array_splice($bytes,0,count($bytes)-4);
80 $truncated = implode('', $truncated_bytes);
81 $prepend = dechex(hexdec($truncated) ^ getMask($mask_index, 4));
82 }
83
84 $serial = dechex($mask_index+1).$prepend.str_pad(dechex($id ^ getMask($mask_index)), 8, '0', STR_PAD_LEFT);
85
86 return $serial;
87
88}// getSerialUsingId
89
90
91function getIdUsingSerial($serial)
92{
93 $mask_index = hexdec($serial[0])-1;
94 $serial = substr($serial, 1);
95 $prepended = false;
96 if(strlen($serial)>9)
97 {
98 $prepended = substr($serial, 0, 4);
99 $serial = substr($serial, 4);
100 }
101 $id = hexdec($serial) ^ getMask($mask_index);
102 if($prepended)
103 {
104 $unmasked_prepended = dechex(hexdec($prepended) ^ getMask($mask_index, 4));
105 $bytes = array_reverse(array_merge
106 (
107 explode("n", chunk_split($unmasked_prepended, 2, "n")),
108 explode("n", chunk_split(dechex($id), 2, "n")),
109 array('00','00')
110 ));
111 foreach($bytes as $bi=>$b) if(!$b) unset($bytes[$bi]);
112 $packed = pack('H*', implode('', $bytes));
113 $unpacked = unpack('d', $packed);
114 $id = $unpacked[1];
115 }
116
117 return $id;
118
119}// getIdUsingSerial
120
121Test 1 (id: 1) was a success! (serial: 60fa28850)
122Test 2 (id: 99999999999) was a success! (serial: 24db649b1e87e)
123Test 3 (id: 487808132) was a success! (serial: 31952aafb)
124Test 4 (id: 227726272) was a success! (serial: 40869d847)
125Test 5 (id: 836896236) was a success! (serial: 53ef7473e)
126Test 6 (id: 958345007) was a success! (serial: 93d750827)
127Test 7 (id: 164308905) was a success! (serial: 30d8ad1d6)
128Test 8 (id: 715018588) was a success! (serial: 1205727a8)
129Test 9 (id: 1127737044) was a success! (serial: 8403db29c)
130Test 10 (id: 409934489) was a success! (serial: 81b654ed1)
131Test 11 (id: 907129123) was a success! (serial: f3fe6ca06)
132Test 12 (id: 720453497) was a success! (serial: b2cae9b1b)
133Test 13 (id: 500526447) was a success! (serial: 1171c1b9b)
134Test 14 (id: 322340582) was a success! (serial: 119fff012)
135Test 15 (id: 1176988677) was a success! (serial: b4078c867)
136Test 16 (id: 698755861) was a success! (serial: 92dcc0c1d)
137Test 17 (id: 555569451) was a success! (serial: 52e0813f9)
138Test 18 (id: 227332917) was a success! (serial: a0809bc8a)
139Test 19 (id: 819326158) was a success! (serial: 334941ab1)
140Test 20 (id: 659803411) was a success! (serial: d29f10e83)
141Test 21 (id: 895574245) was a success! (serial: d3bc3a375)
142Test 22 (id: 539979792) was a success! (serial: 425d47b97)
143Test 23 (id: 933093554) was a success! (serial: 83497b4fa)
144Test 24 (id: 959556569) was a success! (serial: 93d5b8cd1)
145Test 25 (id: 668064949) was a success! (serial: 22616d334)