0

zlibを使用して文字列を圧縮しようとしています(現在の 1.2.3 バージョンの zlib と zlib 1.1.3 でこのコードを試しました)。 日本語のマシンで実行しない限り、私のコードは正しく動作します。ファイルを圧縮した後、暗号化しています。復号化は成功しますが、uncompress の呼び出しは -3 を返します (Z_DATA_ERROR入力データが破損していることを意味します)。エラーがログに記録されていないため、例外がスローされておらず、圧縮関数が 0 を返していることがわかります ( Z_OK、機能したことを意味します)。

したがって、問題は、行 " " または行 " ."のsCompressedいずれかで文字列の整合性が失われていることだと思います あるいは、VB6 がの呼び出し中にの内容に役立つ何か愚かなことをしている可能性があります。私は、この関数の戻り値が後で壊れていないことを知っています.sCompressed = Left(sCompressed, lcompressedlen)encryptedData.Content = sCompressedsCompressedcompress

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

結論:
不審な文字セットを備えたマシンで実行すると、プログラムにエラー メッセージを表示して終了させることになりました。このバグがまだいくつかの設定に存在する可能性が非常に高く、エラーをトリガーする一部の設定には存在しない可能性もあります。ただし、ターゲット オーディエンスは英語を話す人であるため、Turkey Test に合格することは、実際にこれにより多くの時間を費やすことを正当化するほど重要ではありません。

4

2 に答える 2

2

バイト配列を渡すつもりなら、文字列の使用をやめますか?

もちろん、ここで行っているように文字列を使用すると、自動的に ANSI 変換とデータの再コピーが行われます。

于 2009-08-27T18:25:43.377 に答える
0

ボブは正しいです。これらは彼の答えに対する私の脚注です。私は zlib にまったく慣れていないことに注意してください。 Declareforを使用して DLL を呼び出していると仮定していますcompress

Byte 配列の代わりに String を使用しても、ANSI 変換を回避できるわけではありません。多くの場合、VB6 が暗黙的に変換を行い、それを制御できないことを意味します。たとえば、Declareステートメントで DLL を呼び出して文字列を渡す場合などです。

圧縮から返されたバイトのマジック シーケンスが、日本語コード ページの有効な "ANSI" 文字列ではない可能性があります。一部の文字シーケンスは、そのコード ページのMSDN テーブルで定義されていません。ステートメントを使用して DLL を呼び出し、Declare文字列が sCompressed に返されることを期待している場合、その DLL は有効な "ANSI" 文字列を対応するバッファーに書き込むことをお勧めします。無効なバイト シーケンスを書き込むと、何かが起こる可能性があります。また、中国語 (936 および 950) と韓国語 (949) でも問題が発生します。

あなたが説明していることはよく起こるかもしれません.whenがcompress無効なバイトシーケンスを返すと、エラーが報告されずに「Unicode」文字列に変換される可能性があります-おそらく、バイトシーケンスの最初の部分に一致する切り捨てられたUnicode文字列です。次に、後で解凍しようとすると、その Unicode 文字列が ANSI 文字列に変換されて元のバイト シーケンスと一致しなくなります。それはおそらく一致することはできません。有効な文字列ではない一連のバイトとして、コード ページ 932 の "ANSI" 文字列に変換される可能性のある Unicode 文字列はありません。

VB6 での Unicode の実装であるひどい寄せ集めについての詳細情報を次に示します。Michael Kaplan の優れた本Internationalization With Visual Basicからの無料の章です。

また、文字列内の文字数と、文字列が ANSI 表現で占めるバイト数を混同しているのではないかと思います (私は と を疑っていlStringLenますlcompressedlen)。繰り返しますが、日本語は 2 バイト文字セットであるため、ANSI 文字列は N 文字に対して最大 2*N バイトを使用する場合があります。

于 2009-09-02T15:13:09.347 に答える