最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

nodejs [13.13.0]和ruby [2.5.1p57]之间的zlib实现差异

网站源码admin20浏览0评论

nodejs [13.13.0]和ruby [2.5.1p57]之间的zlib实现差异

nodejs [13.13.0]和ruby [2.5.1p57]之间的zlib实现差异

我正在学习git的内部知识,这是我的存储库中的一棵树:

git cat-file 88e38705fdbd3608cddbe904b67c731f3234c45b -p
100644 blob ce013625030ba8dba906f756967f9e9ca394464a    hello.txt
100644 blob cc628ccd10742baea8241c5924df992b5c019f71    world.txt

当我将Ruby的zlib与:一起使用时:

puts Zlib::Inflate.inflate(STDIN.read)

并通过hexdump -C传递输出:

cat .git/objects/88/e38705fdbd3608cddbe904b67c731f3234c45b | rinflate | hexdump -C

这是输出:

00000000  74 72 65 65 20 37 34 00  31 30 30 36 34 34 20 68  |tree 74.100644 h|
00000010  65 6c 6c 6f 2e 74 78 74  00 ce 01 36 25 03 0b a8  |ello.txt...6%...|
00000020  db a9 06 f7 56 96 7f 9e  9c a3 94 46 4a 31 30 30  |....V......FJ100|
00000030  36 34 34 20 77 6f 72 6c  64 2e 74 78 74 00 cc 62  |644 world.txt..b|
00000040  8c cd 10 74 2b ae a8 24  1c 59 24 df 99 2b 5c 01  |...t+..$.Y$..+\.|
00000050  9f 71                                             |.q|
00000052

但是,当我使用NodeJS时:

  const zlib = require("zlib");
  const fs = require("fs");
  fs.writeFileSync("/dev/stdout", zlib.inflateSync(fs.readFileSync("/dev/stdin")).toString());

我得到此输出:

00000000  74 72 65 65 20 37 34 00  31 30 30 36 34 34 20 68  |tree 74.100644 h|
00000010  65 6c 6c 6f 2e 74 78 74  00 ef bf bd 01 36 25 03  |ello.txt.....6%.|
00000020  0b ef bf bd db a9 06 ef  bf bd 56 ef bf bd 7f ef  |..........V.....|
00000030  bf bd ef bf bd ef bf bd  ef bf bd 46 4a 31 30 30  |...........FJ100|
00000040  36 34 34 20 77 6f 72 6c  64 2e 74 78 74 00 ef bf  |644 world.txt...|
00000050  bd 62 ef bf bd ef bf bd  10 74 2b ef bf bd ef bf  |.b.......t+.....|
00000060  bd 24 1c 59 24 df 99 2b  5c 01 ef bf bd 71        |.$.Y$..+\....q|

为什么会有这种差异?以及如何使NodeJS和Ruby输出相同的内容?

回答如下:

在JavaScript中,字符串是用UTF-16编码的Unicode字符序列。您不能将非文本内容存储在JavaScript字符串中,因为它不能提供以任何其他编码形式存储的方法。

但是,Git树对象是二进制的,并且包含二进制格式的加密哈希(通常为SHA-1),因此它们将不会具有文本内容,也无法存储在JavaScript字符串中。如果仍然尝试这样做,将会得到无效的字节值,该值将由替换字符U + FFFD替换,该替换字符在UTF-8中编码为0xef 0xbf 0xbd,从而破坏了数据。

如果不调用toString(),则您的数据存储在某种二进制缓冲区对象中,并且具有zlib解码的字节。

另一方面,Ruby的每个字符串都有一个编码,可以存储编码为ASCII-8BIT(也称为BINARY)的二进制字符串。因此,如果您有Ruby代码,则可能会正常工作。

发布评论

评论列表(0)

  1. 暂无评论