crc32

(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)

crc32Calcula polinômio crc32 de uma string

Descrição

crc32(string $string): int

Gera a soma de verificação de redundância cíclica de 32-bits de comprimento da string. É usado geralmente para validar a integridade de um dado sendo transferido.

Aviso

Pelo fato do tipo inteiro do PHP ser com sinal, muitas somas de verificação crc32 resultarão em inteiros negativos em plataformas de 32 bits. Em instalações de 64 bits todos os resultados de crc32() serão inteiros positivos.

Por isso, é necessário usar o formatador "%u" da função sprintf() ou printf() para obter a representação em string da soma de verificação sem sinal da função crc32() em formato decimal.

Para uma representação hexadecimal da soma de verificação, pode-se usar tanto o formatador "%x" de sprintf() ou printf() quanto as funções de conversão dechex(), ambas destas soluções também tomam o cuidado de converter o resultado de crc32() para um inteiro sem sinal.

Foi considerado que instalações de 64 bits também retornassem inteiros negativos para valores mais altos de resultados, porém isto iria quebrar a conversão para hexadecimal, já que os negativos teriam um deslocamento extra de 0xFFFFFFFF######## neste caso. Como a representação hexadecimal parece ser o uso de caso mais comum, decidiu-se não quebrar esta conversão mesmo que ela quebre comparações diretas em decimal em aproximadamente 50% dos casos ao mover de 32 para 64 bits.

Em retrospecto, fazer com que a função retornasse um inteiro talvez não tenha sido a melhor ideia, e retornar uma representação hexadecimal em string diretamente (como, por exemplo, a função md5() faz) poderia ter sido um plano melhor para se começar.

Para uma solução mais portável, pode-se considerar a função genérica hash(). hash("crc32b", $str) retornará a mesma string que str_pad(dechex(crc32($str)), 8, '0', STR_PAD_LEFT).

Parâmetros

string

Os dados.

Valor Retornado

Retorna a soma de verificação crc32 da string como um inteiro.

Exemplos

Exemplo #1 Mostrando uma soma de verificação crc32

Este exemplo mostra como exibir uma soma de verificação convertida com a função printf():

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

Veja Também

  • hash() - Generate a hash value (message digest)
  • md5() - Calculate the md5 hash of a string
  • sha1() - Calculate the sha1 hash of a string

add a note add a note

User Contributed Notes 23 notes

up
23
jian at theorchard dot com
14 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
9
i at morfi dot ru
11 years 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
7
JS at JavsSys dot Org
11 years 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
8
Bulk at bulksplace dot com
19 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
6
slimshady451
17 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
5
same
20 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
4
dave at jufer dot info
17 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
2
Clifford dot ct at gmail dot com
12 years 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
2
alban dot lopez+php [ at ] gmail dot com
13 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
1
arris at zsolttech dot com
13 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
quix at free dot fr
21 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
1
spectrumizer at cycos dot net
21 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
Ren
17 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
arachnid at notdot dot net
20 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
sukitsupaluk at hotmail dot com
13 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
2
roberto at spadim dot com dot br
18 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
0
chernyshevsky at hotmail dot com
14 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
0
berna (at) gensis (dot) com (dot) br
15 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);
}
?>
up
-1
mail at tristansmis dot nl
17 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
-1
toggio at writeme dot com
8 years ago
A faster implementation of modbus CRC16

function crc16($data)
{
   $crc = 0xFFFF;
   for ($i = 0; $i < strlen($data); $i++)
   {
     $crc ^=ord($data[$i]);
    
        for ($j = 8; $j !=0; $j--)
        {
            if (($crc & 0x0001) !=0)
            {
                $crc >>= 1;
                $crc ^= 0xA001;
            }
            else
                $crc >>= 1;
        }
    }   
   return $crc;
}
up
-3
gabri dot ns at gmail dot com
14 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
-3
dotg at mail dot ru
7 years ago
crc32() on php 32bit and 64 bit not equal in some values

i use abs for result in positive for 32 bit

not equal
<?=abs(crc32(1));?>
64 bit
2212294583
32 bit
2082672713

equal
<?=abs(crc32(3));?>
64 bit
1842515611
32 bit
1842515611
up
-13
waldomonster at netjukebox dot demon dot nl
20 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
To Top