- PR -

文字列の比較で矛盾が生じます。

投稿者投稿内容
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2007-05-12 16:57
引用:

http://msdn2.microsoft.com/ja-jp/library/system.security.cryptography.rijndaelmanaged(vs.80).aspx

ここのサンプルで紹介されているコードの最後に



ヤクザなサンプルですなぁ。
fromEntrypt が encrypted.Length で作られていますが、encrypted は Rijndael のようなブロック暗号技術では元データよりも(大抵)数バイト大きくなります。
で、その後ろの数バイト分は、csDecrypt.Read では埋まりません。データは 0 が残ります。
ところがそれを無視して、その 0 も含めて textConverter.GetString しちゃってるので、後ろに \0 文字が挿入されちゃうんですね。
CompareTo を使った場合、末尾の \0 は無視して比較を行うようなので等しいと判断されるんでしょう。

textConverter で GetString する際、正しい範囲を指定してやればいいでしょう。GetString にはそのためのオーバーロード(同じ名前で引数が違うメソッド)が定義されています。
読み込んだバイト数は、Read メソッドが返してくれます。
フィーバー
常連さん
会議室デビュー日: 2006/08/30
投稿数: 22
投稿日時: 2007-05-12 19:42
Dim i As Integer = 0
For Each bt As Byte In fromEncrypt
i = i + 1
If bt.ToString() = 0 Then
Exit For
End If
Next bt
roundtrip = textConverter.GetString(fromEncrypt, 0, i - 1)

これで良いでしょうか?

自分なりに考えたんですが、

読み込んだバイト数は、Read メソッドが返してくれます。

の部分が理解できなくて、こんなコードになってしまいました。
正直効率が悪そうな気がしますが、一応動きました。
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-05-13 03:10
引用:

フィーバーさんの書き込み (2007-05-12 19:42) より:
Dim i As Integer = 0
For Each bt As Byte In fromEncrypt
i = i + 1
If bt.ToString() = 0 Then
Exit For
End If
Next bt
roundtrip = textConverter.GetString(fromEncrypt, 0, i - 1)



roundtrip = textConverter.GetString(fromEncrypt, 0, Array.IndexOf(fromEncrypt, 0) - 1)

でよいのでは?
#・テストしていません。
#・もっといい方法があるかも
ぽぴ王子
ぬし
会議室デビュー日: 2006/03/24
投稿数: 475
お住まい・勤務地: お住まい:城・勤務地:城
投稿日時: 2007-05-13 08:53
引用:

フィーバーさんの書き込み (2007-05-12 16:33) より:

ブレークポイントの設定をしてみましたが、1バイト単位での見方がわかりませんでした。
ローカルっていう所で問題と思われる所を発見いたしました。
例 文字列 a
暗号化前:"a"
復号化後:"a
のように"a"の最後の"が付いていませんでした。


私も見てみましたが、確かに String 型変数を1バイト単位(あるいは1文字単位)
でローカルタブから見るのはできませんね。曖昧な情報を提供してしまってすい
ません。
ほぼ解決されていますが、原因としては Hongliang さんが書かれているように、
復号化した文字列の最後に \0 文字が追加されていることだと思います。

引用:

暗号化・復号化の処理は、検索して見つけたコードを少し改良した程度のものです。

http://msdn2.microsoft.com/ja-jp/library/system.security.cryptography.rijndaelmanaged(vs.80).aspx


この情報が最初からあると、もっと話がすすめやすかったかもしれませんね
_________________
ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。
フィーバー
常連さん
会議室デビュー日: 2006/08/30
投稿数: 22
投稿日時: 2007-05-13 13:45
教えていただいたコード
roundtrip = textConverter.GetString(fromEncrypt, 0, Array.IndexOf(fromEncrypt, 0) - 1)
を実行すると、以下のエラーが発生いたしました。

System.ArgumentOutOfRangeException はハンドルされませんでした。
Message="負の値ではない数値が必要です。
パラメータ名: byteCount"
ParamName="byteCount"
Source="mscorlib"


ぽぴ王子様
暗号化・復号化の処理は、言語・ソフトの開発・発売元のマイクロソフトの
ものでしたので、100%信じきっていましたので、今回のような不都合?が
あるとは、良い勉強になりました。
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-05-14 09:44
引用:

フィーバーさんの書き込み (2007-05-13 13:45) より:
教えていただいたコード
roundtrip = textConverter.GetString(fromEncrypt, 0, Array.IndexOf(fromEncrypt, 0) - 1)
を実行すると、以下のエラーが発生いたしました。

System.ArgumentOutOfRangeException はハンドルされませんでした。
Message="負の値ではない数値が必要です。
パラメータ名: byteCount"
ParamName="byteCount"
Source="mscorlib"



最後の-1がいらなかったですね(^^;

roundtrip = textConverter.GetString(fromEncrypt, 0, Array.IndexOf(fromEncrypt, 0))

がたぶん正しいです。(あいかわらず未検証です)
が、私の言いたいことはArray.IndexOfを使えばよいのでは?
という提案ですので、書いてある内容の意味を理解してほしいところです。

<修正>
・閉じタグがおかしかったのを修正
</修正>
<追記>
・フィーバーさんの提示のソースから、
バイト配列から値が0の箇所のインデックスを知ることができればOKかな?
と思ったのですが、違ったのでしょうかね・・・
MSサンプルの方は読んでいないので、間違ったアドバイスをしているのかもしれません。
申し訳ないです。
</追記>

[ メッセージ編集済み 編集者: よねKEN 編集日時 2007-05-14 14:58 ]
フィーバー
常連さん
会議室デビュー日: 2006/08/30
投稿数: 22
投稿日時: 2007-05-14 14:49
教えて頂いておいて、申し訳ありませんが、

Dim i As Integer = 0
For Each bt As Byte In fromEncrypt
i = i + 1
If bt.ToString() = 0 Then
Exit For
End If
Next bt
roundtrip = textConverter.GetString(fromEncrypt, 0, i - 1)


MessageBox.Show(Array.IndexOf(fromEncrypt, 0) & "_" & i)
を追加してみて値を取得してみたところ、
-1_86と出ましたので、
Array.IndexOf(fromEncrypt, 0) は-1となりますので、エラーになると思います。


それで、他にコードを考えてみました。
roundtrip = textConverter.GetString(fromEncrypt).Trim(ChrW(0))
です。
ひろれい
ぬし
会議室デビュー日: 2006/03/02
投稿数: 486
お住まい・勤務地: 万博開催地
投稿日時: 2007-05-14 15:35
引用:

フィーバーさんの書き込み (2007-05-14 14:49) より:

教えて頂いておいて、申し訳ありませんが、

Dim i As Integer = 0
For Each bt As Byte In fromEncrypt
i = i + 1
If bt.ToString() = 0 Then
Exit For
End If
Next bt
roundtrip = textConverter.GetString(fromEncrypt, 0, i - 1)


MessageBox.Show(Array.IndexOf(fromEncrypt, 0) & "_" & i)
を追加してみて値を取得してみたところ、
-1_86と出ましたので、
Array.IndexOf(fromEncrypt, 0) は-1となりますので、エラーになると思います。


それで、他にコードを考えてみました。
roundtrip = textConverter.GetString(fromEncrypt).Trim(ChrW(0))
です。



  CryptoStream.Read メソッド

普通に、

コード:
        Dim csDecrypt As New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)

        fromEncrypt = New Byte(encrypted.Length) {}

        'Read the data out of the crypto stream.
        Dim hoge As Integer = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length)

        'Convert the byte array back into a string.
        roundtrip = textConverter.GetString(fromEncrypt, 0, hoge)



じゃダメなんでしょうか?

Hongliang さんが「読み込んだバイト数は、Read メソッドが返してくれます」と教えてくれていますが・・・

スキルアップ/キャリアアップ(JOB@IT)