Php 如何使用实际订单Id生成唯一的订单Id(仅用于显示touser)?
再次编辑:我不想再提出另一个问题,所以在这里提问。我也有同样的情况。但是这次我需要C语言的算法。有人能帮我吗。 我有下表Php 如何使用实际订单Id生成唯一的订单Id(仅用于显示touser)?,php,c,algorithm,encryption,Php,C,Algorithm,Encryption,再次编辑:我不想再提出另一个问题,所以在这里提问。我也有同样的情况。但是这次我需要C语言的算法。有人能帮我吗。 我有下表 CREATE TABLE IF NOT EXISTS `j741_order` ( `order_id` int(11) NOT NULL AUTO_INCREMENT, `buyer_id` int(11) NOT NULL, `subtotal` decimal(15,5) DEFAULT '0.00000', `discount` decimal(15,
CREATE TABLE IF NOT EXISTS `j741_order` (
`order_id` int(11) NOT NULL AUTO_INCREMENT,
`buyer_id` int(11) NOT NULL,
`subtotal` decimal(15,5) DEFAULT '0.00000',
`discount` decimal(15,5) NOT NULL DEFAULT '0.00000',
`shipping` decimal(15,5) DEFAULT '0.00000',
`tax` decimal(15,5) DEFAULT '0.00000',
`total` decimal(15,5) NOT NULL DEFAULT '0.00000',
`currency` char(3) DEFAULT NULL,
`status` int(11) NOT NULL DEFAULT '0',
`created_date` datetime NOT NULL,
`modified_date` datetime NOT NULL,
PRIMARY KEY (`order_id`),
KEY `idx_buyer_id` (`buyer_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
我想生成一个唯一的订单Id(只是向用户显示),这样用户就无法猜到下一个订单Id是什么
我怎样才能得到唯一的随机顺序
来自原始订单的Id,如果
并从中获取原始订单Id
那个随机顺序Id
编辑:我不想创建任何其他字段。首先,您应该将您的
顺序id作为数据库中的物理标识符:该字段是一个整数,它工作正常(您的代码就是为了使用它而设计的——整数比字符串键具有更好的性能)
但是您可以添加另一个字段,作为用户的标识符:
- 一个
varchar(something)
或char(something)
字段,可以获得更好的显示效果,并且更难猜测
- 它将显示给用户
- 上面会有一个
唯一的
索引
- 但它对您的代码没有技术意义
A可能是个主意--但我有点担心它可能有点太长了
那么基于用户名的第一个字母、日期和一些随机数的东西呢?
这将是很难猜测,仍然有一点意义的用户
当然,您将无法从该字符串标识符计算订单id——但如果该标识符是唯一的,则只需进行简单查询,即可获得订单id:
select order_id from your_table where nice_looking_id = '...';
你可以有点胡编乱造,但我完全建议你再增加一个专栏。下面是我如何使用PHP实现它的
// do your insert
// Retrieve last insert id
$orderId = mysql_insert_id();
// get the current timestamp
$time = time();
// Intersperse the $orderId into the $time to get a new "hash"
$orderId = explode("", (string)$orderId);
$time = explode("", (string)$time);
$orderIdLength = sizeof($orderId);
$newOrderId = "";
for ($i = 0; $i < $orderIdLength; ++$i) {
$newOrderId .= $orderId[$i] . $time[$i];
}
$newOrderId = (int)$newOrderId;
//执行插入操作
//检索最后一个插入id
$orderId=mysql_insert_id();
//获取当前时间戳
$time=time();
//将$orderId散布到$time中以获得新的“哈希”
$orderId=分解(“,(字符串)$orderId);
$time=explode(“,(字符串)$time);
$ORDERDIDLENGTH=sizeof($ORDERDID);
$newOrderId=“”;
对于($i=0;$i<$orderIdLength;++$i){
$newOrderId.=$orderId[$i]。$time[$i];
}
$newOrderId=(int)$newOrderId;
因此,如果您的实际订单id是489,当前时间戳是1300778794,那么您最终会得到一个看起来像418390的订单id。如果您的客户随后使用该订单id进行任何操作,您只需将其重新分解:
$newOrderId = explode("", (string)$newOrderId);
$length = sizeof($newOrderId);
$oldOrderId = "";
for ($i = 0; $i < $length; $i = $i + 2) {
$oldOrderId .= $newOrderId[$i];
}
$oldOrderId = (int)$oldOrderId;
$newOrderId=explode(“,(字符串)$newOrderId);
$length=sizeof($newOrderId);
$oldOrderId=“”;
对于($i=0;$i<$length;$i=$i+2){
$oldOrderId.=$newOrderId[$i];
}
$oldOrderId=(int)$oldOrderId;
这不是一个非常复杂的方法,也不是100%的傻瓜。但是为了稍微模糊你的订单ID,我认为它已经足够了
编辑:作为一个简短的旁白,除了time()
,您还可以使用其他方法生成一些半随机数来填充id。例如,您可以执行rand(pow(10,log10($orderId)),pow(10,log10($orderId)+1))
,这将始终返回与orderId长度相同的随机数
创建密钥(任意字符串)并保存在配置文件(或DB config)中
创建唯一ID:$newId=hash_hmac('sha1',$orderId,$secret_key)。'-'.$orderId代码>。因此,您的订单页面看起来像http://example.com/order/show/123456...absdef-123
李>
您可以快速获取原始订单ID并进行检查:
这样原始ID是公共的,但用户无法在站点地址中替换它,因为未知的哈希字符串(唯一ID的第一部分)。另一个非常简单的方法是对OrderID进行base64编码。将base64编码的ID而不是实际ID传递给客户端,然后在ID返回时对其进行解码。我建议删除编码字符串末尾的等号
优点:
- 非常快速和简单的混淆
实际ID的
缺点:
- 你必须记得解码它
- 一个聪明的用户很容易理解
出去
$original_id=[无论什么]
$salt = [very big private number/string/value];
$checksum = hexdec(substr(md5($original_id . $salt)), 0, 4); // Generate 16 bit checksum
while(strlen($checksum) < 5) // make sure it's five digits long
$checksum = "0" . $checksum;
$user_facing_id = $checksum . $original_id; // Prepend original with checksum
$salt=[very big private number/string/value];
$checksum=hexdec(substr(md5($original_id.$salt)),0,4);//生成16位校验和
while(strlen($checksum)<5)//确保它是五位数
$checksum=“0”$校验和;
$user\u-face\u-id=$checksum$原始id;//用校验和预加原件
您可以使用substr($user\u-faceting\u-ID,5)返回原始ID,甚至可以通过检查dechex(substr($user\u-faceting\u-ID,0,5))和substr(md5(substr($user\u-faceting\u-ID,5)之间的相等性来检查它是否是有效的订单ID,而无需询问数据库。$salt).正如其他人所说,您可以简单地使用已知的salt生成订单id的散列,而计算机并不真正关心订单号是否正确
854bf1176798d77ecaf6b66cbe71a8fc1b0c1847
或
36698
当涉及到湿制品时,有很大的不同
因此,用户无法猜测下一个订单Id是什么
你到底想避免什么?我想你只是想阻止用户看到其他人的订单-在这种情况下,你只需要使用订单id和用户标识符的组合来选择订单
当然,总订单量可能被视为敏感信息——在这种情况下,只需使用与用户id关联的序列号即可。虽然您没有明确说明正在使用的DBMS,但我假设它是mysql或基于引擎的派生数据库——但以下内容也适用于大多数关系型DBMS:
如果向表中添加一列来描述默认值为0的用户,则可以在订单表中添加触发器
$salt = [very big private number/string/value];
$checksum = hexdec(substr(md5($original_id . $salt)), 0, 4); // Generate 16 bit checksum
while(strlen($checksum) < 5) // make sure it's five digits long
$checksum = "0" . $checksum;
$user_facing_id = $checksum . $original_id; // Prepend original with checksum
ALTER TABLE buyers ADD COLUMN buy_ref_last INTEGER DEFAULT 0;
ALTER TABLE orders ADD COLUMN buyer_order_ref INTEGER;
UPDATE orders o SET buyer_order_ref = (SELECT COUNT(*)
FROM orders r WHERE r.buyer_id=o.buyer_id
AND r.order_id<o.order_id);
UPDATE buyers b SET buy_ref_last=(SELECT MAX(buyer_order_ref)
FROM orders o WHERE o.buyer_id=b.id);
$this->scramble1 = '0123456789-ABCDEFGHIJKLMNOPQRSTUVWXYZ ';
$this->scramble2 = 'UKAH652LMOQ FBDIEG03JT17N4C89XPV-WRSYZ';
<?php
include 'encryption_class.php';
$crypt = new encryption_class();
$key = "A-COMPLETELY-RANDOM-KEY-THAT-I-HAVE-USED";
// Min length of 8 for encrypted string
$min_length = 8;
$order_id = 123456789;
print "Original: " . $order_id . PHP_EOL;
$encrypt_result = $crypt->encrypt($key, $order_id, $min_length);
print "Encrypted: " . $encrypt_result . PHP_EOL;
// DECRYPT
$decrypt_result = $crypt->decrypt($key, $encrypt_result);
print "Decrypted: " . $decrypt_result . PHP_EOL;
?>
Original: 123456789
Encrypted: 2UD5UIK9S
Decrypted: 123456789