将十六进制字符串转换为二进制文件使其损坏且无法打开

Converting hex string to binary file makes it corrupt and unable to open

在转换十六进制值时,PDF 文件,文件已损坏。
这是我要转换的一个简单 pdf 文件的部分十六进制内容:

0x255044462D312E370D0A25B5B5B5B50D0A312030206F626A0D0A3C3C2F547970652F436174

完整字符串:jsfiddle, pastebin

这个问题是 this 问题的延续,我在其中说过我必须在两个处理文件的程序不同的程序之间进行数据迁移。 源程序将十六进制编码的文件存储在数据库中。

我可以使用以下代码成功提取文本文件并将其转换为二进制文件:

file_put_contents(
    'document.pdf', 
    hex2bin(str_replace('0x', '', $hexPdfString))
);

但是当我 运行 在 pdf 文件或其他二进制文件上使用此函数时,它已损坏。
我的问题与 this one 几乎相同,但不幸的是那里的讨论已经停止。

您的字符串的十六进制解码结果已损坏因为您的字符串不完整,它只包含前 65535 个字符。十六进制解码后,可以看到 PDF 在元数据流中被截断:

20 0 obj
<</Type/Metadata/Subtype/XML/Length 3064>>
stream
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?><x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="3.1-701">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""  xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
<pdf:Producer>Microsoft® Word 2019</pdf:Producer></rdf:Description>
<rdf:Description rdf:about=""  xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:creator><rdf:Seq><rdf:li>Samuel Gfeller</rdf:li></rdf:Seq></dc:creator></rdf:Description>
<rdf:Description rdf:about=""  xmlns:xmp="http://ns.adobe.com/xap/1.0/">
<xmp:CreatorTool>Microsoft® Word 2019</xmp:CreatorTool><xmp:CreateDate>2021-06-17T13:00:19+02:00</xmp:CreateDate><xmp:ModifyDate>2021-06-17T13:00:19+02:00</xmp:ModifyDate></rdf:Description>
<rdf:Description rdf:about=""  xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">
<xmpMM:DocumentID>uuid:C29344F5-3E78-414A-B4E3-775A853B1A0C</xmpMM:DocumentID><xmpMM:InstanceID>uuid:C29344F5-3E78-414A-B4E3-775A853B1A0C</xmpMM:InstanceID></rdf:Description>
                                                                                                    
                                                                                                    
                                                                          

长度65535当然比较特殊,是0xFFFF。显然,您在检索该字符串时使用的某些机制无法处理长度超过 65535 个字符的字符串。因此,您必须调查该字符串的来源。

考虑到 the question 你认为这个问题的延续,我假设你从中检索数据的 MS SQL 数据库中的字段限制为 65535 字节或你的数据库值检索代码将其削减。

在前一种情况下,您无能为力,数据库内容只是不完整。在后一种情况下,您只需启用数据库访问代码即可处理长字符串。