BASH:有没有一种简单的方法来检查一个字符串是否是有效的SHA-1(或MD5)哈希?

5

标题就是全部内容。

另一种表述问题的方式是:在BASH中,检查一个字符串是否为由40(或32)个字符组成的序列,并且这些字符位于[0-9][a-f]范围内,有没有简洁的方法?

3个回答

9

尝试以下内容,长度为32个字符:

if [[ $SOME_MD5 =~ ^[a-f0-9]{32}$ ]]
then
    echo "Match"
else
    echo "No match"
fi

这样做不会匹配任何带有前导或尾随非十六进制字符的十六进制字符串吗?使用^和$进行定界应该可以处理这种情况。 - akhan
这个测试返回从0到32个字符的字符串匹配。我认为,如果您想要确切地检查32个字符,您需要^[a-f0-9]{32}$ - elboulangero

9

使用函数:

is_valid() {
    case $1 in
      ( *[!0-9A-Fa-f]* | "" ) return 1 ;;
      ( * )                
        case ${#1} in
          ( 32 | 40 ) return 0 ;;
          ( * )       return 1 ;;
        esac
    esac    
  }

如果shell支持POSIX字符类,则可以使用[![:xdigit:]]代替[!0-9A-Fa-f]

+1 优雅、简洁、惯用语,我相信它与 POSIX 的 sh 兼容(除了 case 中开括号我不太确定)。 - tripleee
请问您能否评论一下@aioobe解决方案中哪些部分不兼容Bourne Classic?谢谢。 - Philippe
1
@Philippe,无论是[[ shell关键字还是=~运算符都不是标准的。 - Dimitre Radoulov
1
@tripleee,谢谢!左括号是可选的,但是标准的,参见SUSCase Conditional Construct - Dimitre Radoulov
2
一些旧的 shell 可能更喜欢使用 [!0-9a-f] 而不是 [^0-9a-f]。而且你可能还想包括大写字母(原文如此)。 - tripleee
谢谢@tripleee,我经常在这种情况下错误地使用^而不是! :) 已更正。(A-Fa-f内容与区域设置有关)。 - Dimitre Radoulov

1
stringZ=0123456789ABCDEF0123456789ABCDEF01234567

echo ${#stringZ}
40
echo `expr "$stringZ" : '[0-9a-fA-F]\{32\}\|[0-9a-fA-F]\{40\}'`
40

然后,测试${#stringZ}是否等于expr "$stringZ" : '[0-9a-fA-F]\{32\}\|[0-9a-fA-F]\{40\}',如果字符串是32或40个字符且仅包含十六进制数字,则应为真。

就像这样:

#!/bin/bash
stringZ=""
while [ "$stringZ" != "q" ]; do
    echo "Enter a 32 or 40 digit hexadecimal ('q' to quit): "
    read stringZ
    if [ "$stringZ" != "q" ]; then
        if [ -n $stringZ ] && [ `expr "$stringZ" : '[0-9a-fA-F]\{32\}\|[0-9a-fA-F]\{40\}'` -eq ${#stringZ} ]; then
            echo "GOOD HASH"
        else
            echo "BAD HASH"
        fi
    fi
done

输出:

[ 07:45 jon@host ~ ]$ ./hexTest.sh 
Enter a 32 or 40 digit hexadecimal ('q' to quit):
1234567890abcdef1234567890abcdef
GOOD HASH
Enter a 32 or 40 digit hexadecimal ('q' to quit):
1234567890abcdef1234567890abcdef01234567
GOOD HASH
Enter a 32 or 40 digit hexadecimal ('q' to quit):
1234567890abcdef1234567890abcdef0
BAD HASH
Enter a 32 or 40 digit hexadecimal ('q' to quit):
123
BAD HASH
Enter a 32 or 40 digit hexadecimal ('q' to quit):
abcdef
BAD HASH
Enter a 32 or 40 digit hexadecimal ('q' to quit):
0123456789ABCDEF0123456789aBcDeF98765432
GOOD HASH
Enter a 32 or 40 digit hexadecimal ('q' to quit):
q
[ 07:46 jon@host ~ ]$

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接