我必须加密一个特定的URL参数。如果我希望输出少于6-7个字符,我应该使用什么算法?
输入仅为1到1,000,000之间的整数。
发布于 2012-02-22 16:13:34
如果您需要加密,并且需要获得尽可能短的结果,则必须使用流密码。Blowfish (你之前使用的)是一个块密码,结果总是只有一个块的最小大小。
在PHP manual on mcrypt中查找comparison of stream ciphers on Wikipedia和支持的密码列表
此外,加密的结果可能包含特殊字符,因此在将其作为参数放入URL时,应使用urlencode()
或base64_encode()
使用urlencode()
或base64_encode()
将扩展字符串,使其比原始数据更长。这对于确保传输/URL安全是必要的。
但是,由于您的输入始终是数字,因此可以使用base_convert()
来缩短输入。在解码方面,您必须反向执行相同的操作。
要获得更短的结果,您可以使用enminicode()
/ deminicode()
function provided by 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
发布于 2012-02-22 15:51:13
把它转换成十六进制很简单。
$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);
发布于 2012-02-22 16:30:51
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
输出:
f1206
987654
https://stackoverflow.com/questions/9390439
复制相似问题