这段代码如何生成字符串“nginx”?

这段代码如何生成字符串“nginx”?,nginx,hex,huffman-code,Nginx,Hex,Huffman Code,我一直在努力研究nginx源代码。最近,nginx1.9.12发布了,他们在HTTP/2中实现了响应头的霍夫曼编码 在这个版本中,我无法理解这一行 static const u_char nginx[5] = "\x84\xaa\x63\x55\xe7"; 或者,您可以在此处浏览源代码: 这一行是Nginx用来插入头服务器的:Nginx 如果我想把它改成Apache呢?我尝试将字符串apache转换为十六进制,然后用\xhh符号替换文件中的十六进制,并将nginx[5]更改为nginx[6],

我一直在努力研究nginx源代码。最近,nginx1.9.12发布了,他们在HTTP/2中实现了响应头的霍夫曼编码

在这个版本中,我无法理解这一行

static const u_char nginx[5] = "\x84\xaa\x63\x55\xe7";
或者,您可以在此处浏览源代码:

这一行是Nginx用来插入头服务器的:Nginx

如果我想把它改成Apache呢?我尝试将字符串apache转换为十六进制,然后用\xhh符号替换文件中的十六进制,并将nginx[5]更改为nginx[6],因为字符串apache的长度为6个字符

但产出似乎不可预测。在问这个问题之前,我已经搜索了很多


有人能帮我这个代码是怎么工作的吗?我怎么替换文本?任何脚本或在线web应用程序都可以简化此过程?

您在这里看到的是使用HPACK的哈夫曼编码压缩的字符串nginx的表示形式

nginx[] = {0x05, 'n', 'g', 'i', 'n', 'x'};

Apache[] = {0x06, 'A', 'p', 'a', 'c', 'h', 'e'};
在这种情况下,第一个字节表示字符串的长度和编码。 顶部位表示是否使用哈夫曼压缩,其余7位表示压缩后字符串的长度(如果使用哈夫曼)

在这种情况下,第一个字节是0x84。顶部位已设置,表示使用了哈夫曼。长度是4

在您的情况下,简单的修复方法是在不使用Huffman的情况下对字符串进行编码。在nginx 0x05的情况下,字符串的长度应该放在第一个字节中,在Apache的情况下,字符串的长度应该放在第一个字节中,0x06。之后是字符串的ASCII表示形式。这将适用于最多63字节的所有字符串。更长的字符串需要更多的字节进行长度编码

nginx[] = {0x05, 'n', 'g', 'i', 'n', 'x'};

Apache[] = {0x06, 'A', 'p', 'a', 'c', 'h', 'e'};

这里您看到的是使用HPACK的哈夫曼编码压缩的字符串nginx的表示

nginx[] = {0x05, 'n', 'g', 'i', 'n', 'x'};

Apache[] = {0x06, 'A', 'p', 'a', 'c', 'h', 'e'};
在这种情况下,第一个字节表示字符串的长度和编码。 顶部位表示是否使用哈夫曼压缩,其余7位表示压缩后字符串的长度(如果使用哈夫曼)

在这种情况下,第一个字节是0x84。顶部位已设置,表示使用了哈夫曼。长度是4

在您的情况下,简单的修复方法是在不使用Huffman的情况下对字符串进行编码。在nginx 0x05的情况下,字符串的长度应该放在第一个字节中,在Apache的情况下,字符串的长度应该放在第一个字节中,0x06。之后是字符串的ASCII表示形式。这将适用于最多63字节的所有字符串。更长的字符串需要更多的字节进行长度编码

nginx[] = {0x05, 'n', 'g', 'i', 'n', 'x'};

Apache[] = {0x06, 'A', 'p', 'a', 'c', 'h', 'e'};

我编写了简单的Go脚本,用于将HPACK压缩字符串从/转换为HPACK压缩字符串:

包干管 // ////////////////////////////////////////////////////////////////////////////////// // 进口 fmt golang.org/x/net/http2/hpack // ////////////////////////////////////////////////////////////////////////////////// // func main{ fmt.Printlnnginx,→, Encodinginx fmt.Printlnapache,→, 阿帕奇编码 fmt.Println--- fmt.Println\\x84\\xaa\\x63\\x55\\xe7,→, 解码\x84\xaa\x63\x55\xe7 fmt.Println\\x84\\x1d\\x63\\x24\\xe5,→, 解码\x84\x1d\x63\x24\xe5 } func对字符串进行编码{ 变量结果字符串 hd:=hpack.appendhuffmanstringni,s hl:=hpack.huffmanencodelength | 0x80 结果+=renderBytehl 对于u,b:=范围hd{ 结果+=渲染字节B } 返回结果 } func解码字符串{ 数据:=[]字节 结果,u:=hpack.HuffmanDecodeToStringdata[1:] 返回结果 } func renderByte字节字符串{ 返回fmt.Sprintf\\x%x,b } // ////////////////////////////////////////////////////////////////////////////////// //
我编写了简单的Go脚本,用于将HPACK压缩字符串从/转换为HPACK压缩字符串:

包干管 // ////////////////////////////////////////////////////////////////////////////////// // 进口 fmt golang.org/x/net/http2/hpack // ////////////////////////////////////////////////////////////////////////////////// // func main{ fmt.Printlnnginx,→, Encodinginx fmt.Printlnapache,→, 阿帕奇编码 fmt.Println--- fmt.Println\\x84\\xaa\\x63\\x55\\xe7,→, 解码\x84\xaa\x63\x55\xe7 fmt.Println\\x84\\x1d\\x63\\x24\\xe5,→, 解码\x84\x1d\x63\x24\xe5 } func对字符串进行编码{ 变量结果字符串 hd:=hpack.appendhuffmanstringni,s hl:=hpack.huffmanencodelength | 0x80 结果+=renderBytehl 对于u,b:=范围hd{ 结果+=渲染字节B } 返回结果 } func解码字符串{ 数据:=[]字节 结果,u:=hpack.HuffmanDecodeToStringdata[1:] 返回结果 } func renderByte字节字符串{ 返回fmt.Sprintf\\x%x,b } // ////////////////////////////////////////////////////////////////////////////////// //
谢谢你,弗拉德。我已将行更改为static const u_char nginx[]={0x06、0x41、0x70、0x61、0x63、0x68、0x65};并编译。服务器在服务器头中响应Apache。这就是我想要的。但是,我只想知道,如果我使用enc,是否存在任何性能影响或安全问题
使用HPACK的哈夫曼编码对字符串进行ode,这与源代码中的编码方式以及您告诉我的不使用哈夫曼的方式相同。我更喜欢您的方式,即使用HPACK的哈夫曼编码对字符串进行编码。至少,只是为了了解它是如何工作的。在这种情况下,您应该调用ngx_http_v2_write_value。它将以最短的形式对字符串进行编码。OK。谢谢你,弗拉德。调用ngx_http_v2_write_值的正确方法是什么?在nginx源代码中,它有4个参数dst、src、len、tmp。我很困惑,因为我只有一个字符串作为输入。我宁愿直接知道字符串的哈夫曼编码十六进制值,而不是在源代码中进行另一次调用,这样我就可以像您那样做。除了C/C++中的nginxs之外,还有什么样的代码可以做到这一点?我在C的表现不如你,只是一个向你这样的专家学习的大学生。再次感谢Vlad。您可以复制相关代码,将其编译为独立的应用程序,运行它,然后查看结果。Vlad,过去几周我一直在尝试。我无法获取工作代码。你有剧本或类似的东西吗?我感觉很痛苦,谢谢你,弗拉德。我已将行更改为static const u_char nginx[]={0x06、0x41、0x70、0x61、0x63、0x68、0x65};并编译。服务器在服务器头中响应Apache。这就是我想要的。但是,我只想知道是否有任何性能影响或安全问题,如果我使用HPACK的Huffman编码字符串,就像它在源代码中的编码方式,以及您告诉我不要使用Huffman的方式。我更喜欢您的方式,即使用HPACK的哈夫曼编码对字符串进行编码。至少,只是为了了解它是如何工作的。在这种情况下,您应该调用ngx_http_v2_write_value。它将以最短的形式对字符串进行编码。OK。谢谢你,弗拉德。调用ngx_http_v2_write_值的正确方法是什么?在nginx源代码中,它有4个参数dst、src、len、tmp。我很困惑,因为我只有一个字符串作为输入。我宁愿直接知道字符串的哈夫曼编码十六进制值,而不是在源代码中进行另一次调用,这样我就可以像您那样做。除了C/C++中的nginxs之外,还有什么样的代码可以做到这一点?我在C的表现不如你,只是一个向你这样的专家学习的大学生。再次感谢Vlad。您可以复制相关代码,将其编译为独立的应用程序,运行它,然后查看结果。Vlad,过去几周我一直在尝试。我无法获取工作代码。你有剧本或类似的东西吗?我感觉很痛苦,谢谢你,安迪。非常感谢,谢谢安迪。谢谢。