Параметр шифрования числового URL, результат не должен быть длиннее исходного - PullRequest
3 голосов
/ 22 февраля 2012

Я должен зашифровать определенный параметр URL. Если я хочу, чтобы вывод был менее 6-7 символов, какой алгоритм мне использовать?

Входные данные являются целыми числами в диапазоне от 1 до 1 000 000.

Ответы [ 3 ]

6 голосов
/ 22 февраля 2012

Если вам требуется шифрование и вы хотите получить максимально короткий результат, вы должны использовать потоковый шифр. Blowfish (то, что вы использовали ранее) является блочным шифром, и результат всегда будет иметь минимальный размер одного отдельного блока.

Найдите сравнение потоковых шифров в Википедии и список поддерживаемых шифров в руководстве PHP для mcrypt

Кроме того, результат шифрования может содержать специальные символы, поэтому при помещении его в URL-адрес в качестве параметра следует использовать urlencode() или base64_encode()

Использование urlencode() или base64_encode() расширит вашу строку, сделав ее длиннее исходных данных. Это необходимо для обеспечения безопасности транспорта / URL.

Однако, поскольку ваш ввод всегда является числом, вы можете использовать base_convert(), чтобы сократить ввод. На стороне декодирования вы должны сделать то же самое.

Чтобы получить еще более короткие результаты , вы можете использовать функцию enminicode() / deminicode(), предоставленную Aron Cederholm вместо использования base_convert().

Вот пример использования потокового шифра RC4 (который, кстати, не очень силен) и преобразования из базы 10 в базу 36.

ПРИМЕЧАНИЕ: этот пример работает только с числами, поэтому он использует base_convert() для сжатия входной строки!

function my_number_encrypt($data, $key, $base64_safe=true, $shrink=true) {
        if ($shrink) $data = base_convert($data, 10, 36);
        $data = @mcrypt_encrypt(MCRYPT_ARCFOUR, $key, $data, MCRYPT_MODE_STREAM);
        if ($base64_safe) $data = str_replace('=', '', base64_encode($data));
        return $data;
}

function my_number_decrypt($data, $key, $base64_safe=true, $expand=true) {
        if ($base64_safe) $data = base64_decode($data.'==');
        $data = @mcrypt_encrypt(MCRYPT_ARCFOUR, $key, $data, MCRYPT_MODE_STREAM);
        if ($expand) $data = base_convert($data, 36, 10);
        return $data;
}

$data = "15231223";
$key = "&/ASD%g/..&FWSF2csvsq2we!%%";

echo "data: ", $data, "\n";
$encrypted = my_number_encrypt($data, $key);
echo "encrypted: ", $encrypted, "\n";
$decrypted = my_number_decrypt($encrypted, $key);
echo "decrypted: ", $decrypted, "\n";

Результат:

data: 15231223
encrypted: BuF3xdE
decrypted: 15231223
3 голосов
/ 22 февраля 2012
function enminicode($int) {
    $foo = '';
    while ($int) {
        $tmp =  $int%256;
        $int = floor($int/256);
        $foo = chr($tmp) . $foo;
    }
    return base64_encode($foo);
}

function deminicode($b64) {
    $moo = base64_decode($b64);
    $res = 0;
    for ($i = 0; $i <= strlen($moo) - 1; ++$i) {
        $res *= 256;
        $res += ord($moo[$i]);
    }
    return $res;
}

$ii = array(12, 123456, 1000000, 467, 9456724645);
foreach ($ii as $i) {
    echo $i, ': ', enminicode($i), ' => ', deminicode(enminicode($i)), PHP_EOL;
}

Какие выходы:

12: DA== => 12
123456: AeJA => 123456
1000000: D0JA => 1000000
467: AdM= => 467
9456724645: AjOqKqU= => 9456724645

Работает как брелок.Для целых чисел до 1000000 он будет использовать 4 буквы.Но не используйте это для безопасности!Безопасность по неясности никогда не является опцией, и вы никогда не пытаетесь использовать этот метод, чтобы скрыть число от пользователя, если он не должен знать об этом.

Другим более элегантным решением является использование base_convert, который будет давать несколько более длинные строки, но он все равно будет вмещаться в пределах 6-7 символов.

$int = 987654;
$convert = base_convert($int, 10, 16)
$original = base_convert($convert, 16, 10)
echo $convert, PHP_EOL; #f1206
echo $original, PHP_EOL; #987654

output:

f1206
987654
3 голосов
/ 22 февраля 2012

Это просто конвертировать в шестнадцатеричное.

$number= 1000000;
echo base_convert($number, 10, 16); // f4240

Хочешь даже повеселиться и перевести его в базу 36

$number= 1000000;
echo base_convert($number, 10, 36); 

И выполнить обратную операцию для декодирования:

$base46_number = 'LFLS';
$decimal = base_convert($base46_number, 36, 10);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...