首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为PHP中的URL生成随机字符

为PHP中的URL生成随机字符
EN

Stack Overflow用户
提问于 2014-07-01 17:13:50
回答 1查看 963关注 0票数 0

我已经用我自己的实现来回答了(下面),如果你能检查一下数学和逻辑,我会很感激,但是我意识到还有其他的可能性。

我试图生成32个随机字符,以便在注册URL中使用。

新帐户部分由工作人员创建(设置名称/电子邮件),并向新用户发送纯文本电子邮件,以便他们能够确认电子邮件地址并设置密码。

试图保持A-Za-z0-9字符,我相信这创造了一个基础62系统,需要6位以下的存储.这就是190位以上的熵?还是190.53428193238?

由于这是一个安全特性,我不认为uniqid()本身是一个好主意,因为这是基于当前的微时间。

我不认为使用加密或散列的用户ID或电子邮件地址也是一个很好的解决方案(碰撞,低熵,并可能由一个单一的密钥安全)。

EN

回答 1

Stack Overflow用户

发布于 2014-07-01 17:13:50

使用PHP7.0 random_bytes()函数可以做到这一点:

代码语言:javascript
复制
<?php

function random_key($length, $safe = false) {

    if ($safe !== false) {
        $bad_words = array_map('trim', file('/path/to/bad-words.txt', FILE_IGNORE_NEW_LINES));
    } else {
        $bad_words = NULL;
    }

    $j = 0;

    do {

        $bytes = (ceil($length / 4) * 3); // Must be divisible by 3, otherwise base64 encoding introduces padding characters, and the last character biases towards "0 4 8 A E I M Q U Y c g k o s w".
        $bytes = ($bytes * 2); // Get even more, because some characters will be dropped.

        $key = random_bytes($bytes);
        $key = base64_encode($key);
        $key = str_replace(array('0', 'O', 'I', 'l', '/', '+'), '', $key); // Make URL safe (base58), and drop similar looking characters (no substitutions, as we don't want to bias certain characters)
        $key = substr($key, 0, $length);

        if (preg_match('/[^a-zA-Z0-9]/', $key)) {
            exit_with_error('Invalid characters detected in key "' . $key . '"');
        }

        $valid = (strlen($key) == $length);

        if ($bad_words) {
            foreach ($bad_words as $bad_word) {
                if (stripos($key, $bad_word) !== false) {
                    $valid = false;
                    break;
                }
            }
        }

        if ($valid) {
            return $key;
        }

    } while ($j++ < 10);

    exit_with_error('Cannot generate a safe key after 10 attempts.');

}

?>

这段代码显示了base64_encode()函数如何偏向于某些字符:

代码语言:javascript
复制
<?php

$characters = [];

for ($k = 0; $k < 500000; $k++) {

    $key = base64_encode(random_bytes(32)); // 32 bytes results in "=" padding; try changing to 30 to fix.

    foreach (str_split($key) as $c) {
        if (!isset($characters[$c])) {
            $characters[$c] = 0;
        }
        $characters[$c]++;
    }

}

$characters = array_filter($characters, function($value) {
        return ($value > 343750); // ((((33/3)*4)*500000)/64) = 343750, everything else is about ~327000
    });

ksort($characters, SORT_STRING);

print_r($characters);

?>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24515903

复制
相关文章

相似问题

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