如何计算文本的真实SHA1?

时间:2018-01-26 20:42:04

标签: postgresql digest

my last question一样(请参阅详情),我正在使用

SELECT encode(digest(x::text::bytea, 'sha1'), 'hex') FROM xtmp;

没有解决,是不是相同的哈希tham原始...也许::text强制使用\n符号的内部表示,所以解决方案将直接转换为bytea,但它是一个无效的演员。

其他解决方法也不是解决方案,

SELECT encode(digest( replace(x::text,'\n',E'\n')::bytea, 'sha1' ), 'hex') 
FROM xtmp

...我尝试CREATE TABLE btmp (x bytea)COPY btmp FROM '/tmp/test.xml' ( FORMAT binary ),但错误(“未知的COPY文件签名”)。

1 个答案:

答案 0 :(得分:1)

简单的解决方案!添加" \ n"。

SELECT encode(digest((x::text||E'\n')::bytea, 'sha1'), 'hex') FROM xtmp;

但真正的问题是获得原始文件而不削减最后一个" \ n" (上次EOL)...让我们看看my old test-kit处的功能:

 INSERT INTO  xtmp (x) 
  SELECT array_to_string(array_agg(x),E'\n')::xml FROM ttmp
;

这是" bug" (在解决方法COPY之后没有将一个完整文件加载到一行中的一个字段)。
array_to_string()没有添加最后一个EOL,因此通过|| E'\n'连接来修复错误。

注意

检查其他假设并为测试工具包提供良好的解决方案。

POSIX规则不是问题......

行结束(EOL)是POSIX文件系统(和非二进制模式)的义务,请参阅this answer about EOL。我们可以想象类似于"字符串和文件表示因EOL而不同......我们可以查看吗?它有什么不同?

我们可以通过终端证明没有"字符串 vs 文件"问题,没有EOL的奇怪成瘾:

printf "<root/>" > original1.xml 
printf "<root/>\n" > original2.xml 
sha1sum original*.xml
printf "<root/>" | openssl sha1
printf "<root/>\n" | openssl sha1

结果

062c3db8ce3458fc3ccaf2f930bf663d8ce31d7d  original1.xml
a05d91cbf0902b0fe341c979e9fc18fc69813f55  original2.xml
(stdin)= 062c3db8ce3458fc3ccaf2f930bf663d8ce31d7d
(stdin)= a05d91cbf0902b0fe341c979e9fc18fc69813f55

所以sha1sum没有使用额外的EOL,字符串和文件是一些。

现在在SQL上,得出了同样的结论:

SELECT encode(digest('<root/>'::bytea, 'sha1'), 'hex') ;
SELECT encode(digest(E'<root/>\n'::bytea, 'sha1'), 'hex') ;

结果

 062c3db8ce3458fc3ccaf2f930bf663d8ce31d7d
 a05d91cbf0902b0fe341c979e9fc18fc69813f55

更好的测试工具包的解决方案

对于这个简单的加载/保存文本过程,COPY命令很难看,让我们使用直接的getfile函数:

CREATE FUNCTION getfile(p_file text) RETURNS text AS $$
   with open(args[0],"r") as content_file:
       content = content_file.read()
   return content
$$ LANGUAGE PLpythonU;

SELECT encode(digest( getfile('/tmp/original1.xml') ::bytea, 'sha1'), 'hex') ;
SELECT encode(digest( getfile('/tmp/original2.xml') ::bytea, 'sha1'), 'hex') ;

结果

062c3db8ce3458fc3ccaf2f930bf663d8ce31d7d
a05d91cbf0902b0fe341c979e9fc18fc69813f55

完美(!),现在没有EOL问题。