46

我正在尝试将通用文本中的 SHA1 与正则表达式匹配。

理想情况下,我想避免匹配单词。

可以肯定地说,完整的 SHA1 具有独特的模式(它们很长且长度一致) - 所以我可以可靠地匹配这些 - 但是缩写的 SHA1 呢?

我可以依赖数字的存在吗?

查看我的提交日志中的 SHA1 - 数字总是出现在前 3 个字符中。但这太短了吗?在我假设一个数字会出现之前,我需要考虑多少个 SHA1 字符?

这不一定是 100% 准确 - 我只需要 99% 的时间匹配缩写的 SHA1。

4

6 回答 6

79

您可以认为 SHA1 哈希是完全随机的,因此这减少了概率问题。给定数字不是数字的概率是 6/16,即 0.375。三个 SHA1 数字都不是数字的概率是 0.375 ** 3,或 0.0527(5% ish)。在六位数时,这再次减少到 0.00278 (0.2%)。在五位数时,所有字母的概率下降到 1% 以下(你说你想匹配 99% 的时间)。

制作始终与 SHA1 值匹配的正则表达式很容易:

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

但是,这也可能匹配完美的五个字母单词,例如“添加”或“褪色”。在我的/usr/share/dict/words文件中,有几个六个字母的单词会匹配:“accede”、“beaded”、“bedded”、“decade”、“deface”、“efface”和“facade”是最有可能的。在七个字母中,只有不太可能出现在散文中的“契约”。这完全取决于您可以容忍多少误报,以及您实际遇到的可能单词是什么。

于 2009-01-22T08:04:56.440 回答
41

你到底想做什么?你不应该需要用启发式解析任何 git 输出——你总是可以准确地请求你需要的数据。

如果要匹配 SHA1 和的完整十六进制表示,请尝试:

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

也就是说,一个由 40 个字符组成的单词,这些字符要么是数字,要么是字母 a 到 f。

如果你只有几个字符并且不知道它们在哪里,那么你就很不走运了。“e78fd98”是缩写的提交 ID 吗?也许吧,但是“1234567”呢?那是提交ID吗?有问题的票号?使测试失败的数字?

没有上下文,您无法真正了解数据的含义。

要回答您的直接问题,SHA1 没有属性可以使前三个字符(以十六进制形式)为数字。你只是幸运,或者可能是不幸,这取决于你如何看待它。

于 2009-01-22T08:15:26.623 回答
7

我将假设您想要匹配 SHA1 的十六进制打印表示,而不是与等效的 20 个原始字节匹配。此外,我将假设所讨论的 SHA1 仅使用小写字母来表示十六进制数字。如果您的要求不同,则必须调整正则表达式。

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

将匹配这样的 SHA1。您需要将上述正则表达式从 egrep 的方言转换为您碰巧使用的任何工具。由于匹配必须正好有 40 个字符长,我认为您不会有意外匹配单词的危险。我不知道任何仅由字母 a 到 f 组成的 40 个字符的单词。

编辑:

更好的是:使用A Regex 匹配 SHA1,因为他的解决方案包括检查两端的单词边界。我忽略了上面的那个。

于 2009-01-22T08:25:29.613 回答
3

如果您有权访问 repo,则可以使用git cat-file -e它来检查它是否代表 repo 中的对象。这也非常快。如果您进一步想将其限制为仅提交和标签,您可以使用git cat-file -t来找出对象的类型。

例如,这可用于搜索人工生成的文本以查找提及 git 提交并生成指向 git Web 界面的超链接。

于 2010-07-02T06:08:31.107 回答
0

我在红宝石中使用它。它允许 sha 的简短版本(在发生冲突的情况下为 6 - 8)和 40 个字符长的完整 sha。

\A(([0-9a-f]{40})|([0-9a-f]{6,8}))\z
于 2014-01-29T22:40:09.983 回答
-2

对于这种类型的哈希 : 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}$/
于 2011-08-28T13:31:32.063 回答