首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >加密数字URL参数,结果不应长于原始长度

加密数字URL参数,结果不应长于原始长度
EN

Stack Overflow用户
提问于 2012-02-22 15:02:10
回答 3查看 3.3K关注 0票数 3

我必须加密一个特定的URL参数。如果我希望输出少于6-7个字符,我应该使用什么算法?

输入仅为1到1,000,000之间的整数。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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()来缩小输入字符串!

代码语言:javascript
运行
复制
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";

结果:

代码语言:javascript
运行
复制
data: 15231223
encrypted: BuF3xdE
decrypted: 15231223
票数 6
EN

Stack Overflow用户

发布于 2012-02-22 15:51:13

把它转换成十六进制很简单。

代码语言:javascript
运行
复制
$number= 1000000;
echo base_convert($number, 10, 16); // f4240

你甚至想要找点乐子,把它转换成36号基地

代码语言:javascript
运行
复制
$number= 1000000;
echo base_convert($number, 10, 36); 

并执行相反的操作来解码:

代码语言:javascript
运行
复制
$base46_number = 'LFLS';
$decimal = base_convert($base46_number, 36, 10);
票数 3
EN

Stack Overflow用户

发布于 2012-02-22 16:30:51

代码语言:javascript
运行
复制
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;
}

以下哪项输出:

代码语言:javascript
运行
复制
12: DA== => 12
123456: AeJA => 123456
1000000: D0JA => 1000000
467: AdM= => 467
9456724645: AjOqKqU= => 9456724645

就像一种护身符。对于最大为1000000的整数,它将消耗4个字母。但是不要为了安全而使用它!隐蔽性的安全性从来不是一个选项,如果用户不想知道某个数字,也永远不会尝试使用这种方法来对用户隐藏该数字。

另一个更优雅的解决方案是使用base_convert,它会产生稍微长一点的字符串,但它仍然可以容纳6-7个字符。

代码语言:javascript
运行
复制
$int = 987654;
$convert = base_convert($int, 10, 16)
$original = base_convert($convert, 16, 10)
echo $convert, PHP_EOL; #f1206
echo $original, PHP_EOL; #987654

输出:

代码语言:javascript
运行
复制
f1206
987654
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9390439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档