<?php
function generate_xor_key($length)
{
$result = array_fill(0, $length, 0);
for ($i = 0, $bit = 1; $i < $length; $i++) {
for ($j = 0; $j < 3; $j++, $bit++) {
$result[$i] |= ($bit % 2) << $j;
}
}
return implode('', array_map('chr', $result));
}
function encode_id($id, $encodedLength = 7, $rawBits = 16, $key = null)
{
$maxRawBits = $encodedLength * 3;
if ($rawBits > $maxRawBits) {
trigger_error('encode_id(): $rawBits must be no more than 3 times greater than $encodedLength');
return false;
}
if ($key === null) {
$key = generate_xor_key($encodedLength);
}
$result = array_fill(0, $encodedLength, 0x30);
for ($position = 0; $position < $rawBits; $position++) {
$bit = (($id >> $position) & 0x01) << floor($position / $encodedLength);
$index = $position % $encodedLength;
$result[$index] |= $bit;
}
do {
$index = $position % $encodedLength;
$bit = ($position % 2) << floor($position / $encodedLength);
$result[$index] |= $bit;
} while (++$position < $maxRawBits);
return implode('', array_map('chr', $result)) ^ $key;
}
function decode_id($id, $encodedLength = 7, $rawBits = 16, $key = null)
{
if ($key === null) {
$key = generate_xor_key($encodedLength);
}
$bytes = array_map(
'ord',
str_split(
str_pad($id, $encodedLength, '0', STR_PAD_LEFT) ^ $key,
1
)
);
$result = 0;
for ($position = 0; $position < $rawBits; $position++) {
$index = $position % $encodedLength;
$bit = (($bytes[$index] >> floor($position / $encodedLength)) & 0x01) << $position;
$result |= $bit;
}
return $result;
}
//$key = "\x07\x04\x02\x03\x07\x04\x02";
for ($i = 1; $i <= 1048576; $i++) {
if (preg_match('/\D/', encode_id($i, 7, 20, $key))) {
echo "Fail at $i\n";
}
}
preferences:
39.61 ms | 402 KiB | 5 Q