Pregunta

En mi tabla de base de datos de usuario, tomo el hash MD5 de la dirección de correo electrónico de un usuario como id.

Ejemplo: email (example@example.org) = id (d41d8cd98f00b204e9800998ecf8427e)

Desafortunadamente, ahora tengo que representar los identificadores como valores enteros, para poder usar una API donde la identificación solo puede ser un entero.

Ahora estoy buscando una forma de codificar la identificación en un número entero para enviar una decodificación nuevamente al recibirla. ¿Cómo podría hacer esto?

Mis ideas hasta ahora:

  1. convert_uuencode () y convert_uudecode () para el hash MD5
  2. reemplaza cada carácter del hash MD5 por su valor ord ()

¿Qué enfoque es mejor? ¿Conoces formas aún mejores de hacer esto?

Espero que me puedan ayudar. ¡Muchas gracias de antemano!

¿Fue útil?

Solución

Ten cuidado. La conversión de los MD5 a un número entero requerirá soporte para enteros grandes (128 bits). Lo más probable es que la API que está utilizando solo admitirá enteros de 32 bits, o peor, podría estar tratando con el número en coma flotante. De cualquier manera, su identificación será mordida. Si este es el caso, solo asignar una segunda ID arbitrariamente es una forma mucho mejor de lidiar con las cosas que tratar de convertir el MD5 en un entero.

Sin embargo, si está seguro de que la API puede manejar enteros arbitrariamente grandes sin problemas, puede convertir el MD5 de hexadecimal a un entero. Sin embargo, es muy probable que PHP no sea compatible con este incorporado, ya que intentará representarlo como un entero de 32 bits o un punto flotante; probablemente necesitará usar la biblioteca PHP GMP para ello.

Otros consejos

Hay buenas razones, expresadas por otros, para hacerlo de otra manera.

Pero si lo que quieres hacer es convertir un hash md5 en una cadena de dígitos decimales (que es lo que creo que realmente quieres decir con " representar por un entero " ;, ya que un md5 ya es un entero en forma de cadena), y transformarlo nuevamente en la misma cadena md5:

function md5_hex_to_dec($hex_str)
{
    $arr = str_split($hex_str, 4);
    foreach ($arr as $grp) {
        $dec[] = str_pad(hexdec($grp), 5, '0', STR_PAD_LEFT);
    }
    return implode('', $dec);
}

function md5_dec_to_hex($dec_str)
{
    $arr = str_split($dec_str, 5);
    foreach ($arr as $grp) {
        $hex[] = str_pad(dechex($grp), 4, '0', STR_PAD_LEFT);
    }
    return implode('', $hex);
}

Demostración:

$md5 = md5('example@example.com');
echo $md5 . '<br />';  // 23463b99b62a72f26ed677cc556c44e8
$dec = md5_hex_to_dec($md5);
echo $dec . '<br />';  // 0903015257466342942628374306682186817640
$hex = md5_dec_to_hex($dec);
echo $hex;             // 23463b99b62a72f26ed677cc556c44e8

Por supuesto, debe tener cuidado al usar cualquiera de las cadenas, como asegurarse de usarlas solo como tipo de cadena para evitar perder los ceros a la izquierda, asegurándose de que las cadenas tengan la longitud correcta, etc.

Para una condensación de 32 bits, se puede hacer una solución simple seleccionando 4 pares hexadecimales (8 caracteres) del hash MD5, donde cada par representa un byte, y luego convirtiéndolo con intval () .

Para un Int de 32 bits sin firmar:

$inthash = intval(substr(md5($str), 0, 8), 16);

Solo para el valor positivo de un Int de 32 bits con signo:

$inthash = intval(substr(md5($str), 0, 8), 16) >> 1;

Es probable que esto solo funcione para valores de hasta 64 bits (8 bytes o 16 caracteres) para la mayoría de los sistemas modernos como se indica en los documentos.

En un sistema que puede acomodar Ints de 64 bits, una estrategia de división que consume todo el hash MD5 de 128 bits como 2 Ints podría verse así:

$hash = md5($str);
$inthash1 = intval(substr($hash, 0, 16), 16);
$inthash2 = intval(substr($hash, 16, 16), 16);

Puede usar hexdec para analizar la cadena hexadecimal y almacenar el número en la base de datos.

¿No podría simplemente agregar otro campo que fuera un campo int de incremento automático?

¿Por qué ord ()? md5 produce un valor normal de 16 bytes, presentado en hexadecimal para una mejor legibilidad. Por lo tanto, no puede convertir un valor de 16 bytes a un entero de 4 u 8 bytes sin pérdida. Debe cambiar alguna parte de sus algoritmos para usar esto como id.

¿qué pasa con:

$ float = hexdec (md5 ('cadena'));

o

$ int = (entero) (substr (hexdec (md5 ('string')), 0,9) * 100000000);

Sin embargo, ¿hay posibilidades de colisión definitivamente mayores pero sigue siendo buena para usar en lugar de hash en DB?

aplausos,

/ Marcin

Use la dirección de correo electrónico como el nombre de un archivo temporal en blanco en una carpeta compartida, como /var/myprocess/example@example.org

Luego, llame a ftok en el nombre del archivo. ftok devolverá un ID entero único.

Sin embargo, no se garantizará que sea único, pero probablemente será suficiente para su API.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top