web-dev-qa-db-fra.com

Un regex pour correspondre à un SHA1

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

Idéalement, je veux éviter de faire correspondre les mots. 

Il est prudent de dire que les SHA1 complets ont un motif distinctif (ils sont longs et cohérents) - afin que je puisse les reproduire de manière fiable - mais qu'en est-il des SHA1 abrégés?

Puis-je compter sur la présence de chiffres?

En regardant les SHA1 dans mon journal de commit, 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 nombre serait apparu? 

Cela ne doit pas nécessairement être précis à 100% - je dois simplement faire correspondre un SHA1 abrégé 99% du temps.

31
git-noob

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 6/16, ou 0,375. La probabilité que trois chiffres SHA1 ne soient pas des nombres est 0,375 ** 3, ou 0,0527 (5% ish). À six chiffres, le nombre passe à 0,00278 (0,2%). À cinq chiffres, la probabilité que toutes les lettres descendent en dessous de 1% (vous avez dit vouloir faire correspondre 99% du temps).

Il est facile de créer une expression régulière qui correspond toujours aux valeurs SHA1:

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

Cependant, cela peut aussi correspondre parfaitement à des mots de cinq lettres, comme "ajouté" ou "fané". Dans mon fichier /usr/share/dict/words, il y a plusieurs mots de six lettres qui pourraient correspondre: "accéder", "perlé", "literie", "décade", "déformation", "effacé" 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 mots probables que vous allez rencontrer.

61
Greg Hewgill

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

Si vous souhaitez faire correspondre une représentation hexadécimale complète d'une somme SHA1, essayez:

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

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

Si vous n'avez que quelques personnages et que vous ne savez pas où ils se trouvent, vous avez peu de chance. "E78fd98" est-il un identifiant de validation abrégé? Peut-être, mais qu'en est-il de "1234567"? Est-ce un identifiant de commit? Un numéro de ticket 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, il n’existe aucune propriété de SHA1 qui donnerait aux trois premiers caractères (sous forme hexadécimale) des chiffres. Vous êtes simplement chanceux, ou peut-être malchanceux, selon votre point de vue.

32
jrockway

Je suppose que vous souhaitez faire correspondre la représentation imprimée hexadécimale d'un SHA1, et non les 20 octets bruts équivalents. De plus, 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 exigences diffèrent.

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

Correspondra à un tel SHA1. Vous aurez besoin de traduire l'expression régulière ci-dessus du dialecte d'egrep vers l'outil que vous utiliserez par la suite. Étant donné que la correspondance doit comporter exactement 40 caractères, je ne pense pas que vous risquez de faire correspondre des mots par inadvertance. Je ne connais aucun mot de 40 caractères composé uniquement des lettres a à f.

modifier:

Mieux encore: utilisez Un regex pour faire correspondre un SHA1 car sa solution inclut la vérification des limites de Word aux deux extrémités. J'ai oublié cela ci-dessus.

4
bendin

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

Cela pourrait être utilisé, par exemple, pour rechercher dans le texte généré par l'homme des mentions des commits git et générer des hyperliens vers une interface Web git.

3
Neil Mayhew

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
Dededede4

Je l'utilise en Ruby. Il permet une version courte du sha (6 à 8 en cas d’affrontements) et un sha complet avec une longueur de 40 caractères.

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