【问题标题】:How to generate a 128-bit long string?如何生成一个 128 位长的字符串?
【发布时间】:2010-11-08 01:30:39
【问题描述】:

基本上,我正在寻找执行以下操作的函数

generateToken(128)

这将返回一个由整数或字母字符组成的 128 位 字符串

澄清:从 cmets,我不得不改变问题。显然,如果需要 128 位,我正在寻找一个长度为 16 个字符的字符串。

【问题讨论】:

  • 什么是 128 位?字符串表示的编号?
  • 阿克苏尔,你的回答没有任何意义。
  • 你的意思是你想要一个编码为字符串的 128 位数字,还是你想要一个 128 位的数字?我假设您在我的答案中想要一个 128 位的数字。
  • @Cameron 128 位数字与 128 位数字不同。 128 位的数字介于 0 和 2^128-1 之间。我问他是想要一个 0 到 2^128-1 之间的随机数还是一个 128/8=16 个字符的字符串。
  • @Artefacto:是的,我知道。这就是我要求澄清的原因:OP 需要 128 位还是 128 位十进制数字?

标签: php random


【解决方案1】:

您是否有理由必须将字符串限制为整数?这实际上使问题变得更加困难,因为每个数字为您提供 3.3 位(因为 2^3.3 ~= 10)。以这种方式准确地生成 128 位的令牌是很棘手的。

更容易的是允许十六进制编码(每个字符 4 位)。然后,您可以生成 128 个真正的随机位,然后将它们编码为十六进制以用于您的应用程序。 Base64 编码(每个字符 6 位)对于这种事情也很有用。

openssl_random_pseudo_bytes 会给你一串随机字节,你可以使用bin2hex 进行编码,否则你可以在自己的令牌生成例程中使用mt_rand

编辑:阅读问题的更新后,您似乎想要生成一个表示 128 位数据的令牌,而实际字符串长度(以字符为单位)并不那么重要。如果我猜对了您的意图(这是一个唯一 ID,可能用于识别/身份验证目的),那么我建议您使用 openssl_random_pseudo_bytes 为您的问题生成正确的位数,在这种情况下为 128(16 个字节) .然后,您可以以任何您认为合适的方式对这些位进行编码:十六进制和 base64 是两种可能性。

请注意,十六进制编码将使用 32 个字符来编码 128 位数据,因为每个字符仅编码 4 位 (128 / 4 = 32)。 Base64 将使用 22 个字符 (128 / 6 = 21.3)。每个字符占用 8 位 存储,但只编码 4 或 6 位 信息

要非常小心,不要将编码字符串长度与原始数据长度混淆。如果您选择使用字母数字字符(a-z、A-Z、0-9)的 16 个字符的字符串,那么每个字符只能获得 6 位信息(62 的对数基数 2 接近 6),因此您的 16 个字符的字符串只会编码96 位信息。您应该将您的令牌视为一个不透明的字节数组,并且只有在您实际尝试通过网络发送它或将其放入 cookie 或其他任何东西时才担心将其转换为字符串。

【讨论】:

  • openssl_random_pseudo_bytes 不提供十六进制编码表示。无论如何,这是一个很好的解决方案。之后,这只是使用例如的问题。 bcmath 以基数 10 字符串表示形式构建数字。
  • 是的,你是对的。我误读了这个例子并遗漏了bin2hex 位:)
  • 相关:请参阅stackoverflow.com/questions/2982112/…,了解如何将任意数据转换为以 10 为底的数字。
【解决方案2】:

从 PHP 5.3 开始:

$rand128 = bin2hex(openssl_random_pseudo_bytes(16));

【讨论】:

  • 对于 PHP 7.0+,它只是 random_bytes 而不是 openssl_random_pseudo_bytes
【解决方案3】:

你的目的是什么?

如果你只想要一个唯一的 id,那么使用 uniqid:

http://www.php.net/manual/en/function.uniqid.php

它不是随机的,它本质上是一个基于微时间的十六进制字符串。如果你执行 uniqid('', true),那么它将返回一个基于微时间的十六进制字符串,并在 id 末尾添加一堆随机数(所以即使两个调用在同一微秒内进入,他们不太可能共享一个唯一的 ID)。

如果你需要一个 16 字符的字符串,那么目的是什么?你在给密码加盐吗?字符串应该有多随机?总而言之,您总是可以这样做:

$toShow = array();
for($i = 0; $i<16; $i++){
    $toShow[] = chr(mt_rand(ord('a'), ord('z')));
}
return $toShow

现在这会创建一个介于“a”和“z”之间的字符串。您可以将“ord('a')”更改为 0,将“ord('z')”更改为 255,以获得完全随机的二进制字符串...或您需要的任何其他范围。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 2012-03-07
    • 1970-01-01
    • 2015-08-27
    • 2013-05-05
    • 2012-10-26
    • 2013-08-09
    相关资源
    最近更新 更多