前言:
.NET用户在任何情况下都不应使用Microsoft提供的GZipStream或DeflateStream类,除非Microsoft用可行的东西完全替换了它们。
请改用 DotNetZip库。
更新到前言: .NET framework
4.5和更高版本已解决了压缩问题,并且GZipStream和DeflateStream在这些版本中使用zlib。我不知道下面提到的CRC问题是否已解决。
另一个更新:
CRC问题不仅没有得到解决,而且Microsoft决定他们不会解决它!
这是GZipStream中的几个错误之一。自尊的gzip压缩器 永远 都不能从11个字节的输入中产生133个字节的输出。请参阅为什么BCL
GZipStream(使用StreamReader)不能可靠地使用CRC32检测数据错误的评论。。
内部发生的事情是GZipStream没有使用静态或存储方法,这两种方法都将产生与输入数据大小相同的压缩数据(在其顶部将添加18个字节的gzip标头和尾标)。相反,它使用了动态方法,该方法为非常少量的代码创建了非常大的代码描述符标头。这仅仅是一个错误/非常糟糕的实现。
更新:
对于十六进制转储,我可以提供一些分析。首先,Fiddler和php输出都是正确和正确的。它们之间的唯一区别是在gzip标头中,特别是在Fiddler中设置的时间戳(而不是在php中),以及原始 *** 作系统在php中设置,而不是在Fiddler中。因为这13个字节的压缩数据是相同的,并且可以表示为(使用我的infgen程序反汇编deflate流):
laststaticliteral 'Hello Worldend
完全应该如此。单个静态块,不需要代码描述符,只需将所有字节编码为文字。(没有与长度和距离匹配的先前字符串。)
另一方面,GZipStream的输出在几种方面令人震惊。压缩后的数据为:
dynamicpre 3 5pre 4 5pre 5 4pre 6 4pre 7 4pre 8 3pre 9 3pre 10 4pre 11 4pre 12 4pre 13 4pre 14 3pre 16 3litlen 0 14litlen 1 14litlen 2 14litlen 3 14litlen 4 14litlen 5 14litlen 6 14litlen 7 14litlen 8 14litlen 9 12litlen 10 6litlen 11 14litlen 12 14litlen 13 14litlen 14 14litlen 15 14litlen 16 14litlen 17 14litlen 18 14litlen 19 14litlen 20 14litlen 21 14litlen 22 14litlen 23 14litlen 24 14litlen 25 14litlen 26 14litlen 27 14litlen 28 14litlen 29 14litlen 30 13litlen 31 14litlen 32 6litlen 33 14litlen 34 10litlen 35 12litlen 36 14litlen 37 14litlen 38 13litlen 39 10litlen 40 8litlen 41 9litlen 42 11litlen 43 10litlen 44 7litlen 45 8litlen 46 7litlen 47 9litlen 48 8litlen 49 8litlen 50 8litlen 51 9litlen 52 8litlen 53 9litlen 54 10litlen 55 9litlen 56 8litlen 57 9litlen 58 9litlen 59 8litlen 60 9litlen 61 10litlen 62 8litlen 63 14litlen 64 14litlen 65 8litlen 66 9litlen 67 8litlen 68 9litlen 69 8litlen 70 9litlen 71 10litlen 72 11litlen 73 8litlen 74 11litlen 75 14litlen 76 9litlen 77 10litlen 78 9litlen 79 10litlen 80 9litlen 81 12litlen 82 9litlen 83 9litlen 84 9litlen 85 10litlen 86 12litlen 87 11litlen 88 14litlen 89 14litlen 90 12litlen 91 11litlen 92 14litlen 93 11litlen 94 14litlen 95 14litlen 96 14litlen 97 6litlen 98 7litlen 99 7litlen 100 7litlen 101 6litlen 102 8litlen 103 8litlen 104 7litlen 105 6litlen 106 12litlen 107 9litlen 108 6litlen 109 7litlen 110 7litlen 111 6litlen 112 7litlen 113 13litlen 114 6litlen 115 6litlen 116 6litlen 117 7litlen 118 8litlen 119 8litlen 120 9litlen 121 8litlen 122 11litlen 123 13litlen 124 12litlen 125 13litlen 126 13litlen 127 14litlen 128 14litlen 129 14litlen 130 14litlen 131 14litlen 132 14litlen 133 14litlen 134 14litlen 135 14litlen 136 14litlen 137 14litlen 138 14litlen 139 14litlen 140 14litlen 141 14litlen 142 14litlen 143 14litlen 144 14litlen 145 14litlen 146 14litlen 147 14litlen 148 14litlen 149 14litlen 150 14litlen 151 14litlen 152 14litlen 153 14litlen 154 14litlen 155 14litlen 156 14litlen 157 14litlen 158 14litlen 159 14litlen 160 14litlen 161 14litlen 162 14litlen 163 14litlen 164 14litlen 165 14litlen 166 14litlen 167 14litlen 168 14litlen 169 14litlen 170 14litlen 171 14litlen 172 14litlen 173 14litlen 174 14litlen 175 14litlen 176 14litlen 177 14litlen 178 14litlen 179 14litlen 180 14litlen 181 14litlen 182 14litlen 183 14litlen 184 14litlen 185 14litlen 186 14litlen 187 14litlen 188 14litlen 189 14litlen 190 14litlen 191 14litlen 192 14litlen 193 14litlen 194 14litlen 195 14litlen 196 14litlen 197 14litlen 198 14litlen 199 14litlen 200 14litlen 201 14litlen 202 14litlen 203 14litlen 204 14litlen 205 14litlen 206 14litlen 207 14litlen 208 14litlen 209 14litlen 210 14litlen 211 14litlen 212 14litlen 213 14litlen 214 14litlen 215 14litlen 216 14litlen 217 14litlen 218 14litlen 219 14litlen 220 14litlen 221 14litlen 222 14litlen 223 14litlen 224 14litlen 225 14litlen 226 14litlen 227 14litlen 228 14litlen 229 14litlen 230 14litlen 231 14litlen 232 14litlen 233 14litlen 234 14litlen 235 14litlen 236 14litlen 237 14litlen 238 14litlen 239 14litlen 240 14litlen 241 14litlen 242 14litlen 243 13litlen 244 13litlen 245 13litlen 246 14litlen 247 13litlen 248 14litlen 249 13litlen 250 14litlen 251 13litlen 252 14litlen 253 14litlen 254 14litlen 255 14litlen 256 14litlen 257 4litlen 258 3litlen 259 4litlen 260 4litlen 261 4litlen 262 5litlen 263 5litlen 264 5litlen 265 5litlen 266 5litlen 267 6litlen 268 6litlen 269 5litlen 270 6litlen 271 7litlen 272 8litlen 273 8litlen 274 9litlen 275 10litlen 276 9litlen 277 10litlen 278 12litlen 279 11litlen 280 12litlen 281 14litlen 282 14litlen 283 14litlen 284 12litlen 285 11dist 0 6dist 1 10dist 2 11dist 3 11dist 4 9dist 5 8dist 6 8dist 7 8dist 8 7dist 9 7dist 10 5dist 11 6dist 12 4dist 13 5dist 14 4dist 15 5dist 16 4dist 17 5dist 18 4dist 19 4dist 20 4dist 21 4dist 22 4dist 23 4dist 24 4dist 25 5dist 26 4dist 27 5dist 28 5dist 29 5literal 'Hello Worldend!laststoredend
那到底是什么?实际数据只是“ literal’Hello
World”末尾附近的行,该行仅对输入的每个字节进行编码。它之前是一组有关文字,长度和距离的霍夫曼代码的描述。这是问题所在:
- 首先,它根本不应该使用动态。描述代码集大约需要100个字节。这正是放气格式提供了静态块中使用的一组预定义代码的原因。在这种情况下,压缩器应选择一个静态块(这是php和Fiddler所做的事情)。
- 其次,即使从未使用过绝大多数代码,也定义了每个可能的代码!使用动态块时,适当的压缩器将仅定义该块中实际使用的文字,长度和距离的代码。在这种情况下,不使用长度或距离,而仅使用八个不同的文字(H,e,l,o,space,w,r和d)。相反,它继续定义256个文字代码,29个长度代码和30个距离代码。我猜想一些实验将显示GZipStream的动态标头始终是相同的,在这种情况下它甚至不是动态的,这就是重点!
- 第三,它最后抛出不必要的空存储块。应该将第一个块标记为最后一个块。
所有这一切都表明一个简单的事实,就是谁写了这个GZipStream代码,都是出于礼貌地对一般的deflate格式或压缩不了解。他们选择只产生动态块(末尾有一个空的静态块除外),每次都只产生相同的动态头(我认为),这违背了动态块的目的,并且不去理会当前块是最后一个,需要放一个空块来标记结尾。
如其他地方所述,这些并不是GZipStream的唯一问题。它甚至无法正确地使用CRC-32来检测损坏的流。
真正令人困惑的不是为什么Microsoft指派不称职的人来编写gzip压缩器和解压缩器,而是为什么他们要指派任何人来编写它!有免费的代码zlib,它具有极其宽松的许可证,允许在没有署名的情况下进行商业使用。这段代码已经广泛部署了近二十年,它可以正确有效地完成所有工作。大多数其他东西都使用zlib,包括php,我也怀疑Fiddler。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)