如何在PHP中实现zlib的crc32_combine()函数?

时间:2015-04-27 10:01:27

标签: php zlib crc32

我正在尝试在PHP中创建crc32_combine函数,但我不完全理解它是source in zlib library

我需要这个:

<?php
$crc_a = crc32('a');
$crc_aa = crc32('aa');
$crc_aa === crc32_combine($crc_a, $crc_a, 1); // should result in TRUE

我有什么:

<?php
define('GF2_DIM', 32);

function gf2_matrix_times($mat, $vec) {
    $sum = 0;
    while ($vec) {
        if ($vec & 1) {
            $sum ^= $mat;
        }
        $vec >>= 1;
        $mat++;
    }
    return $sum;
}

function gf2_matrix_square(&$square, &$mat) {
    for ($n = 0; $n < GF2_DIM; $n++) {
        $square[$n] = gf2_matrix_times($mat, $mat[$n]);
    }
}

function crc32_combine($crc1, $crc2, $len2) {
    $even = array_fill(0, GF2_DIM, 0);
    $odd = array_fill(0, GF2_DIM, 0);

    /* degenerate case (also disallow negative lengths) */
    if ($len2 <= 0) {
        return $crc1;
    }

    /* put operator for one zero bit in odd */
    $odd[0] = 0xedb88320;   /* CRC-32 polynomial */
    $row = 1;
    for ($n = 1; $n < GF2_DIM; $n++) {
        $odd[$n] = $row;
        $row <<= 1;
    }

    /* put operator for two zero bits in even */
    gf2_matrix_square($even, $odd);

    /* put operator for four zero bits in odd */
    gf2_matrix_square($odd, $even);

    /* apply len2 zeros to crc1 (first square will put the operator for one
     zero byte, eight zero bits, in 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;

        /* if no more bits set, then done */
    } while ($len2 != 0);

    /* return combined crc */
    $crc1 ^= $crc2;
    return $crc1;
}

我认为gf2_matrix_times函数是错误的,因为$ mat是一个数组,但我不知道如何重写它。

1 个答案:

答案 0 :(得分:3)

我的代码正常运行:

<?php
define('GF2_DIM', 32);

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

function gf2_matrix_square(&$square, &$mat) {
    for ($n = 0; $n < GF2_DIM; $n++) {
        $square[$n] = gf2_matrix_times($mat, $mat[$n]);
    }
}

function crc32_combine($crc1, $crc2, $len2) {
    $even = array_fill(0, GF2_DIM, 0);
    $odd = array_fill(0, GF2_DIM, 0);

    /* degenerate case (also disallow negative lengths) */
    if ($len2 <= 0) {
        return $crc1;
    }

    /* put operator for one zero bit in odd */
    $odd[0] = 0xedb88320;   /* CRC-32 polynomial */
    $row = 1;
    for ($n = 1; $n < GF2_DIM; $n++) {
        $odd[$n] = $row;
        $row <<= 1;
    }

    /* put operator for two zero bits in even */
    gf2_matrix_square($even, $odd);

    /* put operator for four zero bits in odd */
    gf2_matrix_square($odd, $even);

    /* apply len2 zeros to crc1 (first square will put the operator for one
     zero byte, eight zero bits, in 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;

        /* if no more bits set, then done */
    } while ($len2 != 0);

    /* return combined crc */
    $crc1 ^= $crc2;
    return $crc1;
}