客户有一个简单的增加订单号(1,2,3 ......)。他希望最终用户收到8位或9位数字(仅数字 - 无字符)“随机”数字。显然,这个“随机”数字实际上必须是唯一且可逆的(它实际上是对actualOrderNumber的加密)。
我的第一个想法是只是洗牌一些。当我向客户展示一个样本序列时,他抱怨随后的obfuscOrderNumbers正在增加,直到它们达到“shuffle”点(低位比特发挥作用的点)。他希望obfuscOrderNumbers尽可能随机看似。
我的下一个想法是确定性地为一个线性同余伪随机数生成器播种,然后获取actualOrderNumber值。但在这种情况下,我需要担心碰撞 - 客户想要一种保证不会在至少10 ^ 7个周期内发生碰撞的算法。
我的第三个想法是“呃,只是对加密的东西进行加密”,但是如果我使用股票加密库,我必须对其进行后处理才能获得8位或9位数的要求。
我的第四个想法是将actualOrderNumber的位解释为格雷编码的整数并返回。
我的第五个问题是:“我可能会过度思考这个问题。我敢打赌StackOverflow上的某个人可以通过几行代码完成此任务。”
答案 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)之间的随机索引。在该位置添加另一个随机数字。其余的是“真正的订单号:
结果: 500040100
Orig Nr: 101
您可以决定第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/>";
?>