Truc du jour: CRC32 compatible PHP

Extrait d'un diagramme d'algorithme CRC
Crédit image: Zhu Han

PHP inclut des fonctions crc32() et hash("crc32"), mais quel est donc leur équivalent exact en Go ?

La question

Durant le portage (en réalité, la réécriture) d’une vieille bibliothèque PHP en Go, j’ai eu besoin de calculer une somme de contrôle CRC (cyclic redundancy check). Dans du PHP traditionnel, le standard de fait pour cela est bien établi depuis PHP 4: utiliser la fonction crc32 de la bibliothèque strings, en faisant attention au bit de signe; ou bien, de façon plus moderne mais compatible, utiliser la fonction hash de la bibliothèque hash, comme dans cet exemple:

1
2
3
4
<?php
    $hash = gmp_init(hash("crc32b", $url), 16);
    $hex = gmp_strval($hash);
?>

Pas de souci en vue: la bibliothèque standard Go inclut un paquet hash/crc32, donc ce devrait être une utilisation directe, pas vrai ?

Problème, à la différence de PHP qui se contente de les lister ses algorithmes sur la page de la fonction hash_algos, la bibliothèque Go va un peu plus loin que celle de PHP (surprise, surprise), et documente les siens, comme ceci:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
const (
        // IEEE is by far and away the most common CRC-32 polynomial.
        // Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, ...
        IEEE = 0xedb88320

        // Castagnoli's polynomial, used in iSCSI.
        // Has better error detection characteristics than IEEE.
        // https://dx.doi.org/10.1109/26.231911
        Castagnoli = 0x82f63b78

        // Koopman's polynomial.
        // Also has better error detection characteristics than IEEE.
        // https://dx.doi.org/10.1109/DSN.2002.1028931
        Koopman = 0xeb31d82e
)

Problème, PHP n’a aucune référence aux polynômes IEEE, de Castagnoli, ni de Koopman, listant simplement crc et crc32 en guise de détails.

La réponse

Un rapide contrôle des valeurs de sommes permet d’identifier les équivalences:

LangageAlgorithmeSomme de Hello world
PHPcrc3275883905
PHPcrc32b8bd69e52
Gocrc32.Castagnoli72b51f78
Gocrc32.IEEE8bd69e52
Gocrc32.Koopmanb1bcb065

Petit contrôle avec d’autres jeux de valeurs pour s’assurer que ce n’est pas un hasard, et le résultat est confirmé:

  • le code PHP hash(‘crc32b’, $value)
  • est équivalent au code Go crc32.ChecksumIEEE(value).