隐藏/加密订单号作为另一个数字:对称,“随机”外观?

时间:2009-03-04 18:45:42

标签: encryption random encoding numbers

客户有一个简单的增加订单号(1,2,3 ......)。他希望最终用户收到8位或9位数字(仅数字 - 无字符)“随机”数字。显然,这个“随机”数字实际上必须是唯一且可逆的(它实际上是对actualOrderNumber的加密)。

我的第一个想法是只是洗牌一些。当我向客户展示一个样本序列时,他抱怨随后的obfuscOrderNumbers正在增加,直到它们达到“shuffle”点(低位比特发挥作用的点)。他希望obfuscOrderNumbers尽可能随机看似。

我的下一个想法是确定性地为一个线性同余伪随机数生成器播种,然后获取actualOrderNumber值。但在这种情况下,我需要担心碰撞 - 客户想要一种保证不会在至少10 ^ 7个周期内发生碰撞的算法。

我的第三个想法是“呃,只是对加密的东西进行加密”,但是如果我使用股票加密库,我必须对其进行后处理才能获得8位或9位数的要求。

我的第四个想法是将actualOrderNumber的位解释为格雷编码的整数并返回。

我的第五个问题是:“我可能会过度思考这个问题。我敢打赌StackOverflow上的某个人可以通过几行代码完成此任务。”

7 个答案:

答案 0 :(得分:15)

随机选择一个8位或9位数字,比如839712541.然后,取你的订单号的二进制表示(对于这个例子,我没有使用2的补码),将其填充到相同的位数(30) ,反转它,以及xor翻转的订单号和幻数。例如:

1         = 000000000000000000000000000001

Flip      = 100000000000000000000000000000
839712541 = 110010000011001111111100011101
XOR       = 010010000011001111111100011101 = 302841629

2         = 000000000000000000000000000010

Flip      = 010000000000000000000000000000
839712541 = 110010000011001111111100011101
XOR       = 100010000011001111111100011101 = 571277085

要获取订单号,请输出带有幻数的输出数,转换为位串,然后反转。

答案 1 :(得分:6)

答案 2 :(得分:5)

客户端是否需要分发模糊的连续订单号以使其看起来像什么?

如果您不想使用加密复杂化,请使用位混洗和一些随机salting的组合(如果您有多余的位/数字)XOR叠加在某个固定常量(或某些函数的某些函数)上随时可以随机提供混淆的订单ID,例如下订单的customer_id?)


修改

似乎所有客户的愿望都是外部方无法推断销售进度。在这种情况下,改组解决方案(比特映射,例如原始比特1映射到模糊比特6,原始比特6映射到模糊比特3等)应该是绰绰有余的。如果您真的想要使其更难破解,请添加一些随机位,前提是您有额外的位可用(例如,假设原始订单号最多只能达到6位数,但在混淆的订单号中允许8-9,然后你可以在执行位映射之前使用2-3位数字进行随机性处理。可能会对结果进行XOR以进行额外的恐吓(好奇的一方可能会尝试生成两个连续的混淆命令,将它们相互异或以消除XOR常数,然后必须推断出哪些非零位来自盐,哪些是来自一个增量,以及他是否真的有两个连续的订单号...他将不得不重复这一点,他希望是连续订单号的大量数据,以便破解它。)


<强> EDIT2

当然,您可以为混淆的订单ID分配完全随机的数字,将对应关系存储到持久存储(例如DB),并执行冲突检测以及针对相同存储的去混淆。如果你问我,有点矫枉过正,但就好处来说,就混淆而言是最好的(并且你实现了你的灵魂所需的任何分配功能,你可以随时改变分配功能。)

答案 3 :(得分:4)

在9位数字中,第一个数字是0到7(或1-8)之间的随机索引。在该位置添加另一个随机数字。其余的是“真正的订单号:

  • 原始订单: 100
  • 随机指数:5
  • 随机数字:4(保证,滚动a 骰子:))
  • 结果: 500040100

  • Orig Nr: 101

  • 随机指数:2
  • 随机数字6
  • 结果: 200001061

您可以决定第5个(或任何其他)数字是索引。

或者,如果您可以使用6位数的实际订单号,那么您也可以引入“二级”索引。并且您可以颠倒“真实”顺序中的数字顺序。

答案 4 :(得分:3)

我很晚才看到这个,(!)因此我的反应相当迟缓。它可能对后来出现的其他人有用。

你说:“我的第三个想法是”呃,只是加密了这件事,“但是如果我使用股票加密库,我必须对它进行后处理以获得8或9位数的要求。“

这是正确的。加密是可逆的,并保证对于给定的输入是唯一的。正如您所指出的,大多数标准加密都没有正确的块大小。但是,有一个Hasty Pudding Cipher可以从1位向上具有任何块大小。

或者你也可以自己写。鉴于您不需要NSA无法破解的东西,那么您可以构建一个简单的Feistel cipher来满足您的需求。

答案 5 :(得分:0)

如果您的订单ID是唯一的,您只需输入前缀并在订单ID中添加/混合该前缀。

这样的事情:

long pre = DateTime.Now.Ticks % 100;
string prefix = pre.ToString();
string number = prefix + YOURID.ToString()

答案 6 :(得分:-1)

<?PHP 

$cry = array(0=>5,1=>3,2=>9,3=>2,4=>7,5=>6,6=>1,7=>8,8=>0,9=>4);

function enc($e,$cry,$k){
    if(strlen($e)>10)die("max encrypt digits is 10");
    if(strlen($e) >= $k)die("Request encrypt must be lesser than its length");
    if(strlen($e) ==0)die("must pass some numbers");

    $ct =  $e;
    $jump = ($k-1)-strlen($e);
    $ency = $cry[(strlen($e))];
    $n = 0;
    for($a=0;$a<$k-1;$a++){
        if($jump > 0){
            if($a%2 == 1){
                $ency .=rand(0,9);
                $jump -=1;
            }else{
                if(isset($ct[$n])){
                    $ency.=$cry[$ct[$n]];
                    $n++;
                }else{
                    $ency .=rand(0,9);
                    $jump -=1;
                }
            }
        }else{
            $ency.= $cry[$ct[$n]];
            $n++;
        }
    }
    return $ency;
}

function dec($e,$cry){
    //$decy = substr($e,6);
    $ar = str_split($e,1);
    $len = array_search($ar[0], $cry);
    $jump = strlen($e)-($len+1);
    $val = "";
    for($i=1;$i<strlen($e);$i++){
        if($i%2==0){
            if($jump >0){
                //$val .=array_search($e[$i], $cry);
                $jump--;
            }else{
                $val .=array_search($e[$i], $cry);
            }
        }else{
            if($len > 0){
                $val .=array_search($e[$i], $cry);
                $len--;
            }else{
                $jump--;
            }
        }
    }
    return $val;
}
if(isset($_GET["n"])){
    $n = $_GET["n"];
}else{
    $n = 1000;
}

$str = 1253;
$str = enc($str,$cry,15);
echo "Encerypted Value : ".$str ."<br/>";
$str = dec($str,$cry);
echo "Decrypted Value : ".$str ."<br/>";
?>