如何在日本机器上使用zlib?

时间:2009-08-27 17:49:40

标签: unicode vb6 internationalization zlib

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

因此,我怀疑问题是sCompressed字符串在“sCompressed = Left(sCompressed, lcompressedlen)”行或“encryptedData.Content = sCompressed”行中失去了完整性。或者,在调用sCompressed期间,VB6可能正在对compress的内容执行某些操作 stupid 。我知道这个函数的返回值以后没有被破坏,因为这会破解解密,这很好。

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

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

2 个答案:

答案 0 :(得分:2)

如果要传递Byte数组,请停止使用String吗?

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

答案 1 :(得分:0)

Bob是right。这些只是他回答的脚注。请注意,我对zlib完全不熟悉 - 我假设您使用Declarecompress调用DLL。

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

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

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

这里有一些关于可怕的混蛋的更多信息,这是VB6的Unicode实现:来自Michael Kaplan的优秀书free chapter

Internationalization With Visual Basic

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