/lib/ezc/Archive/src/utils/checksums.php
https://bitbucket.org/ericsagnes/ezpublish-multisite · PHP · 228 lines · 92 code · 26 blank · 110 comment · 15 complexity · 4798d2836083c402f291fa06bd46d226 MD5 · raw file
- <?php
- /**
- * File containing the ezcArchiveChecksums class.
- *
- * @package Archive
- * @version //autogentag//
- * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
- * @license http://ez.no/licenses/new_bsd New BSD License
- * @access private
- */
- /**
- * The ezcArchiveChecksums is a collection of checksum algorithms. The
- * total-byte-value checksum and CRC32 checksum are currently available.
- *
- * For each different checksum are two methods available:
- * - Calculate the checksum from a string.
- * - Calculate the checksum from a file.
- *
- * The latter will consume less memory since a part of the file is read in
- * memory at the time, and will be freed after use. The consequence might be
- * that the checksum from a string is a bit faster.
- *
- * @package Archive
- * @version //autogentag//
- * @access private
- */
- class ezcArchiveChecksums
- {
- /**
- * The CRC-32 lookup table.
- *
- * @var array(int)
- */
- private static $crc32Table = false;
- /**
- * Calculates the total-byte-value checksum from a string.
- *
- * Returns the total ASCII value from all characters in the data string.
- * Example 1: For example:
- *
- * <code>
- * $crc = ezcArchiveChecksums::getTotalByteValueFromFile( "abc" );
- * // $crc contains the value: 141 + 142 + 143 = 426
- * </code>
- *
- * @param string $data Character string.
- * @return int The total byte value.
- *
- * @see getTotalByteValueFromFile()
- */
- public static function getTotalByteValueFromString( $data )
- {
- $total = 0;
- $length = strlen( $data );
- for ( $i = 0; $i < $length; $i++ )
- {
- $total += ord( $data[$i] );
- }
- return $total;
- }
- /**
- * Calculates the total-byte-value checksum from a file.
- *
- * Returns the total ASCII value from all characters in the data string.
- * For example:
- *
- * <code>
- * $crc = ezcArchiveChecksums::getTotalByteValueFromFile( "abc" );
- * // $crc contains the value: 141 + 142 + 143 = 426
- * </code>
- *
- * @param string $fileName The file to use
- * @return int Value which contains the total byte value.
- */
- public static function getTotalByteValueFromFile( $fileName )
- {
- if ( ( $fp = fopen( $fileName, 'rb' ) ) === false )
- {
- return false;
- }
- // Perform the algorithm on each character in file
- $total = 0;
- while ( true )
- {
- $i = fread( $fp, 1 );
- if ( strlen( $i ) == 0 )
- {
- break;
- }
- $total += ord( $i );
- }
- fclose( $fp );
- return $total;
- }
- /**
- * Calculates the (official) CRC-32 polynomial from a $data string as input.
- *
- * @param string $data
- * @return int The calculated CRC-32.
- */
- public static function getCrc32FromString( $data )
- {
- return crc32( $data );
- }
- /**
- * Calculates the (official) CRC-32 polynomial from a file.
- *
- * This method is taken from the PHP user comments
- * (http://no.php.net/manual/en/function.crc32.php).
- *
- * @param string $fileName Absolute or relative path to the file.
- * @return int The calculated CRC-32.
- */
- public static function getCrc32FromFile( $fileName )
- {
- if ( self::$crc32Table === false )
- {
- self::crc32InitTable();
- }
- // 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;
- // Added for issue #13517: Not possible to add directories to an archive on Windows
- if ( is_dir( $fileName ) )
- {
- return false;
- }
- if ( ( $fp = fopen( $fileName ,'rb' ) ) === false )
- {
- return false;
- }
- // Perform the algorithm on each character in file
- while ( true )
- {
- $i = fread( $fp, 1 );
- if ( strlen( $i ) == 0 )
- {
- break;
- }
- $crc = ( ( $crc >> 8 ) & 0x00ffffff ) ^ self::$crc32Table[( $crc & 0xFF ) ^ ord( $i )];
- }
- fclose( $fp );
- // Exclusive OR the result with the beginning value.
- return $crc ^ 0xffffffff;
- }
- /**
- * Initializes the CRC-32 table.
- *
- * Builds the lookup table array. This is the official polynomial used by
- * CRC-32 in PKZip, WinZip and Ethernet.
- *
- * This method is taken from the PHP user comments
- * (http://no.php.net/manual/en/function.crc32.php).
- */
- protected static function crc32InitTable()
- {
- // 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 )
- {
- self::$crc32Table[$i] = ( self::crc32Reflect( $i, 8 ) << 24 );
- for ( $j = 0; $j < 8; ++$j )
- {
- self::$crc32Table[$i] = ( ( self::$crc32Table[$i] << 1 ) ^ ( ( self::$crc32Table[$i] & ( 1 << 31 ) ) ? $polynomial : 0 ) );
- }
- self::$crc32Table[$i] = self::crc32Reflect( self::$crc32Table[$i], 32 );
- }
- }
- /**
- * Reflects CRC bits in the lookup table
- *
- * This method is taken from the PHP user comments
- * (http://no.php.net/manual/en/function.crc32.php).
- *
- * @param int $ref
- * @param int $ch
- * @return int
- */
- protected static function crc32Reflect( $ref, $ch )
- {
- $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;
- }
- }
- ?>