I want to generate random alphanumeric strings in PHP. They will be used in places where the strength of random numbers is important (publicly visible IDs in URLs and the like).

我想在PHP中生成随机的字母数字字符串。它们将用于随机数强度很重要的地方(url中可见的id等)。

As I understand, in PHP the main source of cryptographically strong randomness is openssl_random_pseudo_bytes(). This however returns an array of bytes, not alphanumeric characters.

正如我所理解的,在PHP中,密码强随机性的主要来源是openssl_random_pseu_bytes()。然而,它返回的是字节数组,而不是字母数字字符。

To convert them to alphanumerics I could either hash them (which would produce a longer-than-necessary string of a limited set of hex characters), or base64_encode() them (which would produce a string with +, / and = in it - not alphanumerics).

要将它们转换为字母数字,我可以对它们进行哈希(这会产生一组有限的十六进制字符的长时间字符串),或者对它们进行base64_encode()(将生成一个带+ /和=的字符串,而不是字母数字)。

So I think that instead I could use the random bytes as a source of entropy and generated my own string consisting only of the characters 0-9a-zA-Z.

所以我认为我可以用随机字节作为熵的来源,生成我自己的字符串,只包含0-9a-zA-Z字符。

The problem then becomes - how to translate from 256 distinct values (one byte of input) to 62 distinct value (one character of output). And in a way, that all 62 characters are equally as likely. (Otherwise there will be 8 characters that appear more often than the rest).

问题变成了如何从256个不同的值(一个字节的输入)转换到62个不同的值(一个字符的输出)。在某种程度上,所有62个角色的可能性都是一样的。(否则将会有8个字符比其他字符出现得更频繁)。

Or perhaps I should use another approach entirely? I would like my string to be as short as possible (say, 20 characters or so - shorter URLs are better) and consist only of alphanumeric characters (so that it doesn't need to be specially escaped anywhere).

或者我应该完全使用另一种方法?我希望我的字符串尽可能短(比方说,20个字符或者更短的url更好),并且只包含字母数字字符(这样它就不需要在任何地方特别转义)。

3 个解决方案

#1


2

You can implement your own base64 encoding, sort of. If you can allow two specific symbols - these can be anything, for example . and -, it doesn't really matter. It can even be a space for one of them. In any case, what you would do is this:

您可以实现自己的base64编码。如果您允许两个特定的符号——例如,这些符号可以是任何东西。这并不重要。它甚至可以是其中一个的空间。无论如何,你要做的是:

$alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-";
// using . and - for the two symbols here
$input = [123,193,21,13]; // whatever your input it, I'm assuming an array of bytes
$output = "";
foreach($input as $byte) {
    $output .= $alphabet[$byte%64];
}

Assuming random input, all characters have equal probability of appearing.

假设随机输入,所有字符出现的概率相等。

That being said, if you can't allow anything except pure alphanumeric, cut the symbols from the $alphabet and use %62 instead of %64. While this does mean you have a small bias towards the chracters 0 through 7, I don't think it's significant enough to worry about.

也就是说,如果你只能允许纯字母数字,那就从$alphabet中删除符号,使用%62而不是%64。虽然这确实意味着你对chracter 0到7有一个小的偏见,但我认为这还不够重要。

更多相关文章

  1. 查找具有特定数据字符串的数组并返回其具有的另一个数据字符串
  2. 在php中,从字符串中删除逗号后的所有内容
  3. 如何通过PHP将HTML页面作为字符串获取?
  4. php 基本的常用字符串函数
  5. 用PHP计算字符串中元音的简单方法?
  6. 将DOMDocument中的特定元素导出为字符串
  7. PHP实现字符串转换成查询语句
  8. mysql 判断null 和 空字符串
  9. Mysql字符集和校验规则

随机推荐

  1. 我用起来顺手的数据库设计工具,这次推荐给
  2. C语言中的数据类型及其转换详解
  3. 什么是单点登录(SSO)
  4. 感动,感谢,感恩 PMP 考后感
  5. 对SATA硬盘的理解
  6. MongoDB快速入门,掌握这些刚刚好!
  7. 【JavaWeb基础】图书管理系统总结(修订版
  8. 近况
  9. 我常用的IDEA插件大公开,个个是精品!
  10. Kubernetes 原生 CI/CD 构建框架 Argo 详