3

The docs (http://php.net/manual/de/function.crypt.php) for the crypt() function show the following example for an MD5 hash:

$1$rasmusle$rISCgZzpwk3UhDidwXvin0

I understand, that "$1$" is the prefix, which contains the information, that the hash is an MD5 hash.

But how is the rest of the string an MD5 hash? Normally it should be a 32 char string (0-9, a-f), right?

I'm sure, it's a stupid question, but I still want to ask.

mmvsbg
  • 3,570
  • 17
  • 52
  • 73
Tream
  • 1,049
  • 2
  • 13
  • 29
  • 2
    What you're expecting is a hexadecimal-encoded string, what you got is a base64-encoded string. They both represent the binary output of the hashing function. Also: `$ID$SALT$HASH` What you *should* be using is [`password_hash()`](http://php.net/manual/en/function.password-hash.php) and most certainly not MD5. – Sammitch May 12 '15 at 17:53
  • 1
    @Sammitch While `password_hash()` is definitely better than `crypt()`, it's not available prior to PHP 5.5. For example, I still update multiple sites with PHP 5.3 or 5.4, and I'd definitely like to use `password_hash()` there. – PurkkaKoodari May 12 '15 at 18:14
  • 3
    @Pietu1998 - there is a [userland implementation of password_*](https://github.com/ircmaxell/password_compat) for versions of PHP from 5.3.7 upwards – Mark Baker May 12 '15 at 18:23
  • 1
    @Pietu1998 see Mark's link above. It's also worth noting that password_compat was written by the same guy that wrote `password_hash()`, and it's even linked to from the documentation page. – Sammitch May 12 '15 at 18:56

1 Answers1

3

Normally it should be a 32 char string (0-9, a-f), right?

That is not correct (at least strictly speaking). Technically, a MD5 hash is a 128 bit numeric value. The form that you are used to is simply a hexadecimal representation of that number. It is often chosen because they are easy to exchange as strings (128-bit integers are difficult to handle. After all, a typical integer variable usually only holds 64 bit). Consider the following examples:

  1. md5("test") in hexadecimal (base 16) representation: 098f6bcd4621d373cade4e832627b4f6
  2. md5("test") in base 64 representation: CY9rzUYh03PK3k6DJie09g==
  3. md5("test") in decimal (base 10) representation: 12707736894140473154801792860916528374
  4. md5("test") in base 27 representation (never used, just because I can and to prove my point): ko21h9o9h8bc1hgmao4e69bn6f

All these strings represent the same numerical value, just in different bases.

helmbert
  • 35,797
  • 13
  • 82
  • 95