所以对于其他发现这个问题的人来说,故事如下:
是的,Andy 关于为什么 7-Zip 在文件上失败的原因确实是正确的,但这对我的问题没有帮助,因为我不能完全让人们使用我的 7-Zip 版本。
然而,泰伦给了我解决方案。
- 首先,按照他的建议,在 JPG 中添加一个小字节串会让 7-Zip 打开它。但是,它与有效的 JPG 片段略有不同,它需要为 FFEF00 07 504B030400 - 长度相差 2 个字节。
- 这让 7-Zip 打开它,但不提取文件,它会默默地失败。这是因为中央目录中的条目具有指向文件条目的内部指针/偏移量。既然你在那之前放了一堆东西,你需要纠正所有这些指针!
- 要使用 Windows 内置的 zip 支持打开 zip,正如 tyranid 所说,您需要更正“中央目录相对于起始磁盘号的起始偏移量”。这是一个执行最后两个的python脚本,虽然它是一个片段,而不是copypasta-ready-to-use
#Now we need to read the file and rewrite all the zip headers. Fun!
torewrite = open(magicfilename, 'rb')
magicdata = torewrite.read()
torewrite.close()
#Change the Central Repository's Offset
offsetOfCentralRepro = magicdata.find('\x50\x4B\x01\x02') #this is the beginning of the central repo
start = len(magicdata) - 6 #it so happens, that on my files, the point is stored 2 bytes from the end. so datadatadatdaata OF FS ET !! 00 00 EOF where OFFSET!! is the 4 bytes 00 00 are the last two bytes, then EOF
magicdata = magicdata[:start] + pack('I', offsetOfCentralRepro) + magicdata[start+4:]
#Now change the individual offsets in the central directory files
startOfCentralDirectoryEntry = magicdata.find('\x50\x4B\x01\x02', 0) #find the first central directory entry
startOfFileDirectoryEntry = magicdata.find('\x50\x4B\x03\x04', 10) #find the first file entry (we start at 10 because we have to skip past the first fake entry in the jpg)
while startOfCentralDirectoryEntry > 0:
#Now I move a magic number of bytes past the entry (really! It's 42!)
startOfCentralDirectoryEntry = startOfCentralDirectoryEntry + 42
#get the current offset just to output something to the terminal
(oldoffset,) = unpack('I', magicdata[startOfCentralDirectoryEntry : startOfCentralDirectoryEntry+4])
print "Old Offset: ", oldoffset, " New Offset: ", startOfFileDirectoryEntry , " at ", startOfCentralDirectoryEntry
#now replace it
magicdata = magicdata[:startOfCentralDirectoryEntry] + pack('I', startOfFileDirectoryEntry) + magicdata[startOfCentralDirectoryEntry+4:]
#now I move to the next central directory entry, and the next file entry
startOfCentralDirectoryEntry = magicdata.find('\x50\x4B\x01\x02', startOfCentralDirectoryEntry)
startOfFileDirectoryEntry = magicdata.find('\x50\x4B\x03\x04', startOfFileDirectoryEntry+1)
#Finally write the rewritten headers' data
towrite = open(magicfilename, 'wb')
towrite.write(magicdata)
towrite.close()