Php 将数据库ID混淆为面向客户的编号

Php 将数据库ID混淆为面向客户的编号,php,mysql,obfuscation,Php,Mysql,Obfuscation,我使用mysql数据库自动增量作为订单ID。当我向用户显示订单ID时,我想以某种方式屏蔽/混淆它 为什么? 所以乍一看,管理员用户很明显知道这个数字是多少 指(订单从10开始,客户从20开始等) 乍一看,这只是我的第四份订单 基于此,我希望屏蔽/模糊的订单id: 只有数字 一致的长度(如果可能) 不会引起碰撞 是可逆的,这样我就可以解码并得到原始ID 我如何在PHP中实现这一点?它不一定非常复杂,只是乍一看它并不明显。它能帮上忙吗 echo hexdec(uniqid()); 当然,您

我使用mysql数据库自动增量作为订单ID。当我向用户显示订单ID时,我想以某种方式屏蔽/混淆它

为什么?

  • 所以乍一看,管理员用户很明显知道这个数字是多少 指(订单从10开始,客户从20开始等)
  • 乍一看,这只是我的第四份订单
基于此,我希望屏蔽/模糊的订单id:

  • 只有数字
  • 一致的长度(如果可能)
  • 不会引起碰撞
  • 是可逆的,这样我就可以解码并得到原始ID
我如何在PHP中实现这一点?它不一定非常复杂,只是乍一看它并不明显。

它能帮上忙吗

echo hexdec(uniqid());

当然,您应该将此值存储在db中,与订单id位于同一行。

最简单的方法可能是生成一个长的随机字符串,并使用它而不是自动增量id。或者将其与自动增量id一起使用。如果字符串足够长且足够随机,则它对于每个记录都是唯一的(想想GUI)。然后,您可以向用户显示这些信息,而无需担心任何事情。

仅将ID转换为十六进制之类的内容可能不会得到您想要的结果。此外,这仍然很容易“猜测”

我将添加一个额外的ID列(即order_ID)。设置一个unqi。指数然后在创建时使用以下mysql函数之一:

SHA1(contcat('ORDER', id))
MD5(contcat('ORDER', id))
SHA1(contcat('ORDER', id, customer_id))
MD5(contcat('ORDER', id, customer_id))

UUID()

// try this in your mysql console
SELECT UUID(), SHA(CONCAT('ORDER',10)), SHA1(1);
您可以(如示例中所示)添加一个简单的文本前缀,如“order”。甚至把它们结合起来。然而,我认为UUID()将是最简单的


实现有点取决于您喜欢什么(您可以使用存储过程)或将其合并到您的模型中。

我认为您可以使用XOR运算符来隐藏“乍一看”(例如,MySQL示例):

其中
2342323
121
是“神奇”数字-订单编号的模板。 要反转:

(OrderNum ^ 2342323)/121
这种情况下的额外优势-如果
(OrderNum^2342323)
除以121,不带余数,则可以验证OrderNumber(以避免在线形式的垃圾邮件或类似内容)


有点晚了,但是Optimus()确实做到了这里要求的

$encoded = $optimus->encode(20); // 1535832388
$original = $optimus->decode(1535832388); // 20

只有初始设置有点奇怪(生成素数)

是否将当前时间戳添加到开始/结束<代码>$uid=time()$idFromDb。只要数据库中的ID不同,就不会发生冲突,它只会是数字。随着自动递增数字的增加,长度会略有不同。我已更新了我的问题,但我需要能够将其转换回原始数据库ID。是否向其添加某种分隔符<代码>$uid=$idFromDb'@'。时间()然后从代码中的该分隔符再次获取
$idFromDb
?有很多方法可以做到这一点,关于你采取什么方法/策略,这将是基于意见的。我不太确定这将如何工作,我基本上忽略了@符号之后的所有内容来获得ID?可能有点明显你很可能发现你的问题已经在这里得到了回答:
hexdec(md5(你的订单))
您可能没有看到我更新的问题,但它必须是可逆的。对不起,我会说
base64\u encode/base64\u decode
,但它不仅仅是数字,不幸的是,它只需要整数。也许我会使用您的原始解决方案,只是检查它是否已经存在于数据库中。我已经有一个唯一的数据库ID,我想基于该值,这样我就不必检查它是否唯一。@paul-正如我所说,如果您使它足够长且足够随机(如GUID/UUID),那么您就不需要检查它的唯一性。从统计上讲,在生成两个相等的guid之前,太阳会熄灭。即使您使用可用的最快硬件以最大速度连续生成GUI,我如何在PHP中创建类似的东西?这仅仅是数字,如果可能的话,长度是相同的?@paul-首先你用a来获得一堆随机字节(比如说,30)。然后使用函数将每个字节转换为一个数字,并将所有字节连接在一起,得到一个长的随机数字字符串。长度将在30到90位之间。取前30个数字,就完成了!18位数是10^18。GUID为5.3*10^36。所以要低很多。不过,这是一个相当大的数字。我想说,只要你使用一个适当的加密强随机数生成器(不要使用标准的rand/mt_rand),你的机会就很低。
$encoded = $optimus->encode(20); // 1535832388
$original = $optimus->decode(1535832388); // 20