Vérifier que les deux fichiers sont identiques en utilisant uniquement du PHP?

TL;DR: j'ai un système CMS qui stocke les pièces jointes (opaque fichiers) à l'aide de l'algorithme SHA-1, le contenu du fichier le nom du fichier. Comment faire pour vérifier si le fichier téléchargé correspond vraiment un dans le stockage, étant donné que je sais déjà que SHA-1 hash correspond pour les deux fichiers? J'aimerais avoir la haute performance.

Version longue:

Lorsqu'un utilisateur télécharge un nouveau fichier sur le système, je calcule un hash SHA-1 du fichier uploadé le contenu, puis de vérifier si un fichier avec le même hash existe déjà dans le backend de stockage. PHP met le fichier téléchargé dans /tmp avant mon code à exécuter, puis-je exécuter sha1sum contre le fichier téléchargé pour obtenir SHA-1 hash du contenu du fichier. J'ai ensuite calculer la distribution de l'aide de hachage SHA-1 et de décider de stockage sous-répertoire de montage NFS d'une hiérarchie de répertoires. (Par exemple, si le hachage SHA-1 pour un fichier de contenu est 37aefc1e145992f2cc16fabadcfe23eede5fb094 la permanente de nom de fichier est /nfs/data/files/37/ae/fc1e145992f2cc16fabadcfe23eede5fb094.) En plus de sauver les contenus actuels du fichier, je INSERT une nouvelle ligne dans une base de données SQL pour l'utilisateur soumis méta-données (par exemple,Content-Type, nom de fichier original, datestamp, etc).

L'angle cas, je suis actuellement de déterminer qui est le cas lorsqu'un nouveau fichier téléchargé a hachage SHA-1 qui correspond à de hachage existantes dans le backend de stockage. Je sais que les modifications pour que cela se produise par accident sont astronomiquement faible, mais j'aimerais en être sûr. (Pour les fins de cas, voir https://shattered.io/)

Donné deux noms $file_a et $file_b, comment vérifier rapidement si les deux fichiers ont le même contenu? Supposons que les fichiers sont trop gros pour être chargé en mémoire. Avec Python, j'utilise filecmp.cmp() mais PHP ne semble pas avoir quelque chose de semblable. Je sais que cela peut être fait avec fread() et l'abandon si un non-appariement de l'octet est trouvé, mais je préfère ne pas écrire ce code.

Êtes-vous essayer de se couvrir contre les collisions de hachage?
À l'aide de hachage est une bonne idée. Comme vous l'avez mentionné, la probabilité de collision est astronomiquement faible de sorte que vous pouvez être sûr que dans le cas le plus courant, qu'il sera ok. Si non, laissez - nous savoir votre cas avec le contenu de ces fichiers :p
git utilise sha1 donc je pense que vous r d'un coffre-fort assez pour utiliser sha1 🙂
J'essaie d'éviter, peut-être de perdre le contenu du fichier en raison d'une collision de hachage. Et oui, si jamais je vois une collision, je vais garder les deux fichiers. Je serais prêt à parier que dans ce cas, je trouve que mon stockage permanent a bitrotted. (Les modifications d'obtenir un random bit d'erreur sur n'importe quel périphérique de stockage semble beaucoup plus élevé que pour la recherche de SHA-1 de collision; j'aimerais avoir une nouvelle copie du fichier endommagé dans ce cas, encore.)
git aussi ne compare-par-octets de test avant de faire confiance que le fichier est identique juste parce que SHA-1 hash correspond, autant que je sache.

OriginalL'auteur Mikko Rantalainen | 2013-09-17