Pergunta

Na minha tabela de banco de usuário, eu tomo o hash MD5 do endereço de e-mail de um usuário como o id.

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

Infelizmente, eu tenho que representam os ids como valores inteiros agora -., A fim de ser capaz de usar uma API onde o id só pode ser um inteiro

Agora eu estou procurando uma maneira de codificar o id em um inteiro para enviar uma decodificação novamente quando receber. Como eu poderia fazer isso?

As minhas idéias até agora:

  1. convert_uuencode() e convert_uudecode() para o hash MD5
  2. substituir todos os caracteres de hash MD5 pelo seu valor ord()

Qual abordagem é melhor? Você sabe ainda melhores maneiras de fazer isso?

Eu espero que você possa me ajudar. Muito obrigado antecipadamente!

Foi útil?

Solução

Tenha cuidado. Convertendo os MD5s para um número inteiro exigirá suporte para grandes números inteiros (128 bits). As possibilidades são o API que você está usando apenas apoiará inteiros de 32 bits - ou pior, pode ser lidar com o número em ponto flutuante. De qualquer forma, o seu ID vai ficar munged. Se este for o caso, basta atribuir um segundo ID arbitrariamente é uma maneira muito melhor para lidar com as coisas do que tentar converter o MD5 em um inteiro.

No entanto, se você estiver certeza que a API pode lidar com arbitrariamente grandes inteiros, sem problemas, você pode simplesmente converter o MD5 de hexadecimal para um número inteiro. PHP provavelmente não suporta este built-in no entanto, como ele vai tentar representá-lo tanto como um inteiro de 32 bits ou um ponto flutuante; você provavelmente vai precisar usar a PHP GMP biblioteca para ele.

Outras dicas

Há boas razões, declarados por outros, para fazê-lo de maneira diferente.

Mas se o que você quer fazer é converter um hash MD5 em um string de decimal dígitos (que é o que eu acho que você realmente quer dizer por "Representar por um inteiro", uma vez que um md5 já é um número inteiro na forma de string), e transformá-lo de volta para a mesma cadeia 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);
}

Demonstração:

$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

É claro, você tem que ter cuidado usando corda, como certificando-se de usá-los apenas como tipo de cadeia para evitar a perda zeros à esquerda, assegurando as cordas são os comprimentos corretos, etc.

Para uma condensação de 32 bits, uma solução simples pode ser feito seleccionando 4 pares sextavadas (8 caracteres) do hash MD5, onde cada par representa um byte, e, em seguida, a conversão de que, com intval() .

Para uma não assinado de 32 bits Int:

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

Para o valor positiva apenas de um sinal de 32 bit Int:

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

Isso provavelmente vai funcionar apenas para valores de até 64 bits (8 bytes ou 16 caracteres) para a maioria dos sistemas modernos como observado no docs.

Em um sistema que pode acomodar Ints de 64 bits, uma estratégia de divisão que consome todo o hash MD5 de 128 bits como 2 Ints pode parecer:

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

Você pode usar hexdec para analisar a cadeia hexadecimal e armazenar o número no banco de dados.

Você não pode apenas adicionar outro campo que era um campo int auto-incremento?

Por ord ()? md5 produzir valor de 16 bytes normal, que lhe é apresentado em hexadecimal para melhor legibilidade. Então você não pode converter o valor de 16 bytes para 4 ou 8 inteiro byte sem perda. Você deve alterar alguma parte de seus algoritmos para usar isso como id.

o que acontece com:

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

ou

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

Definietly maiores chances de colisão, mas ainda bom enaugh para usar em vez de hash em DB embora?

aplausos,

/ Marcin

Use o endereço de e-mail como nome de arquivo de um espaço em branco, arquivos temporários em uma pasta compartilhada, como /var/myprocess/example@example.org

Em seguida, chame ftok no nome do arquivo. ftok irá retornar um único, ID inteiro.

Não vai ser garantido para ser embora única, mas provavelmente será suficiente para a sua API.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top