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.
À 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
Vous devez vous connecter pour publier un commentaire.
Si vous avez déjà un SHA1 somme, vous pouvez tout simplement faire:
sinon
Vérification de la taille de fichier trop, un peu d'empêcher une collision de hachage (ce qui est déjà très rare). Aussi à l'aide de MD5 parce que c'est beaucoup plus rapide que les algorithmes SHA (mais un peu moins unique).
Mise à jour:
C'est comment exactement comparer deux fichiers les uns contre les autres.
Je suis déjà vérifier les hachages de fichier (SHA-1). Le coin des cas, je suis à essayer de comprendre est de vérifier que tous les octets de match si SHA-1 hash correspondent et la taille du fichier est identique. Je sais que les modifications pour que cela se produise est très faible, mais le code nécessaire pour éviter de même que le faible changement n'est pas difficile à écrire.
J'ai ajouté le code pour ma réponse qui exactement compare les deux fichiers.
Il vous manque deux
fclose()
appels et le code serait mieux si vous retournez immédiatement après l'échec defilesize()
test. C'est une honte que PHP ne fournit pas cette fonctionnalité par défaut.Quelle serait la meilleure pratique comme pour 500 fichiers d'image avec une taille de 1 mo - 10 mo? SHA1, MD5 ou directement comparer? Ce que la performance?
OriginalL'auteur Cobra_Fast
Mise à jour
Si vous voulez vous assurer que les fichiers sont égaux, alors vous devriez d'abord vérifier la taille des fichiers et si elles correspondent alors juste diff du contenu du fichier. C'est beaucoup plus rapide que d'utiliser une fonction de hachage et sera certainement donner le résultat correct.
Il n'est pas nécessaire de charger la totalité du contenu d'un fichier dans la mémoire si vous hachage du contenu à l'aide de
md5_file()
ousha1_file()
ou d'une autre hash_function. Voici un exemple d'utilisation demd5
:De sortie:
Dans votre exemple, il serait:
Note en outre, lorsque vous utilisez une fonction de hachage, vous aurez toujours une situation où vous avez besoin de choisir entre la complexité d'une part, et la probabilité de collisions (ce qui signifie que deux messages différents pour produire le même hash) d'autre part.
vais donner un exemple....
merci, je ne savais pas que PHP de mise en œuvre était sain d'esprit assez pour ne pas lire tout le fichier en mémoire. Je n'ai pas besoin d'utiliser
shell_exec()
etsha1sum
plus à gérer de gros fichiers.Ouais ils sont souvent oubliés 🙂 .. Aussi jeter un oeil à d'autres peut-être plus rapide de fonctions de hachage. Mais ceux-ci doivent être appelées à l'aide de
shell_exec()
de nouveauJe ne prétends pas que
files are equal
en cas de hachage md5 correspond. Je dirais quefiles are probably equal
qui est le cas, j'ai déjà peut prétendre lors de SHA-1 hash correspondent.OriginalL'auteur hek2mgl
Utilisation de hachage Sha1, tout comme vous. Si elles sont égales, de comparer leurs hashs md5 et la taille aussi.
ENSUITE, si vous rencontrez un fichier qui correspond à tous les 3 chèques, mais n'est PAS égale - vous venez de trouver le saint graal 😀
OriginalL'auteur dognose
Lorsque vos fichiers sont gros et binaire, vous pouvez tester la qualité de quelques octets à partir de quelques décalages. Il devrait être beaucoup plus rapide que n'importe quelle fonction de hachage, surtout que la fonction renvoie le résultat par le premier caractère différent.
Cependant, cette méthode ne fonctionne pas pour les fichiers avec seulement quelques differend caractères. C'est le meilleur pour les grands archives, vidéos et ainsi de suite.
OriginalL'auteur sliwhas
Le morceau de code suivant vous aide à vérifier si les fichiers sont identiques ou non.
Je sais que la raison du vote négatif sur mon post pour que je puisse m'améliorer.
le code que j'ai posté est adapté pour le fichier de quelques octets.
La question a déjà dit "vu que je sais déjà que SHA-1 hash correspond pour les deux fichiers" donc c'est à peu près sûr hypothèse que je sais comment faire pour calculer le hachage SHA-1 (ou "somme de contrôle"). Je sais aussi que les fichiers pas être identiques malgré le fait que le hachage SHA-1 correspond à (voir stackoverflow.com/questions/2479348/...).
Est-ce la raison pour négatif de vote?
OriginalL'auteur SwR