0

我正在尝试通过使用zlib压缩字符串(我已经使用当前 1.2.3 版本的 zlib 和 zlib 1.1.3 尝试了此代码)。 我的代码可以正常工作,除非在日本机器上运行。压缩文件后,我正在对其进行加密。解密成功,但对 uncompress 的调用返回 -3(Z_DATA_ERROR,表示输入数据已损坏)。由于没有记录错误,我知道没有抛出异常,并且压缩函数返回 0 ( Z_OK,表示它有效)。

因此,我怀疑问题是sCompressed字符串在 " sCompressed = Left(sCompressed, lcompressedlen)" 行或 " 行 "上失去了完整性encryptedData.Content = sCompressed或者, VB6可能在sCompressed调用compress. 我知道这个函数的返回值以后不会被破坏,因为那会破坏解密,这工作正常。

Public Function EncryptString(ByVal Definition As String) As String
On Error GoTo ErrorHandler
    Dim encryptedData As New CAPICOM.encryptedData
    encryptedData.SetSecret KEY_CONST
    Dim lStringLen As Long
    Dim lcompressedlen As Long
    Dim sCompressed As String
    Dim lReturn As Long
    Dim tstpost As String
    lStringLen = Len(Definition)
    lcompressedlen = (lStringLen * 1.01) + 13
    sCompressed = Space(lcompressedlen)
    lReturn = compress(sCompressed, lcompressedlen, Definition, lStringLen)
    If lReturn <> 0 Then
        sCompressed = "Error: " & CStr(lReturn)
        '<LOG ERROR>'
    Else
        sCompressed = Left(sCompressed, lcompressedlen)
    End If
    encryptedData.Content = sCompressed
    encryptedData.Algorithm.Name = CAPICOM_ENCRYPTION_ALGORITHM_3DES
    EncryptXmlString = encryptedData.Encrypt
Exit Function
ErrorHandler:
    '<LOG ERROR>'
    Resume Next
End Function

结论:
如果在具有可疑字符集的机器上运行,我最终让程序给出错误消息并退出。这个错误很可能仍然存在于一些设置中,也很可能在某些触发错误的设置中不存在。然而,由于目标受众是说英语的人,通过土耳其测试并不重要,不足以证明实际上花更多时间在这方面是合理的。

4

2 回答 2

2

当你的意思是传递一个字节数组时停止使用字符串?

当然,当您像这里一样使用字符串时,您将获得自动 ANSI 转换和数据重新复制。

于 2009-08-27T18:25:43.377 回答
0

鲍勃是对的。这些只是我对他的回答的脚注。请注意,我对 zlib 完全不熟悉 - 我假设您正在使用Declarefor调用 DLL compress

使用 String 而不是 Byte 数组并不意味着您可以避免 ANSI 转换。它通常只是意味着 VB6隐式进行转换并且您无法控制它 - 例如,当您使用Declare语句调用 DLL 并传递字符串时。

从压缩返回的神奇字节序列可能不是日语代码页上的有效“ANSI”字符串。该代码页的MSDN 表中未定义某些字符序列。如果您使用语句调用 DLLDeclare并期望将字符串返回到 sCompressed,则该 DLL 最好将有效的“ANSI”字符串写入相应的缓冲区。如果它写入无效的字节序列,任何事情都可能发生。中文(936 和 950)和韩文(949)也会有问题。

您所描述的很可能会发生:当compress返回无效的字节序列时,可能会转换为“Unicode”字符串而不会报告错误 - 可能是与字节序列的第一部分匹配的截断 Unicode 字符串。然后,当您稍后尝试解压缩时,该 Unicode 字符串将转换回 ANSI 字符串,并且它与您开始的原始字节序列不匹配。它不可能匹配。在代码页 932 上,没有可能的 Unicode 字符串可以转换为“ANSI”字符串作为无效字符串的字节序列。

这里有一些关于 VB6 的 Unicode 实现的可怕混杂的更多信息:Michael Kaplan 的优秀书籍Internationalization With Visual Basic的免费章节

我还怀疑您可能会将字符串中的字符数与其在 ANSI 表示中占用的字节数混淆(我怀疑lStringLenand lcompressedlen)。同样,日语是一个双字节字符集,因此对于 N 个字符,ANSI 字符串最多可能占用 2*N 个字节。

于 2009-09-02T15:13:09.347 回答