2009-01-22 8 views
29

J'essaie de faire correspondre SHA1 en texte générique avec une expression régulière.Un Regex pour correspondre à un SHA1

Idéalement, je veux éviter les mots correspondants.

Il est sûr de dire que les SHA1 complets ont un motif distinctif (ils sont longs et d'une longueur constante) - donc je peux les faire correspondre de manière fiable - mais qu'en est-il des abréviations SHA1? Puis-je m'appuyer sur la présence de chiffres?

En regardant les SHA1 dans mon journal de validation - les numéros apparaissent toujours dans les 3 premiers caractères. Mais est-ce trop court? Combien de caractères de SHA1 dois-je prendre en compte avant de pouvoir supposer qu'un numéro serait apparu?

Cela ne doit pas nécessairement être précis à 100% - j'ai juste besoin de faire correspondre un abrégé SHA1 99% du temps.

+0

Comment les SHA1 sont-ils représentés? Décimal? Hex? Base 64? Le hachage est juste un très grand nombre, et techniquement, chaque personnage est un chiffre, sinon un «nombre» dans le sens normal. Je pense que quelques exemples seraient vraiment bons ici. –

+0

Ou peut-être que je suis juste en train de penser aux choses comme d'habitude. –

+0

FWIW - presque une décennie plus tard - tous les hachages dans mon «git log» ont maintenant une lettre alphabétique dans les trois premiers caractères – galois

Répondre

55

Vous pouvez considérer que les hachages SHA1 sont complètement aléatoires, ce qui réduit les probabilités. La probabilité qu'un chiffre donné ne soit pas un nombre est de 6/16 ou 0,375. La probabilité que trois chiffres SHA1 ne soient pas tous des nombres est 0.375 ** 3, ou 0.0527 (ish 5%). À six chiffres, cela réduit encore à 0,00278 (0,2%). À cinq chiffres, la probabilité que toutes les lettres soient inférieures à 1% (vous avez dit que vous vouliez correspondre à 99% du temps).

Il est facile de concevoir une expression régulière qui correspond toujours des valeurs SHA1:

\b[0-9a-f]{5,40}\b 

Cependant, cela peut également correspondre parfaitement bien cinq mots de lettres, comme « ajoutée » ou « disparu ». Dans mon fichier /usr/share/dict/words, il y a plusieurs mots de six lettres qui correspondent: «accède», «perlé», «literie», «décennie», «défigurer», «s'effacer» et «façade» sont les plus probables. À sept lettres, il n'y a que "deedeed" qui est peu susceptible d'apparaître en prose. Tout dépend du nombre de faux positifs que vous pouvez tolérer, et des vrais mots que vous allez rencontrer.

+6

Pourquoi le {5,40}, et non {40}? –

+1

@sheepsimulator: Vraisemblablement parce qu'il est courant d'abréger les hachages - bien que la longueur d'abréviation par défaut dans la sortie git soit 7, vous pouvez donc aller en toute sécurité à '{7,40}' et avoir beaucoup moins de faux positifs. @Greg Hewgill: mes mots/usr/share/dict contiennent aussi "acceded", "defaced", "effaced", et "facaded" - et les trois premiers sont communs, au moins en ce qui concerne deedeed! – Cascabel

+0

@Jefromi: bizarre, mon fichier 'words' contient" undefaced "mais pas" defaced "! Sur OS X et FreeBSD, aussi. –

28

Qu'essayez-vous exactement de faire? Vous ne devriez pas avoir besoin d'analyser quoi que ce soit avec des heuristiques - vous pouvez toujours demander exactement les données dont vous avez besoin.

Si vous voulez correspondre à une pleine représentation hexagonale d'une somme SHA1, essayez:

/\b([a-f0-9]{40})\b/ 

C'est un mot composé de 40 caractères qui sont soit des chiffres ou des lettres a à f.

Si vous n'avez que quelques caractères et que vous ne savez pas où ils se trouvent, vous n'avez pas vraiment de chance. Est-ce que "e78fd98" est un ID de validation abrégé? Peut-être, mais qu'en est-il de "1234567"? Est-ce un ID de validation? Un numéro de ticket de problème? Un nombre qui fait échouer un test?

Sans contexte, vous ne pouvez pas vraiment savoir ce que les données signifient.

Pour répondre à votre question directe, SHA1 ne possède aucune propriété qui ferait les trois premiers chiffres (sous forme hexadécimale). Vous êtes juste chanceux, ou peut-être malchanceux, selon la façon dont vous le regardez.

+2

C'est ce que vous voulez, exactement 40 caractères de chiffres hexadécimaux vont toujours correspondre plutôt que la réponse acceptée actuellement qui ne peut pas toujours fonctionner. – Otto

4

Je vais supposer que vous voulez faire correspondre à la représentation hexadécimale imprimée d'un SHA1, et non pas aux 20 octets bruts équivalents. En outre, je vais supposer que les SHA1 en question utilisent uniquement des lettres minuscules pour représenter les chiffres hexadécimaux. Vous devrez ajuster l'expression régulière si vos besoins diffèrent.

grep -o -E -e "[0-9a-f]{40}" 

Correspondra à un tel SHA1. Vous devrez traduire l'expression régulière ci-dessus du dialecte d'egrep en n'importe quel outil que vous utilisez. Puisque le match doit avoir exactement 40 caractères, je ne pense pas que vous risquez de faire correspondre accidentellement des mots. Je ne connais pas de mots de 40 caractères composés uniquement des lettres a à f.

modifier:

Mieux encore: utiliser A Regex to match a SHA1 comme sa solution comprend la vérification des limites de mots aux deux extrémités. J'ai négligé cela ci-dessus.

2

Si vous avez accès au dépôt, vous pouvez utiliser git cat-file -e pour vérifier qu'il représente bien un objet dans le repo. C'est très rapide aussi. Si vous souhaitez en outre limiter cela aux commit et tags, vous pouvez utiliser git cat-file -t pour connaître le type de l'objet.

Ceci pourrait être utilisé, par exemple, pour rechercher du texte généré par un humain pour des mentions de commits git et pour générer des hyperliens vers une interface web git.

0

Pour ce type de hachage: 43:A4:02:B7:B6:1D:89:86:C5:CE:AD:52:96:D9:2E:7B:64:98:45:6A:

/^[0-9A-F]{2}(:[0-9A-F]{2}){19}$/ 
0

J'utiliser dans le rubis. Il permet une version courte du sha (6 - 8 en cas d'affrontements) et pour le sha complet à 40 caractères.

\A(([0-9a-f]{40})|([0-9a-f]{6,8}))\z 
+0

Puisque vous dites _ruby_, ce serait encore plus court: '\ A ((\ h {40}) | (\ h {6,8})) \ z', car' \ h' représente la classe de caractères hexadécimaux. – Julien

Questions connexes