【发布时间】:2009-09-15 11:19:49
【问题描述】:
编辑:我已经找到并发布了一个高效而优雅的解决方案,可以将
3141592之类的 ID 转换为vJST之类的字符串并向后转换。它在此处可用于 PHP:https://github.com/delight-im/PHP-IDs
提供一些背景知识,它使用 Knuth 的乘法散列,然后进行基本转换来生成唯一、可逆、非顺序的 ID。
问题:
我在 PHP 中有动态页面,其中的内容根据给定的 id 显示。 id 总是通过 GET 参数提交:page.php?id=X 这会导致一个问题:站点访问者可以枚举 id 并简单地浏览所有不同的内容页面。当然,这应该是不可能的。
如何解决?
我的方法是对链接和表单中的所有 id 进行编码,稍后用作 GET 参数。在每一页的开头,给定的 id 被解码为数据库中使用的“真实”id。这是一个好方法吗?你会选择其他方式吗?
我的方法的可能解决方案:
我会将整数 id 转换为以 38 为基数的整数,并用给定列表的字符替换数字。我会将这些字符用于编码的字符串 id:
a-z 0-9 - _
你也会使用其他角色吗?对于这些角色,我的脚本是这样的:
function id2secure($old_number) {
$alphabet_en = array(0=>'1', 1=>'3', 2=>'5', 3=>'7', 4=>'9', 5=>'0', 6=>'2', 7=>'4', 8=>'6', 9=>'8', 10=>'a', 11=>'c', 12=>'e', 13=>'g', 14=>'i', 15=>'k', 16=>'m', 17=>'o', 18=>'q', 19=>'s', 20=>'u', 21=>'w', 22=>'y', 23=>'b', 24=>'d', 25=>'f', 26=>'h', 27=>'j', 28=>'l', 29=>'n', 30=>'p', 31=>'r', 32=>'t', 33=>'v', 34=>'x', 35=>'z', 36=>'-', 37=>'_');
$new_number = '';
while ($old_number > 0) {
$rest = $old_number%38;
if (!isset($alphabet_en[$rest])) { return FALSE; }
$new_number .= $alphabet_en[$rest];
$old_number = floor($old_number/38);
}
$new_number = strrev($new_number);
return $new_number;
}
其他问题:
我的函数的反向函数是什么?
我希望你能帮助我。谢谢!
【问题讨论】:
-
您可以使用字符串
'1…_'来缩短您的数组构造array(0=>'1', …, 37=>'_')。然后您只需将!isset($alphabet_en[$rest])替换为$rest >= 38,它就可以像您一样工作。 -
“这当然不可能。”除非不允许用户访问这些页面,否则我会提出完全相反的观点。有能力的用户应该能够以他们认为合适的任何方式浏览网站。
-
@Gumbo:非常感谢,好主意。这应该更快吧?
-
一个“枚举”究竟是怎样的?
-
为什么不直接使用php原生base64编码/解码函数?
标签: php security encryption parameters get