什么是电子商务解决方案或付费网络服务的良好订单ID方案?

Hen*_*nte 7 database-design uniqueidentifier e-commerce

考虑以下因素:

a)你想要一些机密性(因为没有告诉每个人你收到了多少订单).

b)您想校验位(例如,使用费尔赫夫算法)在年底,所以你可以很容易地分辨拼错和帮助条形码扫描时,如果是这样的情况下,处理错误.

c)您需要考虑时间,以便消费者可以对订单的顺序进行排序.

d)它应该是全数字还是十六进制等?

E)东西,你的消费者可以说通过电话支持团队和刚好够识别顺序,不必问,因为安全问题的电子邮件等,工作人员.

我很想听听一些意见.

PS:任何为解决这个问题而设计的算法对我来说都是一个有效的答案.

Hen*_*nte 5

这是我的解决方案.

有一个三部分xyz,其中x是时间戳,y是随机码,z是由x和y的串联产生的校验位.但是为了简化(使其更小),x和y在自定义基础中给出,而不是数字基础10,但是仍然在基数10给出z.

使用此方法可以获得的ID示例:

  • LP9NTX-8D41-QW6R-9
  • LP9NTY-5H3L-BFS7-5
  • LP9NTZ-RWL3-D619-8
  • LP9NVB-BW74-788W -6-
  • LP9NVW-G17D-4911-8

因此,您可以按时间戳进行排序(如果您不确切知道数字基数是什么,请注意它是如何以'增量字母数字'顺序排列的).

为此,我使用了base58的数字+大写字母(最后,如果我使用小写或上部,则无关紧要),这是base62而没有一些令人困惑的字符.Flickr,bit.ly和其他人使用base58来制作Twitter'友好'链接等.

下面的Verhoeff :: calcsum是Dahnielson的Verhoeff的Dihedral Group D5 Check.我所做的唯一编辑是将他的代码放在一个类中,所以它也是一样的.

这里有一些代码:(*稍微改进了我在那里的承诺^)

<?php
    $time_divisor = 3;
    $base = "123456789ABCDEFGHJKLMNPQRSTUVWXYZ";//consider using another base **see note below**
    $lower_limit = 50000;//just to avoiding to confuse the user with a lower number
    $upper_limit = 1291467968;//1291467968 == ZZZZZZ in this base I used
    //you can check the limit with base_decode("ZZZZZZ", $base);
    $ptime = (int)($_SERVER['REQUEST_TIME']/$time_divisor);//or time();
    $rand1 = mt_rand($lower_limit, $upper_limi);
    $rand2 = mt_rand($lower_limit, $upper_limi);
    $ptime_b = base_encode($time, $base);
    $rand1_b = base_encode($rand1, $base);
    $rand2_b = base_encode($rand2, $base);

    $order_id = $ptime_b.$rand1_b.$rand2_b.Verhoeff::calcsum($time.$rand1.$rand2);
    echo $order_id;
?>
Run Code Online (Sandbox Code Playgroud)

在我写完这篇文章之后,另一个可能出现问题的东西出现在我脑海中.我记得你不希望你的消费者感到受到侮辱.因此,即使认为诸如'f?ck'或'4ss'之类的坏词最终也可能出现(而且几乎肯定会出现),明确的词语(如在前一词中改变'a'的'4')绝对不是.因此,我建议您使用以下备用base/upper_limit:

<?php
    $lower_limit = 27000;//=2111
    $upper_limit = 809999;//=ZZZZ
    $base = "123456789BCDFGHJKLMNPQRSTVWXYZ";//erased -a -e -u
?>
Run Code Online (Sandbox Code Playgroud)

请注意,如果您尝试使用更大的数字,您将达到PHP的上限int以及mt_rand限制,这可以通过mt_getrandmax()看到.另外,我想说,因为我看到mt_rand的熵就足够了.

如果你需要更大的随机部分数字,我建议只需要添加mt_rand(i,j)之类的第三部分; 其中i和j是你的基数的最小值和最大值,它将增加$ num-chars长度的订单ID(实际上我做了这个,带有上面的配置).

在数据库方面,它是一个独特的领域,以避免碰撞.

谢谢你们.


Jer*_*eir 1

您认为合适的任意长度的随机字符串怎么样?使用不易与其他字符混淆的字符用于通过电话阅读。因此,在每个订单上调用如下内容:

    public static string GetRandomString(int length)
    {
        char[] chars = "ACDEFGHJKMNPQRTWXY34679".ToCharArray();
        var crypto = new RNGCryptoServiceProvider();
        var data = new byte[length];
        crypto.GetNonZeroBytes(data);
        var result = new StringBuilder(length);
        for (int i = 0; i < data.Length; i++)
        {
            result.Append(chars[data[i] % chars.Length]);
        }

        return result.ToString();
    }
Run Code Online (Sandbox Code Playgroud)

猜测上述方法返回的 8 个字符的概率为 1/282429536481。并且您将通过唯一约束来保持数据库的完整性,对吧?