|
crc32
Calculates the crc32 polynomial of a string
(PHP 4 >= 4.0.1, PHP 5)
Example 2402. Displaying a crc32 checksumThis example shows how to print a converted checksum with the printf() function: <?php Code Examples / Notes » crc32xethmir
This is a really simple way of displaying the crc-32 hexadecimal code/checksum for a file... (absolute paths are more reliable) <? $file = "http://foo.net/bar.jpg"; // Read the file into an array $data = file($file); // Join the array into a string $data = implode('', $data); // Calculate the crc $crc = crc32($data); //convert from decimal to hexadecimal $crchex=DecHex($crc*1); //echo the result echo "$crchex"; ?> arachnid
Note that the CRC32 algorithm should NOT be used for cryptographic purposes, or in situations where a hostile/untrusted user is involved, as it is far too easy to generate a hash collision for CRC32 (two different binary strings that have the same CRC32 hash). Instead consider SHA-1 or MD5.
roberto
MODBUS RTU, CRC16, input-> modbus rtu string output -> 2bytes string, in correct modbus order function crc16($string,$length=0){ $auchCRCHi=array( 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40); $auchCRCLo=array( 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40); $length =($length<=0?strlen($string):$length); $uchCRCHi =0xFF; $uchCRCLo =0xFF; $uIndex =0; for ($i=0;$i<$length;$i++){ $uIndex =$uchCRCLo ^ ord(substr($string,$i,1)); $uchCRCLo =$uchCRCHi ^ $auchCRCHi[$uIndex]; $uchCRCHi =$auchCRCLo[$uIndex] ; } return(chr($uchCRCLo).chr($uchCRCHi)); } adam dot chout
it should be poitned out that this function does not operate the same on 32-bit systems and 64-bit systems. so any php code written for one is not portable on the other. more information can be found here: http://bugs.php.net/bug.php?id=39062 manuel
In response to quix at free dot fr (http://www.php.net/manual/de/function.crc32.php#31832): Through buffering his CRC32 calculation is about 2-4 times faster: <?php function __crc32_file($name) { // Creates a CRC from a file // Info: look at __crc32_string global $__crc32_table; // Start out with all bits set high. $crc = 0xffffffff; // Open the file $fp = fopen($name, "rb"); // Read the file using a 1MB buffer // This will speed up CRC calculation at least 2-4x! // (5MB file: 15sec instead of 50sec) if ($fp != false) { $buffer = ''; while (!feof($fp)) { $buffer = fread($fp, 1048576); // Buffer 1MByte of file into memory $len = strlen($buffer); // Cache buffer length (just this saves about 10sec on a 5MB file!) for ($i = 0; $i < $len; $i++) { $crc = (($crc >> 8) & 0x00ffffff) ^ $__crc32_table[($crc & 0xFF) ^ ord($buffer[$i])]; } } fclose($fp); } // Exclusive OR the result with the beginning value. return $crc ^ 0xffffffff; } ?> petteri
If you have php version<5.1.2 you might use this. It's a little bit faster than __crc32_file() :) Ps. crc32_combine() is ported directly from zlib. <?php function crc32_file($filename) { $fp=fopen($filename, "rb"); $old_crc=false; if ($fp != false) { $buffer = ''; while (!feof($fp)) { $buffer=fread($fp, 10485760); $len=strlen($buffer); $t=crc32($buffer); if ($old_crc) { $crc32=crc32_combine($old_crc, $t, $len); $old_crc=$crc32; } else { $crc32=$old_crc=$t; } } fclose($fp); } else { print "Cannot open file\n"; } return $crc32; } function crc32_combine($crc1, $crc2, $len2) { $odd[0]=0xedb88320; $row=1; for($n=1;$n<32;$n++) { $odd[$n]=$row; $row<<=1; } gf2_matrix_square($even,$odd); gf2_matrix_square($odd,$even); do { /* apply zeros operator for this bit of len2 */ gf2_matrix_square($even, $odd); if ($len2 & 1) $crc1=gf2_matrix_times($even, $crc1); $len2>>=1; /* if no more bits set, then done */ if ($len2==0) break; /* another iteration of the loop with odd and even swapped */ gf2_matrix_square($odd, $even); if ($len2 & 1) $crc1=gf2_matrix_times($odd, $crc1); $len2>>= 1; } while ($len2 != 0); $crc1 ^= $crc2; return $crc1; } function gf2_matrix_square(&$square, &$mat) { for ($n=0;$n<32;$n++) { $square[$n]=gf2_matrix_times($mat, $mat[$n]); } } function gf2_matrix_times($mat, $vec) { $sum=0; $i=0; while ($vec) { if ($vec & 1) { $sum ^= $mat[$i]; } $vec>>= 1; $i++; } return $sum; } ?> mail
I used the abs value of this function on a 32-bit system. When porting the code to a 64-bit system Iâve found that the value is different. The following code has the same outcome on both systems. <?php $crc = abs(crc32($string)); if( $crc & 0x80000000){ $crc ^= 0xffffffff; $crc += 1; } /* Old solution * $crc = abs(crc32($string)) */ ?> schmeic-php
I think that Mario's (spectrumizer at cycos dot net) CRC16 algorithm might be wrong. At least according to these two online calculators: http://www.zorc.breitbandkatze.de/crc.html http://www.lammertbies.nl/comm/info/crc-calculation.html However, it seems that there can be some confusion concerning "official" CRC16 algorithms. See this article for two possible CRC16-CCITT algorithms: http://www.joegeluso.com/software/articles/ccitt.htm Here is a php implementation of the "bad" CRC16-CCITT algorithm from the article. The "bad" implementation might not match the "official" algorithm, but is widely used, including by the two crc calculators mentioned above. Note that crc16-CCITT is also referred to as crc16c. <?php // this function is used to calculate the (common) crc16c for an entire buffer function calculate_common_crc16c($buffer) { $crc16c = 0xffff; // the crc initial value $buffer_length = strlen($buffer); for ($i = 0; $i < $buffer_length; $i++) { $ch = ord($buffer[$i]); $crc16c = update_common_crc16c($ch, $crc16c); } return $crc16c; } // this function is used to calculate the (common) crc16c byte by byte // $ch is the next byte and $crc16c is the result from the last call, or 0xffff initially function update_common_crc16c($ch, $crc16c) { global $crc16c_polynomial; // This comment was in the code from // http://www.joegeluso.com/software/articles/ccitt.htm // Why are they shifting this byte left by 8 bits?? // How do the low bits of the poly ever see it? $ch <<= 8; for($i = 0; $i < 8; $i++) { if (($crc16c ^ $ch) & 0x8000) { $xor_flag = true; } else { $xor_flag = false; } $crc16c = $crc16c << 1; if ($xor_flag) { $crc16c = $crc16c ^ $crc16c_polynomial; } $ch = $ch << 1; } // mask off (zero out) the upper two bytes $crc16c = $crc16c & 0x0000ffff; return $crc16c; } ?> slimshady451
I see a lot of function for crc32_file, but for php version >= 5.1.2 don't forget you can use this : function crc32_file($filename) { return hash_file ('CRC32', $filename , FALSE ); } Using crc32(file_get_contents($filename)) will use too many memory on big file so don't use it. quix
I needed the crc32 of a file that was pretty large, so I didn't want to read it into memory. So I made this: <?php $GLOBALS['__crc32_table']=array(); // Lookup table array __crc32_init_table(); function __crc32_init_table() { // Builds lookup table array // This is the official polynomial used by // CRC-32 in PKZip, WinZip and Ethernet. $polynomial = 0x04c11db7; // 256 values representing ASCII character codes. for($i=0;$i <= 0xFF;++$i) { $GLOBALS['__crc32_table'][$i]=(__crc32_reflect($i,8) << 24); for($j=0;$j < 8;++$j) { $GLOBALS['__crc32_table'][$i]=(($GLOBALS['__crc32_table'][$i] << 1) ^ (($GLOBALS['__crc32_table'][$i] & (1 << 31))?$polynomial:0)); } $GLOBALS['__crc32_table'][$i] = __crc32_reflect($GLOBALS['__crc32_table'][$i], 32); } } function __crc32_reflect($ref, $ch) { // Reflects CRC bits in the lookup table $value=0; // Swap bit 0 for bit 7, bit 1 for bit 6, etc. for($i=1;$i<($ch+1);++$i) { if($ref & 1) $value |= (1 << ($ch-$i)); $ref = (($ref >> 1) & 0x7fffffff); } return $value; } function __crc32_string($text) { // Creates a CRC from a text string // Once the lookup table has been filled in by the two functions above, // this function creates all CRCs using only the lookup table. // You need unsigned variables because negative values // introduce high bits where zero bits are required. // PHP doesn't have unsigned integers: // I've solved this problem by doing a '&' after a '>>'. // Start out with all bits set high. $crc=0xffffffff; $len=strlen($text); // Perform the algorithm on each character in the string, // using the lookup table values. for($i=0;$i < $len;++$i) { $crc=(($crc >> 8) & 0x00ffffff) ^ $GLOBALS['__crc32_table'][($crc & 0xFF) ^ ord($text{$i})]; } // Exclusive OR the result with the beginning value. return $crc ^ 0xffffffff; } function __crc32_file($name) { // Creates a CRC from a file // Info: look at __crc32_string // Start out with all bits set high. $crc=0xffffffff; if(($fp=fopen($name,'rb'))===false) return false; // Perform the algorithm on each character in file for(;;) { $i=@fread($fp,1); if(strlen($i)==0) break; $crc=(($crc >> 8) & 0x00ffffff) ^ $GLOBALS['__crc32_table'][($crc & 0xFF) ^ ord($i)]; } @fclose($fp); // Exclusive OR the result with the beginning value. return $crc ^ 0xffffffff; } ?> spectrumizer
Here is a tested and working CRC16-Algorithm: <?php function crc16($string) { $crc = 0xFFFF; for ($x = 0; $x < strlen ($string); $x++) { $crc = $crc ^ ord($string[$x]); for ($y = 0; $y < 8; $y++) { if (($crc & 0x0001) == 0x0001) { $crc = (($crc >> 1) ^ 0xA001); } else { $crc = $crc >> 1; } } } return $crc; } ?> Regards, Mario ren
Dealing with 32 bit unsigned values overflowing 32 bit php signed values can be done by adding 0x10000000 to any unexpected negative result, rather than using sprintf. $i = crc32('1'); printf("%u\n", $i); if (0 > $i) { // Implicitly casts i as float, and corrects this sign. $i += 0x100000000; } var_dump($i); Outputs: 2212294583 float(2212294583) same
bit by bit crc32 computation <?php function bitbybit_crc32($str,$first_call=false){ //reflection in 32 bits of crc32 polynomial 0x04C11DB7 $poly_reflected=0xEDB88320; //=0xFFFFFFFF; //keep track of register value after each call static $reg=0xFFFFFFFF; //initialize register on first call if($first_call) $reg=0xFFFFFFFF; $n=strlen($str); $zeros=$n<4 ? $n : 4; //xor first $zeros=min(4,strlen($str)) bytes into the register for($i=0;$i<$zeros;$i++) $reg^=ord($str{$i})<<$i*8; //now for the rest of the string for($i=4;$i<$n;$i++){ $next_char=ord($str{$i}); for($j=0;$j<8;$j++) $reg=(($reg>>1&0x7FFFFFFF)|($next_char>>$j&1)<<0x1F) ^($reg&1)*$poly_reflected; } //put in enough zeros at the end for($i=0;$i<$zeros*8;$i++) $reg=($reg>>1&0x7FFFFFFF)^($reg&1)*$poly_reflected; //xor the register with 0xFFFFFFFF return ~$reg; } $str="123456789"; //whatever $blocksize=4; //whatever for($i=0;$i<strlen($str);$i+=$blocksize) $crc=bitbybit_crc32(substr($str,$i,$blocksize),!$i); ?> lander
A simple and quite fast (10ms/Mb) way to generate checksums used with the popular SFV (Simple File Verification) format. strtoupper() isn't really needed, but the output looks better this way ;) <?php function generate_sfv_checksum($filename) { $sfv_checksum = strtoupper(dechex(crc32(file_get_contents($filename)))); return $sfv_checksum; } ?> gribber _at hellburner dot_ net
A little correction to the sfv checksum code above, this was confuseing me for a while, heading zeros was striped away. <?php function sfv_checksum ($filename) { return str_pad (strtoupper (dechex (crc32 (file_get_contents ($filename)))), 8, '0', STR_PAD_LEFT); } ?> bulk
A faster way I've found to return CRC values of larger files, is instead of using the file()/implode() method used below, is to us file_get_contents() (PHP 4 >= 4.3.0) which uses memory mapping techniques if supported by your OS to enhance performance. Here's my example function: <? // $file is the path to the file you want to check. function file_crc($file) { $file_string = file_get_contents($file); $crc = crc32($file_string); return sprintf("%u", $crc); } $file_to_crc = /home/path/to/file.jpg; echo file_crc($file_to_crc); // Outputs CRC value for given file. ?> I've found in testing this method is MUCH faster for larger binary files. waldomonster
<?php $data = 'dot'; echo dechex(crc32($data)); ?> Returns 59278a3 Witch is missing a leading zero. <?php $data = 'dot'; echo str_pad(dechex(crc32($data)), 8, '0', STR_PAD_LEFT); ?> Returns the correct string: 059278a3 |
Change Languageaddcslashes addslashes bin2hex chop chr chunk_split convert_cyr_string convert_uudecode convert_uuencode count_chars crc32 crypt echo explode fprintf get_html_translation_table hebrev hebrevc html_entity_decode htmlentities htmlspecialchars_decode htmlspecialchars implode join levenshtein localeconv ltrim md5_file md5 metaphone money_format nl_langinfo nl2br number_format ord parse_str printf quoted_printable_decode quotemeta rtrim setlocale sha1_file sha1 similar_text soundex sprintf sscanf str_getcsv str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split str_word_count strcasecmp strchr strcmp strcoll strcspn strip_tags stripcslashes stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk strpos strrchr strrev strripos strrpos strspn strstr strtok strtolower strtoupper strtr substr_compare substr_count substr_replace substr trim ucfirst ucwords vfprintf vprintf vsprintf wordwrap |