2

我必须从一个递增的数字(1 到 50000)和一个秘密密码开始构建 50,000 个代码。我必须在 php 中完成,最终代码必须是 8 或 12 个字符长,并且只包含大写字母 (AZ) 和数字 (0-9)。

最终代码必须可以使用密码解密...

我正在尝试使用 openssl_encrypt 但我找不到使最终代码“缩短”的方法。

$longCode = openssl_encrypt($number, $method, ENC_KEY, true, $iv);
$shortCode = .....

一些想法?

4

2 回答 2

1

第一步是使用块大小为 8 字节的密码方法,例如“rc2-cbc”。

$nr = 1234;
$key = 'secretkey';
$method = 'rc2-cbc';

$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($method));

$code = openssl_encrypt($nr, $method, $key, true, $iv);

第二步是将生成的字符串转换为您的字母表;因为您的字母大小只有 36,所以最接近且“简单”的转换是 base32;这给出了(在去除可选填充之后)正好 13 个字符的字符串。

理论上您可以将 4 个字节转换为 6 个 base36 字符:

log(36) / log(2) ~ 5.17 bits, saves 1 bit after 6 blocks

6 x 5.17 ~ 31.02, 6 blocks fits inside 32 bits (unsigned long)

32 bits = 4 bytes -> 6 characters

错误的实施

下面的代码应该做到这一点 - 但并不(总是)工作!

$final = '';
foreach (str_split($code, 4) as $part) {
    $x = current(unpack('L', $part));
    $final .= strtoupper(base_convert($x, 10, 36));
}

解码将是这样的:

$code2 = '';
foreach (str_split($final, 6) as $part) {
        $code2 .= pack('L', base_convert(strtolower($part), 36, 10));
}

不知何故,整数精度无法处理它,或者我正在做一些愚蠢的事情;无论哪种方式,它并不总是有效。

于 2012-10-18T08:48:56.647 回答
0

试试这个:

// generate random ID
    function generateRandomID ($len) {
        //To Pull Unique Random Values Out Of AlphaNumeric
        //removed number 0, capital o, number 1 and small L
        //Total: keys = 32, elements = 33
        $characters = array(
        "A","B","C","D","E","F","G","H","J","K","L","M",
        "N","P","Q","R","S","T","U","V","W","X","Y","Z",
        "1","2","3","4","5","6","7","8","9");

        //make an "empty container" or array for our keys
        $keys = array();

        //first count of $keys is empty so "1", remaining count is 1-6 = total 7 times
        while(count($keys) < $len) {
                //"0" because we use this to FIND ARRAY KEYS which has a 0 value
                //"-1" because were only concerned of number of keys which is 32 not 33
                //count($characters) = 33
                $x = mt_rand(0, count($characters)-1);
                if(!in_array($x, $keys)) {
                     $keys[] = $x;
                }
        }

        foreach($keys as $key){
             $random_chars .= $characters[$key];
        }
        return $random_chars;
    }

编辑:删除了一些字母和数字,以便更好地阅读,请参阅代码中的注释。

于 2012-10-18T08:29:34.357 回答