Contamos con la mejor respuesta que hallamos online. Esperamos que te resulte de ayuda y si quieres compartir algún detalle que nos pueda ayudar a crecer hazlo libremente.
Solución:
Editar: Lo siento, ahora me doy cuenta de que ya tenía casi toda mi respuesta, acababa de determinar incorrectamente qué factor usar para qué dígito.
Mi respuesta completa ahora se puede resumir con esta sola oración:
Tienes el factor invertido, estás multiplicando los dígitos equivocados por 2 dependiendo de la longitud del número.
Eche un vistazo al artículo de Wikipedia sobre el algoritmo de Luhn.
La razón por la que su suma de verificación no es válida la mitad de las veces es que con sus cheques, la mitad de las veces su número tiene un número impar de dígitos y luego duplica el dígito equivocado.
Para 37283, al contar desde la derecha, obtienes esta secuencia de números:
3 * 1 = 3 3
8 * 2 = 16 --> 1 + 6 = 7
2 * 1 = 2 2
7 * 2 = 14 --> 1 + 4 = 5
+ 3 * 1 = 3 3
= 20
El algoritmo requiere que sume los dígitos individuales del número original y los dígitos individuales del producto de esos “cada dos dígitos desde la derecha”.
Entonces, desde la derecha, sumas 3 + (1 + 6) + 2 + (1 + 4) + 3, lo que te da 20.
Si el número con el que terminas termina en cero, lo que hace 20, el número es válido.
Ahora, su pregunta sugiere que desea saber cómo generar la suma de verificación, bueno, eso es fácil, haga lo siguiente:
- Agregue un cero adicional, por lo que su número va de xyxyxyxy a xyxyxyxy0
- Calcule la suma de verificación de luhn para el nuevo número
- Tome la suma, módulo 10, por lo que obtiene un solo dígito de 0 a 10
- Si el dígito es 0, entonces felicidades, su dígito de suma de verificación fue un cero
- De lo contrario, calcule 10 dígitos para obtener lo que necesita para el último dígito, en lugar de ese cero
Ejemplo: el número es 12345
- Tachar un cero: 123450
-
Calcule la suma de verificación de Luhn para 123450, lo que da como resultado
0 5 4 3 2 1 1 2 1 2 1 2 <-- factor 0 10 4 6 2 2 <-- product 0 1 0 4 6 2 2 <-- sum these to: 0+1+0+4+6+2+2=15
-
Toma la suma (15), módulo 10, que te da 5
- El dígito (5), no es cero
- Calcula 10-5, lo que te da 5, el último dígito debe ser 5.
Entonces el resultado es 123455.
su php tiene errores, conduce a un bucle infinito. Esta es la versión de trabajo que estoy usando, modificada a partir de su código.
function Luhn($número)
$stack = 0; $number = str_split(strrev($number)); foreach ($number as $key => $value) if ($key % 2 == 0) $value = array_sum(str_split($value * 2)); $stack += $value; $stack %= 10; if ($stack != 0) $stack -= 10; $stack = abs($stack); $number = implode('', array_reverse($number)); $number = $number . strval($stack); return $number;
Cree un php y ejecútelo en su host local Luhn (xxxxxxxx) para confirmar.
MALO
Literalmente no puedo creer cuántas implementaciones de mala calidad hay por ahí.
IDAutomation tiene un ensamblado .NET con una función MOD10() para crear, pero parece que no funciona. En Reflector, el código es demasiado largo para lo que se supone que debe hacer de todos modos.
MALO
Este desorden de una página que actualmente está vinculada desde Wikipedia (!) para Javascript tiene varias implementaciones de verificación que ni siquiera devuelven el mismo valor cuando llamo a cada una.
BIEN
La página vinculada desde la página de Luhn de Wikipedia tiene un codificador Javascript que parece funcionar:
// Javascript
String.prototype.luhnGet = function()
var luhnArr = [[0,1,2,3,4,5,6,7,8,9],[0,2,4,6,8,1,3,5,7,9]], sum = 0;
this.replace(/D+/g,"").replace(/[d]/g, function(c, p, o)
sum += luhnArr[ (o.length-p)&1 ][ parseInt(c,10) ]
);
return this + ((10 - sum%10)%10);
;
alert("54511187504546384725".luhnGet());
BIEN
Esta muy útil página EE4253 verifica el dígito de control y también muestra el cálculo completo y la explicación.
BIEN
Necesitaba código C# y terminé usando este código de proyecto de código:
// C#
public static int GetMod10Digit(string data)
int sum = 0;
bool odd = true;
for (int i = data.Length - 1; i >= 0; i--)
if (odd == true)
int tSum = Convert.ToInt32(data[i].ToString()) * 2;
if (tSum >= 10)
string tData = tSum.ToString();
tSum = Convert.ToInt32(tData[0].ToString()) + Convert.ToInt32(tData[1].ToString());
sum += tSum;
else
sum += Convert.ToInt32(data[i].ToString());
odd = !odd;
int result = (((sum / 10) + 1) * 10) - sum;
return result % 10;
BIEN
Este código de validación en C# parece funcionar, aunque un poco difícil de manejar. Solo lo usé para verificar que lo anterior fuera correcto.
Eres capaz de avalar nuestra investigación poniendo un comentario o puntuándolo te lo agradecemos.