note 86172 added to function.sha1

From: Date: Mon, 06 Oct 2008 19:01:56 +0000
Subject: note 86172 added to function.sha1
Groups: php.notes 
Request: Send a blank email to php-notes+get-145102@lists.php.net to get a copy of this message
Sometimes you want the digest in both readable notation (such as hexadecimal) and raw binary. At other times you want the digest in a notation other than hexadecimal. The following getDigestNotation() function takes a binary string and returns it in base 2, 4, 8, 16, 32, or 64 notation. It works with sha1(), md5(), hash(), or anything else that can output a raw binary string. It works similar to the session.hash_bits_per_character php.ini configuration option. You can specify which characters to use for each position, or use the default, which matches session.hash_bits_per_character (0-9, a-z, A-Z, "-", ","). The practical range of bits to use per character ($bitsPerCharacter) is 1 to 6; you may use more, but you will have to provide your own base character string ($chars) that is at least pow(2, $bitsPerCharacter) characters long. So even with 7 bits per character you need to specify a value for $chars that is 128 characters long, which exceeds the number of printable ASCII characters. The output's radix relates to the value of $bitsPerCharacter as follows: 1: base-2 (binary) 2: base-4 3: base-8 (octal) 4: base-16 (hexadecimal) 5: base-32 6: base-64 <?php $raw = sha1(uniqid(mt_rand(), TRUE), TRUE); echo getDigestNotation($raw, 6); function getDigestNotation($rawDigest, $bitsPerCharacter, $chars = NULL) { if ($chars === NULL || strlen($chars) < 2) { $chars '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,'; } if ($bitsPerCharacter < 1) { // $bitsPerCharacter must be at least 1 $bitsPerCharacter = 1; } elseif (strlen($chars) < pow(2, $bitsPerCharacter)) { // Character length of $chars is too small for $bitsPerCharacter // Set $bitsPerCharacter to greatest value allowed by length of $chars $bitsPerCharacter = 1; do { $bitsPerCharacter++; } while (strlen($chars) > pow(2, $bitsPerCharacter)); } $bytes = unpack('C*', $rawDigest); $byteCount = count($bytes); $out = ''; $byte = array_shift($bytes); $bitsRead = 0; for ($i = 0; $i < $byteCount * 8 / $bitsPerCharacter; $i++) { if ($bitsRead + $bitsPerCharacter > 8) { // Not enough bits remain in this byte for the current character // Get remaining bits and get next byte $oldBits = $byte - ($byte >> 8 - $bitsRead << 8 - $bitsRead); if (count($bytes) == 0) { // Last bits; match final character and exit loop $out .= $chars[$oldBits]; break; } $oldBitCount = 8 - $bitsRead; $byte = array_shift($bytes); $bitsRead = 0; } else { $oldBitCount = 0; } // Read only the needed bits from this byte $bits = $byte >> 8 - ($bitsRead + ($bitsPerCharacter - $oldBitCount)); $bits = $bits - ($bits >> $bitsPerCharacter - $oldBitCount << $bitsPerCharacter - $oldBitCount); $bitsRead += $bitsPerCharacter - $oldBitCount; if ($oldBitCount > 0) { // Bits come from seperate bytes, add $oldBits to $bits $bits = ($oldBits << $bitsPerCharacter - $oldBitCount) | $bits; } $out .= $chars[$bits]; } return $out; } ?> Lastly, depending on the digest length, there may be fewer bits remaining for the last character than $bitsPerCharacter, so the last character will be smaller. The same thing happens with PHP's session ID generator, when 5 or 6 is used for session.hash_bits_per_character. ---- Server IP: 209.41.74.194 Probable Submitter: 207.88.114.211 ---- Manual Page -- http://www.php.net/manual/en/function.sha1.php Edit -- https://master.php.net/note/edit/86172 Del: integrated -- https://master.php.net/note/delete/86172/integrated Del: useless -- https://master.php.net/note/delete/86172/useless Del: bad code -- https://master.php.net/note/delete/86172/bad+code Del: spam -- https://master.php.net/note/delete/86172/spam Del: non-english -- https://master.php.net/note/delete/86172/non-english Del: in docs -- https://master.php.net/note/delete/86172/in+docs Del: other reasons-- https://master.php.net/note/delete/86172 Reject -- https://master.php.net/note/reject/86172 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#145102) next »