crc32

(PHP 4 >= 4.0.1, PHP 5)

crc32文字列の crc32 多項式計算を行う

説明

int crc32 ( string $str )

str の 32 ビット長の CRC (cyclic redundancy checksum) チェックサムを生成します。 これは通常、送信したデータの整合性を検証するために使用します。

警告

PHP の整数型は符号付きで、多くの crc32 チェックサムは 32 ビットシステム上では負の整数になります。 しかし、64 ビット環境では crc32() の結果はすべて正の整数となります。

つまり、符号なしの crc32() チェックサムの文字列表記を 十進形式で取得するには、 sprintf() もしくは printf() の "%u" フォーマッタを使う必要があります。

チェックサムの十六進表記を取得するには、sprintf() あるいは printf() の "%x" フォーマッタを使うか、あるいは変換関数 dechex() を使います。これらはいずれも、 crc32() の結果を符号なし整数に変換することも行います。

64 ビット環境でも、返り値が大きくなると負の整数を返すことが考えられます。 その場合は十六進変換がうまくいかないので、負の整数については オフセット 0xFFFFFFFF######## を与えます。 十六進表現は最もよく使われる形式なので、この処理が壊れないようにしました。 32 ビット環境から 64 ビット環境に移したときに ほぼ 50% の確率で十進形式での比較が失敗してしまいますが、 それよりも十六進表記のほうを優先したのです。

今思えば、この関数が整数値を返すようにしたというのがまずい判断でした。 最初から、md5() のように十六進形式の文字列をを直接返すようにしておけばよかったのでしょう。

移植性を考慮した選択肢として、より汎用的な hash() を使う方法もあります。 hash("crc32b", $str)dechex(crc32($str)) と同じ文字列を返します。

パラメータ

str

データ。

返り値

str の crc32 チェックサムを整数値で返します。

例1 crc32 チェックサムの表示

この例は printf() 関数を用いた変換後のチェックサムの表示方法を示しています。

<?php
$checksum 
crc32("The quick brown fox jumped over the lazy dog.");
printf("%u\n"$checksum);
?>

参考

  • hash() - ハッシュ値 (メッセージダイジェスト) を生成する
  • md5() - 文字列のmd5ハッシュ値を計算する
  • sha1() - 文字列の sha1 ハッシュを計算する

add a note add a note

User Contributed Notes 22 notes

up
7
Bulk at bulksplace dot com
8 years ago
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:

<?php
// $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.
up
3
sukitsupaluk at hotmail dot com
2 years ago
small sample convert crc32 to character map

<?php

function khash($data) {
    static
$map="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
   
$hash=crc32($data)+0x100000000;
   
$str = "";
    do {
       
$str = $map[31+ ($hash % 31)] . $str;
       
$hash /= 31;
    } while(
$hash >= 1);    
    return
$str;
}
$test= array(null,TRUE,FALSE,0,"0",1,"1","2","3","ab","abc","abcd","abcde","abcdefoo");
$out = array();
foreach(
$test as $s)
{
   
$out[]=khash($s).": ". $s;
}
var_dump($out);

/*
output:
array
  0 => string 'zVvOYTv: ' (length=9)
  1 => string 'xKDKKL8: 1' (length=10)
  2 => string 'zVvOYTv: ' (length=9)
  3 => string 'zOKCQxh: 0' (length=10)
  4 => string 'zOKCQxh: 0' (length=10)
  5 => string 'xKDKKL8: 1' (length=10)
  6 => string 'xKDKKL8: 1' (length=10)
  7 => string 'AFSzIAO: 2' (length=10)
  8 => string 'BXGSvQJ: 3' (length=10)
  9 => string 'xZWOQSu: ab' (length=11)
  10 => string 'AVAwHOR: abc' (length=12)
  11 => string 'zKASNE1: abcd' (length=13)
  12 => string 'xLCTOV7: abcde' (length=14)
  13 => string 'zQLzKMt: abcdefoo' (length=17)

*/

?>
up
3
jian at theorchard dot com
4 years ago
This function returns an unsigned integer from a 64-bit Linux platform.  It does return the signed integer from other 32-bit platforms even a 64-bit Windows one.

The reason is because the two constants PHP_INT_SIZE and PHP_INT_MAX have different values on the 64-bit Linux platform.

I've created a work-around function to handle this situation.

<?php
function get_signed_int($in) {
   
$int_max = pow(2, 31)-1;
    if (
$in > $int_max){
       
$out = $in - $int_max * 2 - 2;
    }
    else {
       
$out = $in;
    }
    return
$out;
}
?>

Hope this helps.
up
5
dave at jufer dot info
6 years ago
This function returns the same int value on a 64 bit mc. like the crc32() function on a 32 bit mc.

<?php
function crcKw($num){
   
$crc = crc32($num);
    if(
$crc & 0x80000000){
       
$crc ^= 0xffffffff;
       
$crc += 1;
       
$crc = -$crc;
    }
    return
$crc;
}
?>
up
3
roberto at spadim dot com dot br
8 years ago
MODBUS RTU, CRC16,
input-> modbus rtu string
output -> 2bytes string, in correct modbus order

<?php
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));
}
?>
up
2
same
10 years ago
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);

?>
up
2
Ren
6 years ago
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)
up
1
chernyshevsky at hotmail dot com
3 years ago
The crc32_combine() function provided by petteri at qred dot fi has a bug that causes an infinite loop, a shift operation on a 32-bit signed int might never reach zero. Replacing the function gf2_matrix_times() with the following seems to fix it:

<?php
function gf2_matrix_times($mat, $vec)
{
   
$sum=0;
   
$i=0;

    while (
$vec) {
        if (
$vec & 1) {
           
$sum ^= $mat[$i];
        }
       
$vec = ($vec >> 1) & 0x7FFFFFFF;
       
$i++;      
    }
    return
$sum;
}
?>

Otherwise, it's probably the best solution if you can't use hash_file(). Using a 1meg read buffer, the function only takes twice as long to process a 300meg files than hash_file() in my test.
up
1
i at morfi dot ru
1 year ago
Implementation crc64() in php 64bit

<?php

/**
* @return array
*/
function crc64Table()
{
   
$crc64tab = [];

   
// ECMA polynomial
   
$poly64rev = (0xC96C5795 << 32) | 0xD7870F42;

   
// ISO polynomial
    // $poly64rev = (0xD8 << 56);

   
for ($i = 0; $i < 256; $i++)
    {
        for (
$part = $i, $bit = 0; $bit < 8; $bit++) {
            if (
$part & 1) {
               
$part = (($part >> 1) & ~(0x8 << 60)) ^ $poly64rev;
            } else {
               
$part = ($part >> 1) & ~(0x8 << 60);
            }
        }

      
$crc64tab[$i] = $part;
    }

    return
$crc64tab;
}

/**
* @param string $string
* @param string $format
* @return mixed
*
* Formats:
*  crc64('php'); // afe4e823e7cef190
*  crc64('php', '0x%x'); // 0xafe4e823e7cef190
*  crc64('php', '0x%X'); // 0xAFE4E823E7CEF190
*  crc64('php', '%d'); // -5772233581471534704 signed int
*  crc64('php', '%u'); // 12674510492238016912 unsigned int
*/
function crc64($string, $format = '%x')
{
    static
$crc64tab;

    if (
$crc64tab === null) {
       
$crc64tab = crc64Table();
    }

   
$crc = 0;

    for (
$i = 0; $i < strlen($string); $i++) {
       
$crc = $crc64tab[($crc ^ ord($string[$i])) & 0xff] ^ (($crc >> 8) & ~(0xff << 56));
    }

    return
sprintf($format, $crc);
}
up
1
Clifford dot ct at gmail dot com
1 year ago
The crc32() function can return a signed integer in certain environments.  Assuming that it will always return an unsigned integer is not portable.

Depending on your desired behavior, you should probably use sprintf() on the result or the generic hash() instead.  Also note that integer arithmetic operators do not have the precision to work correctly with the integer output.
up
1
arris at zsolttech dot com
2 years ago
not found anywhere crc64 based on http://bioinfadmin.cs.ucl.ac.uk/downloads/crc64/crc64.c .

(use gmp module)

<?php

/* OLDCRC */
define('POLY64REV', "d800000000000000");
define('INITIALCRC', "0000000000000000");
define('TABLELEN', 256);
/* NEWCRC */
// define('POLY64REV', "95AC9329AC4BC9B5");
// define('INITIALCRC', "FFFFFFFFFFFFFFFF");

if(function_exists('gmp_init')){
        class
CRC64{

                private static
$CRCTable = array();

                public static function
encode($seq){

                       
$crc = gmp_init(INITIALCRC, 16);
                       
$init = FALSE;
                       
$poly64rev = gmp_init(POLY64REV, 16);

                        if (!
$init)
                        {
                               
$init = TRUE;
                                for (
$i = 0; $i < TABLELEN; $i++)
                                {
                                       
$part = gmp_init($i, 10);
                                        for (
$j = 0; $j < 8; $j++)
                                        {
                                                if (
gmp_strval(gmp_and($part, "0x1")) != "0"){
                                                       
// if (gmp_testbit($part, 1)){ /* PHP 5 >= 5.3.0, untested */
                                                       
$part = gmp_xor(gmp_div_q($part, "2"), $poly64rev);
                                                } else {
                                                       
$part = gmp_div_q($part, "2");
                                                }
                                        }
                                       
self::$CRCTable[$i] = $part;
                                }
                        }

                        for(
$k = 0; $k < strlen($seq); $k++){
                               
$tmp_gmp_val = gmp_init(ord($seq[$k]), 10);
                               
$tableindex = gmp_xor(gmp_and($crc, "0xff"), $tmp_gmp_val);
                               
$crc = gmp_div_q($crc, "256");
                               
$crc = gmp_xor($crc, self::$CRCTable[gmp_strval($tableindex, 10)]);
                        }

                       
$res = gmp_strval($crc, 16);

                        return
$res;
                }
        }
} else {
        die(
"Please install php-gmp package!!!");
}
?>
up
1
slimshady451
7 years ago
I see a lot of function for crc32_file, but for php version >= 5.1.2 don't forget you can use this :

<?php
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.
up
1
mail at tristansmis dot nl
7 years ago
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))
    */

?>
up
2
JS at JavsSys dot Org
1 year ago
The khash() function by sukitsupaluk has two problems, it does not use all 62 characters from the $map set and when corrected it then produces different results on 64-bit compared to 32-bit PHP systems.

Here is my modified version :

<?php

/**
* Small sample convert crc32 to character map
* Based upon http://www.php.net/manual/en/function.crc32.php#105703
* (Modified to now use all characters from $map)
* (Modified to be 32-bit PHP safe)
*/
function khash($data)
{
    static
$map = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
   
$hash = bcadd(sprintf('%u',crc32($data)) , 0x100000000);
   
$str = "";
    do
    {
       
$str = $map[bcmod($hash, 62) ] . $str;
       
$hash = bcdiv($hash, 62);
    }
    while (
$hash >= 1);
    return
$str;
}
//-----------------------------------------------------------------------------------
$test = array(null, true, false, 0, "0", 1, "1", "2", "3", "ab", "abc", "abcd",
   
"abcde", "abcdefoo", "248840027", "1365848013", // time()
   
"9223372035488927794", // PHP_INT_MAX-time()
   
"901131979", // mt_rand()
   
"Sat, 13 Apr 2013 10:13:33 +0000" // gmdate('r')
);
$out = array();
foreach (
$test as $s)
{
   
$out[] = khash($s) . ": " . $s;
}
print
"<h3>khash() -- maps a crc32 result into a (62-character) result</h3>";
print
'<pre>';
var_dump($out);
print
"\n\n\$GLOBALS['raw_crc32']:\n";
var_dump($GLOBALS['raw_crc32']);
print
'</pre><hr>';
flush();
$pefile = __FILE__;
print
"<h3>$pefile</h3>";
ob_end_flush();
flush();
highlight_file($pefile);
print
"<hr>";
//-----------------------------------------------------------------------------------
/* CURRENT output
array(19) {
  [0]=>
  string(8) "4GFfc4: "
  [1]=>
  string(9) "76nO4L: 1"
  [2]=>
  string(8) "4GFfc4: "
  [3]=>
  string(9) "9aGcIp: 0"
  [4]=>
  string(9) "9aGcIp: 0"
  [5]=>
  string(9) "76nO4L: 1"
  [6]=>
  string(9) "76nO4L: 1"
  [7]=>
  string(9) "5b8iNn: 2"
  [8]=>
  string(9) "6HmfFN: 3"
  [9]=>
  string(10) "7ADPD7: ab"
  [10]=>
  string(11) "5F0aUq: abc"
  [11]=>
  string(12) "92kWw9: abcd"
  [12]=>
  string(13) "78hcpf: abcde"
  [13]=>
  string(16) "9eBVPB: abcdefoo"
  [14]=>
  string(17) "5TjOuZ: 248840027"
  [15]=>
  string(18) "5eNliI: 1365848013"
  [16]=>
  string(27) "4Q00e5: 9223372035488927794"
  [17]=>
  string(17) "6DUX8V: 901131979"
  [18]=>
  string(39) "5i2aOW: Sat, 13 Apr 2013 10:13:33 +0000"
}
*/
//-----------------------------------------------------------------------------------

?>
up
1
arachnid at notdot dot net
10 years ago
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.
up
1
quix at free dot fr
11 years ago
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;
    }
?>
up
0
D
1 year ago
<?php
$i
= crc32('weak_hash');
   
if(
$i < 0 ) // if hash is negative
{
       
$i*=-1; // do some basic math
}

echo
$i;

/*
OUTPUTS 275953381
*/
?>
up
0
alban dot lopez+php [ at ] gmail dot com
2 years ago
I made this code to verify Transmition with Vantage Pro2 ( weather station ) based on CRC16-CCITT standard.

<?php
// CRC16-CCITT validator
$crc_table = array(
   
0x00x10210x20420x30630x40840x50a50x60c60x70e7,
       
0x81080x91290xa14a0xb16b0xc18c0xd1ad0xe1ce0xf1ef,
       
0x12310x2100x32730x22520x52b50x42940x72f70x62d6,
       
0x93390x83180xb37b0xa35a0xd3bd0xc39c0xf3ff0xe3de,
       
0x24620x34430x4200x14010x64e60x74c70x44a40x5485,
       
0xa56a0xb54b0x85280x95090xe5ee0xf5cf0xc5ac0xd58d,
       
0x36530x26720x16110x6300x76d70x66f60x56950x46b4,
       
0xb75b0xa77a0x97190x87380xf7df0xe7fe0xd79d0xc7bc,
       
0x48c40x58e50x68860x78a70x8400x18610x28020x3823,
       
0xc9cc0xd9ed0xe98e0xf9af0x89480x99690xa90a0xb92b,
       
0x5af50x4ad40x7ab70x6a960x1a710xa500x3a330x2a12,
       
0xdbfd0xcbdc0xfbbf0xeb9e0x9b790x8b580xbb3b0xab1a,
       
0x6ca60x7c870x4ce40x5cc50x2c220x3c030xc600x1c41,
       
0xedae0xfd8f0xcdec0xddcd0xad2a0xbd0b0x8d680x9d49,
       
0x7e970x6eb60x5ed50x4ef40x3e130x2e320x1e510xe70,
       
0xff9f0xefbe0xdfdd0xcffc0xbf1b0xaf3a0x9f590x8f78,
       
0x91880x81a90xb1ca0xa1eb0xd10c0xc12d0xf14e0xe16f,
       
0x10800xa10x30c20x20e30x50040x40250x70460x6067,
       
0x83b90x93980xa3fb0xb3da0xc33d0xd31c0xe37f0xf35e,
       
0x2b10x12900x22f30x32d20x42350x52140x62770x7256,
       
0xb5ea0xa5cb0x95a80x85890xf56e0xe54f0xd52c0xc50d,
       
0x34e20x24c30x14a00x4810x74660x64470x54240x4405,
       
0xa7db0xb7fa0x87990x97b80xe75f0xf77e0xc71d0xd73c,
       
0x26d30x36f20x6910x16b00x66570x76760x46150x5634,
       
0xd94c0xc96d0xf90e0xe92f0x99c80x89e90xb98a0xa9ab,
       
0x58440x48650x78060x68270x18c00x8e10x38820x28a3,
       
0xcb7d0xdb5c0xeb3f0xfb1e0x8bf90x9bd80xabbb0xbb9a,
       
0x4a750x5a540x6a370x7a160xaf10x1ad00x2ab30x3a92,
       
0xfd2e0xed0f0xdd6c0xcd4d0xbdaa0xad8b0x9de80x8dc9,
       
0x7c260x6c070x5c640x4c450x3ca20x2c830x1ce00xcc1,
       
0xef1f0xff3e0xcf5d0xdf7c0xaf9b0xbfba0x8fd90x9ff8,
       
0x6e170x7e360x4e550x5e740x2e930x3eb20xed10x1ef0);

   
$test = chr(0xC6).chr(0xCE).chr(0xA2).chr(0x03); // CRC16-CCITT = 0xE2B4
   
genCRC ($test);
      
function
genCRC (&$ptr)
{
   
$crc = 0x0000;
   
$crc_table = $GLOBALS['crc_table'];
    for (
$i = 0; $i < strlen($ptr); $i++)
       
$crc $crc_table[(($crc>>8) ^ ord($ptr[$i]))] ^ (($crc<<8) & 0x00FFFF);
    return
$crc;
}
?>
up
0
waldomonster at netjukebox dot demon dot nl
10 years ago
<?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
up
0
spectrumizer at cycos dot net
11 years ago
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
up
-1
gabri dot ns at gmail dot com
3 years ago
if you are looking for a fast function to hash a file, take a look at
http://www.php.net/manual/en/function.hash-file.php
this is crc32 file checker based on a CRC32 guide
it have performance at ~ 625 KB/s on my 2.2GHz Turion
far slower than hash_file('crc32b','filename.ext')
<?php
function crc32_file ($filename)
{
  
$f = @fopen($filename,'rb');
   if (!
$f) return false;
  
   static
$CRC32Table, $Reflect8Table;
   if (!isset(
$CRC32Table))
   {
     
$Polynomial = 0x04c11db7;
     
$topBit = 1 << 31;
      
      for(
$i = 0; $i < 256; $i++)
      {
        
$remainder = $i << 24;
         for (
$j = 0; $j < 8; $j++)
         {
            if (
$remainder & $topBit)
              
$remainder = ($remainder << 1) ^ $Polynomial;
            else
$remainder = $remainder << 1;
         }
        
        
$CRC32Table[$i] = $remainder;
        
         if (isset(
$Reflect8Table[$i])) continue;
        
$str = str_pad(decbin($i), 8, '0', STR_PAD_LEFT);
        
$num = bindec(strrev($str));
        
$Reflect8Table[$i] = $num;
        
$Reflect8Table[$num] = $i;
      }
   }
  
  
$remainder = 0xffffffff;
   while (
$data = fread($f,1024))
   {
     
$len = strlen($data);
      for (
$i = 0; $i < $len; $i++)
      {
        
$byte = $Reflect8Table[ord($data[$i])];
        
$index = (($remainder >> 24) & 0xff) ^ $byte;
        
$crc = $CRC32Table[$index];
        
$remainder = ($remainder << 8) ^ $crc;
      }
   }
  
  
$str = decbin($remainder);
  
$str = str_pad($str, 32, '0', STR_PAD_LEFT);
  
$remainder = bindec(strrev($str));
   return
$remainder ^ 0xffffffff;
}
?>

<?php
$a
= microtime();
echo
dechex(crc32_file('filename.ext'))."\n";
$b = microtime();
echo
array_sum(explode(' ',$b)) - array_sum(explode(' ',$a))."\n";
?>
Output:
ec7369fe
2.384134054184 (or similiar)
up
-1
berna (at) gensis (dot) com (dot) br
4 years ago
For those who want a more familiar return value for the function:

<?php
function strcrc32($text) {
 
$crc = crc32($text);
  if (
$crc & 0x80000000) {
   
$crc ^= 0xffffffff;
   
$crc += 1;
   
$crc = -$crc;
  }
  return
$crc;
}
?>

And to show the result in Hex string:

<?php
function int32_to_hex($value) {
 
$value &= 0xffffffff;
  return
str_pad(strtoupper(dechex($value)), 8, "0", STR_PAD_LEFT);
}
?>
To Top