好的,我再试一次。你的目标是:
- 混淆标识符的增量 - 不连续、不可猜测、不可计算
- 让智能手机用户仍然“可用”,因此长 UUID 或 SHA1 哈希超出范围
- 避免随机猜测/暴力破解数据库的必要性
- 您的外键仍然具有良好的数据库性能
要在您的数据库中保持良好的性能,您应该为您的 PK 保留一个标准的 auto_incrementing 整数。请注意,InnoDB 根据 PK 对行进行排序(请参阅“InnoDB clustered Index”),因此如果您使用某种魔法哈希作为 PK,最终会在聚集索引中进行大量重新排序,从而导致写入性能不佳。
我建议使用加密算法(加密,而不是散列)来加密和解密要混淆的 ID。此外,为了获得最佳混淆效果,您希望对结果字符串使用最小长度。生成的字符串应该仍然可用,因此您必须使用 base64 之类的东西来使其用户可读。
试试这个加密示例:
function my_number_encrypt($data, $key, $base64_safe=true, $minlen=8) {
$data = base_convert($data, 10, 36);
$data = str_pad($data, $minlen, '0', STR_PAD_LEFT);
$data = @mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_CBC);
if ($base64_safe) $data = str_replace('=', '', base64_encode($data));
return $data;
}
function my_number_decrypt($data, $key, $base64_safe=true) {
if ($base64_safe) $data = base64_decode($data.'==');
$data = @mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_CBC);
$data = base_convert($data, 36, 10);
return $data;
}
$key = "my super secret magic bytes";
$id = 12345678; // obtain_normal_key_from_mysql();
// give ID to user
$enc = my_number_encrypt($i, $key);
// get ID from user
$dec = my_number_decrypt($enc, $key);
// fetch from database using normal ID -> 12345678
// demo code
for($i=10000; $i<10050; $i++) {
$enc = my_number_encrypt($i, $key);
$dec = my_number_decrypt($enc, $key);
echo "$i -> $enc -> $dec", PHP_EOL;
}
演示结果:
10000 -> 1RXK468NYes -> 10000
10001 -> QdEov5mjMPA -> 10001
10002 -> 2gsgzWJgD+8 -> 10002
10003 -> 2zwPwhqr9HI -> 10003
10004 -> Xq+kDh1UFuM -> 10004
10005 -> wfwv6TrW9xY -> 10005
10006 -> 1Lck1L0HJ/U -> 10006
10007 -> v+3YY2zfL1A -> 10007
10008 -> 5AmGlqD8byM -> 10008
10009 -> pZBIpPnKXHU -> 10009
10010 -> CAeWdKGkk8c -> 10010
10011 -> fYddnLOSK6U -> 10011
10012 -> na8Ry0erHv8 -> 10012
10013 -> zxNj+ZJVMBY -> 10013
10014 -> gWJWC9VulZc -> 10014
10015 -> 5pR9B79eM/E -> 10015
10016 -> MQtpBhpzHRA -> 10016
10017 -> dW+3nejBEIg -> 10017
10018 -> znB/feM6104 -> 10018
10019 -> RtdRwwRyEcs -> 10019
10020 -> 4cW/OWT140E -> 10020
10021 -> dIvK9VjOevg -> 10021
10022 -> QxLdfrucc/Y -> 10022
10023 -> M0KN3sX10Gs -> 10023
10024 -> 827yFJyDCG4 -> 10024
10025 -> JF/VRj92qL8 -> 10025
10026 -> IXTvn/SCzek -> 10026
10027 -> L4nFwvhgwX8 -> 10027
10028 -> z0lve9nhgDA -> 10028
10029 -> m/UBgZzfIXo -> 10029
10030 -> IfWcrLKTHXk -> 10030
10031 -> n/jPFwKR/9A -> 10031
10032 -> j1mm2kbeWl0 -> 10032
10033 -> cm7mOQMVa6k -> 10033
10034 -> jCUuweEyRME -> 10034
10035 -> LDaMcOWKxjg -> 10035
10036 -> Zcrd5XzhhIk -> 10036
10037 -> j0Yg/fCjyAA -> 10037
10038 -> /LmlvRHmmmg -> 10038
10039 -> t0juuzGSKs4 -> 10039
10040 -> 9CoRCVXaak4 -> 10040
10041 -> tFmImR4j0JM -> 10041
10042 -> nI3Thy51hLg -> 10042
10043 -> mTCJh0/h2mE -> 10043
10044 -> S196xdyb3Os -> 10044
10045 -> ItOyUp+J4Q4 -> 10045
10046 -> DL87SidiOLM -> 10046
10047 -> d+Nw3xBqV44 -> 10047
10048 -> 3YzVelaC4uI -> 10048
10049 -> fAUJVOl6PaU -> 10049