【问题标题】:How to generate a proper order number with PHP?如何使用 PHP 生成正确的订单号?
【发布时间】:2017-01-28 15:35:37
【问题描述】:

背景:

我正在创建一个服务预订网站。每个订单都需要有一个唯一的订单号。我选择了 16 位,因为这是以前的软件使用的。

问题

我不确定将数据放入订单号是否有任何好处,或者它是否应该只是一个纯粹的随机字符串。

如果它只是一个随机字符串,那么它的唯一目的就是充当一个 ID。如果是这样,那为什么不直接使用增量 ID?除了混淆我们向最终用户生成的订单数量之外,我想不出一个好的理由。

如果将数据放入字符串中是个好主意,我应该包含什么样的数据?可能是订单的日期,但除此之外我不知道。

我目前正在生成一个像这样的纯随机 16 位字符串。

public function generateOrderNumber()
{
    $time = time(); // Time (CET) to hash
    $token = md5($time); // Hash stored in variable
    return str_shuffle(substr($token, 0, 16)); // Hash shortened to 5 chars and randomised
}

但是我不确定这是否足以用于生产。

【问题讨论】:

  • 为什么不使用自动增量?如果你想混淆你让它从一个随机数开始
  • 我们也不知道。我们完全不知道您的生产需求/要求。另外,为什么 str_shuffle? md5 哈希值本质上始终是“随机的”。缩短它会减少键空间并增加发生冲突的机会,并且改组它并不能帮助您防止冲突。
  • 有道理@Marc B,感谢您澄清这一点。我假设如果我们生成了足够多的订单,那么在使用 MD5 时就有可能出现主键匹配,尽管这种可能性非常低。
  • 关于将数据放入字符串中,请记住,meaningful code 这个术语是矛盾的。
  • 混淆数字的原因:隐藏公司获得的订单数量,使其更难猜测其他客户的订单号(当然这不应该是唯一的安全措施)

标签: php mysql sql hash


【解决方案1】:

如果您需要全局唯一性,例如跨多个定期同步的数据库,那么我会使用标准的 128 位 GUID,它可以压缩成 16 个 8 位字节以保持向后兼容性。 PHP 有 com_create_guid 来生成 GUID。

【讨论】:

  • 字节可以是 8 位以外的任何内容吗? (我认为 4 位组成一个半字节,16 位组成一个字,因此 8 位始终是一个字节。所以你可以说16 bytes?)
  • 这些天是的,但历史上并非总是如此。我是 C 的老前辈,喜欢打卡和分时。
【解决方案2】:

MD5 只产生a-f0-9 范围内的值,这在此处受到严格限制。你真的需要扩展它并使用整个字母表,甚至可能是 Base62,Base64 的变体减去两个“烦人”字符。

一个加密随机数,而不是垃圾 rand() 产生,编码为 5 个字符的 Base62 值可以工作。

如果您需要人们能够手动读写这些值,为了清楚起见,您需要省略 0O1lI

请记住,在非常短的值上,您可能会遇到冲突,因此您需要针对 UNIQUE 约束测试您所做的任何 INSERT 并在它们失败时重试。

【讨论】:

  • 是base64中那些“烦人”的字符吗,有时是填充字符(=)stackoverflow.com/a/4492448/3000179
  • 是的,令人讨厌的是= 填充字符,还有+/,它们会混淆URL 中的值。这就是为什么 Base62 是一种流行的替代方案。
猜你喜欢
  • 1970-01-01
  • 2014-04-12
  • 1970-01-01
  • 2023-04-03
  • 2018-09-01
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 2014-11-29
相关资源
最近更新 更多