将Python SHA1摘要代码改写为适配OpenWRT的Bash脚本
问题描述
在Debian机器上运行以下Python代码可得到正确结果:
#!/usr/bin/env python3 text_in = "abcd".encode('utf8') sha1 = hashlib.sha1() sha1.update(text_in) raw_digest = sha1.digest() text_out = base64.b64encode(raw_digest) print( "text_in: " + str(text_in) ) print( "text_out: " + str(text_out) )
运行结果:
text_in: abcd text_out: gf6L/odXbD7LIkJvjleEc4KRes8=
尝试改写为Bash脚本后结果错误:
#!/bin/sh TEXT_IN="abcd" DIGEST=$( echo -n "$TEXT_IN" | sha1sum | awk '{print $1}' ) TEXT_OUT=$( echo -n "$DIGEST" | base64 ) echo "TEXT_IN: $TEXT_IN" echo "TEXT_OUT: $TEXT_OUT"
错误结果:
TEXT_IN: abcd TEXT_OUT: ODFmZThiZmU4NzU3NmMzZWNiMjI0MjZmOGU1Nzg0NzM4MjkxN2FjZg==
需要在磁盘空间有限的OpenWRT环境中,用轻量工具实现与原Python代码逻辑一致的Bash脚本。
错误原因
原Bash脚本的问题在于:sha1sum默认输出十六进制格式的摘要字符串,脚本将这个字符串转成了Base64;但Python代码中是直接对SHA1生成的原始二进制摘要做Base64编码,两者处理的对象完全不同,导致结果不符。
正确实现方案
针对OpenWRT的轻量环境,提供两种简洁的实现:
方案1:使用sha1sum + xxd(依赖coreutils,OpenWRT默认包含)
#!/bin/sh TEXT_IN="abcd" # 生成SHA1原始二进制摘要并转Base64 TEXT_OUT=$(printf "%s" "$TEXT_IN" | sha1sum --binary | awk '{print $1}' | xxd -r -p | base64) echo "TEXT_IN: $TEXT_IN" echo "TEXT_OUT: $TEXT_OUT"
方案2:使用openssl(若OpenWRT预装了openssl)
#!/bin/sh TEXT_IN="abcd" # 直接生成二进制SHA1摘要并转Base64 TEXT_OUT=$(printf "%s" "$TEXT_IN" | openssl dgst -sha1 -binary | base64) echo "TEXT_IN: $TEXT_IN" echo "TEXT_OUT: $TEXT_OUT"
说明
- 用
printf "%s"代替echo -n,避免不同shell环境下echo参数的兼容性问题 - 两种方案均会输出正确结果:
gf6L/odXbD7LIkJvjleEc4KRes8=
内容的提问来源于stack exchange,提问作者Tinware
相关产品推荐
相关产品推荐

