encryption - que - Obscurece/encripta un número de orden como otro número: apariencia simétrica, "aleatoria"?
seed random (7)
El cliente tiene un número de orden creciente simple (1, 2, 3 ...). Él quiere que los usuarios finales reciban un número "aleatorio" de 8 o 9 dígitos (solo dígitos, sin caracteres). Obviamente, este número "aleatorio" en realidad tiene que ser único y reversible (en realidad es un cifrado del número de pedido real).
Mi primer pensamiento fue simplemente mezclar algunos bits. Cuando le mostré al cliente una secuencia de muestra, se quejó de que los Números de órdenes obfusc subsiguientes aumentaban hasta que llegaban a un punto "aleatorio" (punto en el que entraban en juego los bits de orden inferior). Él quiere que los ObfuscOrderNumbers sean lo más aleatorios posible.
Mi siguiente pensamiento fue determinar de manera determinista un generador congruente lineal de números pseudoaleatorios y luego tomar el valor real de la Número de orden. Pero en ese caso, tengo que preocuparme por las colisiones: el cliente quiere un algoritmo que garantice que no colisione en al menos 10 ^ 7 ciclos.
Mi tercer pensamiento fue "eh, solo encriptar lo maldito", pero si utilizo una biblioteca de cifrado de stock, tendría que post-procesarlo para obtener el requisito de sólo 8 o 9 dígitos.
Mi cuarto pensamiento fue interpretar los bits de realOrderNumber como un entero de código gris y devolver eso.
Mi quinto pensamiento fue: "Probablemente estoy pensando demasiado. Apuesto a que alguien en StackOverflow puede hacer esto en un par de líneas de código".
¿El cliente requerirá la distribución de números de orden consecutivos ofuscados para que se parezcan a algo en particular?
Si no quiere complicarse con el cifrado, utilice una combinación de mezcla de bits con un poco de salazón al azar (si tiene bits / dígitos de sobra) XOR superpuesto sobre una constante fija (o alguna función de algo que sería fácilmente disponible junto con el ID del pedido ofuscado en cualquier momento, como quizás el customer_id
que realizó el pedido?)
EDITAR
Parece que todos los deseos del cliente son para que un tercero no pueda inferir el progreso de las ventas. En este caso, una solución de mezcla (asignación de bits, por ejemplo, el bit 1 original se asigna al bit 6 ofuscado, el bit 6 original se asigna al bit 3 ofuscado, etc.) debería ser más que suficiente. Agregue algunos bits aleatorios si realmente desea dificultar su descifrado, siempre que tenga los bits adicionales disponibles (por ej., Suponiendo que los números de pedido originales solo tengan hasta 6 dígitos, pero tiene permitido 8-9 en el número de orden ofuscado, entonces puedes usar 2-3 dígitos para la aleatoriedad antes de realizar la asignación de bits). Posiblemente XOR sea el resultado de intimidación adicional (una parte inquisitiva podría intentar generar dos órdenes ofuscadas consecutivas, XOR una contra la otra para deshacerse de la constante XOR, y luego tendría que deducir cuál de los bits no nulos proviene de la sal , y cuáles vinieron de un incremento, y si realmente obtuvo dos números de orden consecutivos o no ... Tendría que repetir esto para un número significativo de lo que esperaría sean números de orden consecutivos para descifrarlo).
EDIT2
Por supuesto, puede asignar números completamente aleatorios para los ID de orden ofuscados, almacenar la correspondencia en un almacenamiento persistente (por ejemplo, DB) y realizar la detección de colisiones, así como la eliminación de ofuscaciones contra el mismo almacenamiento. Un poco exagerado si me preguntas, pero en el lado positivo es el mejor en cuanto a la ofuscación (e implementas cualquier función de distribución que tu alma desee, y puedes cambiar la función de distribución en cualquier momento que desees).
¿Función hash? http://www.partow.net/programming/hashfunctions/index.html
Elija un número de 8 o 9 dígitos al azar, digamos 839712541. Luego, tome la representación binaria de su número de orden (para este ejemplo, no estoy usando el complemento de 2), rellene el mismo número de bits (30), inviértalo y x el número de orden invertido y el número mágico. Por ejemplo:
1 = 000000000000000000000000000001
Flip = 100000000000000000000000000000
839712541 = 110010000011001111111100011101
XOR = 010010000011001111111100011101 = 302841629
2 = 000000000000000000000000000010
Flip = 010000000000000000000000000000
839712541 = 110010000011001111111100011101
XOR = 100010000011001111111100011101 = 571277085
Para recuperar los números de pedido, xo el número de salida con su número mágico, conviértalo en una cadena de bits y en reversa.
En un número de 9 dígitos, el primer dígito es un índice aleatorio entre 0 y 7 (o 1-8). Pon otro dígito aleatorio en esa posición. El resto es el "número de orden real:
- Orden de origen: 100
- Índice aleatorio: 5
- Dígito aleatorio: 4 (garantizado, rodado un dado :))
Resultado: 500040100
Orig Nr: 101
- Índice aleatorio: 2
- Dígito aleatorio 6
- Resultado: 200001061
Usted puede decidir que el quinto (o cualquier otro) dígito es el índice.
O bien, si puede vivir con números de pedido reales de 6 dígitos, también puede introducir un índice "secundario". Y puede invertir el orden de los dígitos en el orden "real" nr.
Si su ID de pedido es única, simplemente puede hacer un prefijo y agregar / mezclar ese prefijo con su ID de pedido.
Algo como esto:
long pre = DateTime.Now.Ticks % 100;
string prefix = pre.ToString();
string number = prefix + YOURID.ToString()
Vi esto bastante tarde, (!) De ahí mi respuesta bastante tardía. Puede ser útil para otros que vendrán después.
Usted dijo: "Mi tercer pensamiento fue" eh, simplemente encriptar el maldito asunto ", pero si uso una biblioteca de encriptación de stock, tendría que post-procesarla para obtener el requisito de solo 8 o 9 dígitos".
Eso es correcto. El cifrado es reversible y se garantiza que es único para una entrada determinada. Como usted señala, la mayoría de las encriptaciones estándar no tienen el tamaño de bloque correcto. Sin embargo, hay uno, Hasty Pudding Cipher que puede tener cualquier tamaño de bloque de 1 bit hacia arriba.
Alternativamente puedes escribir el tuyo. Dado que no necesita algo que la NSA no pueda descifrar, puede construir un cifrado sencillo de Feistel para satisfacer sus necesidades.
<?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/>";
?>