Domanda

Nella mia tabella del database utenti, prendo l'hash MD5 dell'indirizzo e-mail di un utente come ID.

Esempio: email (esempio@esempio.org) = id (d41d8cd98f00b204e9800998ecf8427e)

Sfortunatamente, devo rappresentare gli ID come valori interi ora - per poter usare un'API in cui l'id può essere solo un numero intero.

Ora sto cercando un modo per codificare l'id in un numero intero per inviarlo di nuovo decodificandolo alla ricezione. Come potrei farlo?

Le mie idee finora:

  1. convert_uuencode () e convert_uudecode () per l'hash MD5
  2. sostituisce ogni carattere dell'hash MD5 con il suo valore ord ()

Quale approccio è migliore? Conosci modi ancora migliori per farlo?

Spero che tu mi possa aiutare. Grazie mille in anticipo!

È stato utile?

Soluzione

Stai attento. La conversione degli MD5 in un numero intero richiederà il supporto per numeri interi grandi (128 bit). È probabile che l'API che stai utilizzando supporterà solo numeri interi a 32 bit - o peggio, potrebbe avere a che fare con il numero in virgola mobile. In entrambi i casi, il tuo ID verrà bloccato. In questo caso, assegnare un secondo ID in modo arbitrario è un modo molto migliore per gestire le cose rispetto al tentativo di convertire l'MD5 in un numero intero.

Tuttavia, se si è sicuri che l'API è in grado di gestire senza problemi numeri interi arbitrariamente grandi, è possibile convertire MD5 da esadecimale a un numero intero. Molto probabilmente PHP non supporta questo built-in, poiché tenterà di rappresentarlo come numero intero a 32 bit o in virgola mobile; probabilmente dovrai utilizzare la libreria PHP GMP per questo.

Altri suggerimenti

Ci sono buone ragioni, dichiarate da altri, per farlo in un modo diverso.

Ma se quello che vuoi fare è convertire un hash md5 in una stringa di cifre decimali (che è ciò che penso davvero intendi "rappresentano un numero intero", poiché un md5 è già un numero intero in forma di stringa), e trasformalo nuovamente nella stessa stringa 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);
}

Demo:

$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

Ovviamente, dovresti stare attento a usare una delle due stringhe, come assicurarti di usarle solo come tipo di stringa per evitare di perdere gli zeri iniziali, assicurandoti che le stringhe abbiano la lunghezza corretta, ecc.

Per una condensazione a 32 bit, una soluzione semplice potrebbe essere fatta selezionando 4 coppie esadecimali (8 caratteri) dell'hash MD5, dove ogni coppia rappresenta un byte, e quindi convertendola con intval () .

Per un Int a 32 bit senza segno:

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

Solo per il valore positivo di un Int a 32 bit con segno:

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

Probabilmente funzionerà solo con valori fino a 64 bit (8 byte o 16 caratteri) per la maggior parte dei sistemi moderni, come indicato nei documenti.

Su un sistema che può contenere Ints a 64 bit, una strategia di suddivisione che consuma l'intero hash MD5 a 128 bit come 2 Ints potrebbe apparire come:

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

Potresti usare hexdec per analizzare la stringa esadecimale e memorizzare il numero nel database.

Non potresti semplicemente aggiungere un altro campo che era un campo int con incremento automatico?

Perché ord ()? md5 produce un normale valore di 16 byte, presentato in esadecimale per una migliore leggibilità. Quindi non è possibile convertire il valore di 16 byte in un numero intero di 4 o 8 byte senza perdita. Devi modificare alcune parti dei tuoi algoritmi per usarlo come id.

che dire di:

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

o

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

Probabilmente maggiori possibilità di collisione ma comunque abbastanza buono da usare al posto dell'hash nel DB?

applausi,

/ Marcin

Utilizza l'indirizzo e-mail come nome file di un file temporaneo vuoto in una cartella condivisa, come /var/myprocess/example@example.org

Quindi, chiama ftok sul nome del file. ftok restituirà un ID intero univoco.

Non sarà garantito che sia unico, ma probabilmente sarà sufficiente per la tua API.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top