Una Regex para coincidir con un SHA1

Estoy tratando de hacer coincidir SHA1 en text genérico con una expresión regular.

Lo ideal es evitar las palabras coincidentes.

Es seguro decir que los SHA1 completos tienen un patrón distintivo (son largos y de una longitud constante), por lo que puedo unirlos de manera confiable, pero ¿qué hay con los SHA1 abreviados?

¿Puedo confiar en la presencia de numbers?

Mirando los SHA1 en mi logging de compromiso, los numbers siempre aparecen en los primeros 3 caracteres. Pero, ¿es esto demasiado corto? ¿Cuántos caracteres de SHA1 necesito considerar antes de poder asumir que un número hubiera aparecido?

Esto no tiene que ser 100% exacto, solo necesito hacer coincidir un SHA1 abreviado el 99% del time.

Puede considerar que los hashes SHA1 son completamente aleatorios, por lo que esto se networkinguce a una cuestión de probabilidades. La probabilidad de que un dígito dado no sea un número es 6/16 o 0.375. La probabilidad de que tres dígitos SHA1 no sean numbers es 0.375 ** 3, o 0.0527 (5% ish). En seis dígitos, esto se networkinguce nuevamente a 0.00278 (0.2%). Con cinco dígitos, la probabilidad de que todas las letras caigan por debajo del 1% (dijiste que querías unir el 99% del time).

Es fácil crear una expresión regular que siempre coincida con los valores de SHA1:

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

Sin embargo, esto también puede coincidir perfectamente con palabras de cinco letras, como "agregado" o "desvanecido". En mi file /usr/share/dict/words , hay varias palabras de seis letras que constringn: "acceder", "con counts", "con cama", "década", "desfigurar", "borrar" y "fachada" son los más probables En siete letras, solo hay "profundo" que es poco probable que aparezca en prosa. Todo depende de cuántos falsos positivos pueda tolerar y cuáles sean las posibles palabras con las que se encontrará.

¿Qué estás tratando de hacer exactamente? No debería necesitar analizar nada con salidas heurísticas; siempre puede solicitar exactamente los datos que necesita.

Si desea hacer coincidir una representación hexadecimal completa de una sum SHA1, intente:

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

Es decir, una palabra que consta de 40 caracteres que son o dígitos o las letras aa f.

Si solo tienes algunos personajes y no sabes dónde están, entonces no estás de suerte. ¿Es "e78fd98" una identificación de confirmación abreviada? Quizás, pero ¿qué pasa con "1234567"? ¿Es eso una identificación de compromiso? ¿Un número de ticket problemático? ¿Un número que hace que una testing falle?

Sin context, no se puede saber realmente qué significan los datos.

Para responder a su pregunta directa, no hay ninguna propiedad de SHA1 que haga los primeros tres caracteres (en forma de hexágono) dígitos. Tienes suerte, o tal vez mala suerte, dependiendo de cómo lo mires.

Voy a suponer que desea hacer coincidir contra la representación impresa hexadecimal de un SHA1, y no contra el equivalente de 20 bytes sin formatting. Además, voy a suponer que los SHA1 en cuestión usan solo letras minúsculas para representar dígitos hexadecimales. Tendrá que ajustar la expresión regular si sus requisitos son diferentes.

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

Coincidirá con tal SHA1. Deberá traducir la expresión regular anterior del dialecto de egrep a la herramienta que esté utilizando. Dado que el partido debe tener exactamente 40 caracteres, no creo que estés en peligro de casar palabras accidentalmente. No conozco ninguna palabra de 40 caracteres que consista solo de las letras aa f.

editar:

Mejor aún: use A Regex para que coincida con un SHA1 ya que su solución incluye verificar los límites de las palabras en ambos extremos. Pasé por alto eso de arriba.

Si tiene acceso al repository, puede usar git cat-file -e para verificar que representa un object en el repository. Esto es muy rápido, también. Si además quieres restringir esto a commits y tags, puedes usar git cat-file -t para encontrar el tipo de object.

Esto podría usarse, por ejemplo, para search text generado por humanos para menciones de commit de git y generar hyperlinks a una interfaz web de git.

Para este tipo de hash: 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}$/ 

Lo uso en ruby Permite una versión corta del sha (6 – 8 en caso de choques) y para el sha completo a 40 caracteres de largo.

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