Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使用实际订单Id生成唯一的订单Id(仅用于显示touser)?_Php_C_Algorithm_Encryption - Fatal编程技术网

Php 如何使用实际订单Id生成唯一的订单Id(仅用于显示touser)?

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,

再次编辑:我不想再提出另一个问题,所以在这里提问。我也有同样的情况。但是这次我需要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,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