DOBON.NET DOBON.NETプログラミング掲示板過去ログ

変換して表示

分類:[.NET]

今回私はVB.NET学習でBinary型に変換して表示するという
ことをやりたいのですが、どうもうまくいきません基本的に
どうしたいかと言いますと、
1、テキストかなにかに適当に文を打てるようにし
2、その文を変換するためのボタンを作成し
3、ボタンを押すとバイナリデータに変換&表示できるように
したいのです。
バイナリデータで表示されると16進数で分が表示されるわけな
んですがどうもうまくいきません変換等に詳しい方ぜひ教えて
ください。よろしくお願いします。
■No1788に返信(水野さんの記事)
> 今回私はVB.NET学習でBinary型に変換して表示するという
> ことをやりたいのですが、どうもうまくいきません基本的に
> どうしたいかと言いますと、
> 1、テキストかなにかに適当に文を打てるようにし
> 2、その文を変換するためのボタンを作成し
> 3、ボタンを押すとバイナリデータに変換&表示できるように
> したいのです。
> バイナリデータで表示されると16進数で分が表示されるわけな
> んですがどうもうまくいきません変換等に詳しい方ぜひ教えて
> ください。よろしくお願いします。

簡単な関数でやろうとすれば、

1.Mid関数で1文字ずつ取得
2.Asc関数で文字コード(10進数)を取得
3.Hex関数で16進数に変換
4.TextBoxに表示

といったところでしょうか。
もしかするとVB.NETにもっと便利で簡単な関数があるかもしれません。
琴さん前回は大変お世話になりましたm(__)m解りやすく
解説までしていただけたので初心者の私でも理解しながら
完成させることができました☆
 今回キストの中に書いた文をバイナリに変換もするので
すが、最終的にファイル(csv/txt)→テキスト表示→Binary変換
→ファイルに保存です。私的にかなりハイレベルなのでここの
ところも詳しく教えていただけると光栄です☆
■No1790に返信(水野さんの記事)
> 琴さん前回は大変お世話になりましたm(__)m解りやすく
> 解説までしていただけたので初心者の私でも理解しながら
> 完成させることができました☆
>  今回キストの中に書いた文をバイナリに変換もするので
> すが、最終的にファイル(csv/txt)→テキスト表示→Binary変換
> →ファイルに保存です。私的にかなりハイレベルなのでここの
> ところも詳しく教えていただけると光栄です☆

ファイルの読み込み・表示およびファイルに保存は、

 ストリームを使ってテキストファイルを読み込む
 http://dobon.net/vb/dotnet/file/readfile.html

 ストリームを使ってテキストファイルに書き込む
 http://dobon.net/vb/dotnet/file/writefile.html

を用いてTextBoxとやり取りすればできると思います。

肝心の変換は、

 Dim I As Integer
 Dim sWork As String
 Dim sMid As String
 Dim iAsc As Integer
 Dim sHex As Integer

 sWork = ""
 For I = 1 To TextBox.Text.Length
  'TextBox.TextのI文字目を取得
  sMid = Mid$(TextBox.Text, I, 1)

  '文字コード(10進数)の取得
  iAsc = Asc(sMid)

  '16進数へ変換
  sHex = Hex(iAsc)

  '全角文字は4バイトとして変換されているので下2バイト分だけ変数に格納
  sWork = sWork & Microsoft.VisualBasic.Right(sHex, 4)
 Next

このようにすることでTextBoxの内容をBinary変換したものがsWorkに格納されているので、それをファイルに書き出せばいいと思います。
ただし、上記の変換だと、改行コードやCSVファイルなどの「"」「,」等も変換してしまうので、それらを残すのであれば特定の文字に限り変換しない処理を追加する必要があります。
いつもありがとうございますm(__)m
ファイルの書込み&読み込みは実はできていたので
琴サンから教えていただいた肝心な部分だけを
変換ボタンの中に打ってみたのですが、
'16進数へ変換
sHex = Hex(iAsc)
の部分でどうしても下記のよなエラーが出てきて
今一歩のところで実行できずにいます。変数を変える
くらいは自分で試してみましたがどうもうまくいきま
せんので少し教えてください。

エラーメッセージ
'System.InvalidCastException' のハンドルされていない例外が microsoft.visualbasic.dll で発生しました。

追加情報 : 文字列 "FFFF91E5" から型 'Integer' へのキャスト
が有効ではありません。
■No1792に返信(水野さんの記事)
> いつもありがとうございますm(__)m
> ファイルの書込み&読み込みは実はできていたので
> 琴サンから教えていただいた肝心な部分だけを
> 変換ボタンの中に打ってみたのですが、
> '16進数へ変換
> sHex = Hex(iAsc)
> の部分でどうしても下記のよなエラーが出てきて
> 今一歩のところで実行できずにいます。変数を変える
> くらいは自分で試してみましたがどうもうまくいきま
> せんので少し教えてください。
>
> エラーメッセージ
> 'System.InvalidCastException' のハンドルされていない例外が microsoft.visualbasic.dll で発生しました。
>
> 追加情報 : 文字列 "FFFF91E5" から型 'Integer' へのキャスト
> が有効ではありません。
>

ごめんなさい。変数の宣言に間違いがありました。

 ×:Dim sHex As Integer
   ↓
 ○:Dim sHex As String

これで大丈夫だと思います。 失礼しました。
  • 題名: Re[6]: 変換して表示
  • 著者: 水野
  • 日時: 2003/12/11 15:00:42
  • ID: 1794
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
自分で変数変換してたら、うまくいってました☆
すみませんm(__)mありがとうございました良い勉強に
なりました。6.0を少しかじり.NETに移ったらすごく初心者に
なっていました。またなにかありましたらお力を貸してくだ
さいm(__)m
解決済み!
おかげさまで16進数の変換はうまくいってますが、琴さんの
プログラムを内容逆バージョンで変換し直せば通常の文に戻るか
と思い試してみたのですが、16進数のEとかFが数字としてではなく
文字として認識されてしまっているためか文を元に戻す処理ができ
ませんこれができれば今回は一様全部完成となります。
少しその部分ご指導くださいm(__)m
きいぼーです。
琴さんのサンプルで作成した16進数は文字列ですので、
2文字ずつ変換していくのはどうでしょう。
2文字の1文字目*16+2文字目=10進数となります。
例  "FF"なら16*15+15=255
   "1F"なら16*1 +15=31

1文字ずつ文字が
Fなら15
Eなら14
として計算させます。
■No1804に返信(きいぼーさんの記事)
> きいぼーです。
> 琴さんのサンプルで作成した16進数は文字列ですので、
> 2文字ずつ変換していくのはどうでしょう。
> 2文字の1文字目*16+2文字目=10進数となります。
> 例  "FF"なら16*15+15=255
>    "1F"なら16*1 +15=31
>
> 1文字ずつ文字が
> Fなら15
> Eなら14
> として計算させます。

変換元するの文字が全て半角であれば、きいぼーさんの方法でできると思います。
しかし、全角文字が入っていると4文字で変換をかけないとおかしくなってしまいます。
(「O(全角オー)」を16進数に変換すると「826E」ですが、2文字ずつ変換をかけると「n(82:Nothing 6E:n)」になってしまいます)
始めに2文字取得して、それが半角文字なのか全角文字なのかを判断する必要があると思われます。
処理は時間があるときに少し考えてみます。

※1791の私のサンプルですが、改行コード(13)等の特殊コードを変換すると"D"などと1文字に変換されてしまいます。
 これでは変換結果がおかしくなってしまうので、1文字だった場合は頭に"0"を付けて2文字になるようにする必要があります。

 If sHex.Length < 2 then
  sHex = "0" & sHex
 End If
キイボーさん有難うございます☆ですが琴さんが言ったとおり
全角が多くなかなかうまくぜきませんでした。変数エラー等も
出ていたので(私のヘッポコプログラムの組かたのせいです)
いろいろ試しているのですが16進数から元の文にもどす事がで
きませんせっかく琴さんやキイボーさん達から指導していただ
きここまできたので最後の処理を終えて完成させたいと思いま
すので完成までお付き合いください宜しくお願いしますm(__)m
■No1811に返信(水野さんの記事)
> キイボーさん有難うございます☆ですが琴さんが言ったとおり
> 全角が多くなかなかうまくぜきませんでした。変数エラー等も
> 出ていたので(私のヘッポコプログラムの組かたのせいです)
> いろいろ試しているのですが16進数から元の文にもどす事がで
> きませんせっかく琴さんやキイボーさん達から指導していただ
> きここまできたので最後の処理を終えて完成させたいと思いま
> すので完成までお付き合いください宜しくお願いしますm(__)m

簡単な動作確認しか行っていませんが、一応動いたので。

 Dim I As Integer
 Dim sWork As String
 Dim sMid As String
 Dim iAsc As Integer
 Dim sHex As String
 Dim iAsc_Low As Integer
 Dim sHex_Low As String

 sWork = ""
 For I = 1 To TextBox.Text.Length Step 2
  '2文字取得
  sHex = Mid(TextBox.Text, I, 2)

  '1文字ずつ10進数に変換
  iAsc = Uri.FromHex(Microsoft.VisualBasic.Left(sHex, 1)) * 16
  iAsc = iAsc + Uri.FromHex(Microsoft.VisualBasic.Right(sHex, 1))

  '変換後の10進数が128(&H80)以上だったら全角文字と判断する
  If TextBox.Text.Length > I And iAsc > &H80 Then
   '読み込み位置を進める
   I = I + 2

   '下位2文字取得
   sHex_Low = Mid(TextBox.Text, I, 2)

   '1文字ずつ10進数に変換
   iAsc_Low = Uri.FromHex(Microsoft.VisualBasic.Left(sHex_Low, 1)) * 16
   iAsc_Low = iAsc + Uri.FromHex(Microsoft.VisualBasic.Right(sHex_Low, 1))

   '全角文字コードの算出
   iAsc = iAsc * (16 ^ 2) + iAsc_Low
  End If

  '文字コードを文字に変換
  sMid = Chr(iAsc)

  '最終的な文字列変数へ格納
  sWork = sWork & sMid
 Next

これで変換前の文字列がsWorkに格納されていると思います。

※注
 ・このソースコードは手打ちですので、タイプミスがある可能性があります。 あったらごめんなさい。
 ・全て確認していないので、もしかすると変換できない全角文字・特殊文字があるかもしれません。
 ・.NETにもっと簡単な関数があるかもしれません。
2003/12/13(Sat) 05:29:13 編集(投稿者)

■No1788に返信(水野さんの記事)
> 1、テキストかなにかに適当に文を打てるようにし
> 2、その文を変換するためのボタンを作成し
> 3、ボタンを押すとバイナリデータに変換&表示できるように
> したいのです。

#次回からは、「Title」をもう少し分かりやすい題にしてください。

他のみなさんからの回答で解決できたかもしれませんが、参考までに別の方法(多分)を紹介します。ここで使われているテクニックについては、次のページを参考にしてください。

・文字列を文字コードを指定してバイト型配列のデータに変換する
http://dobon.net/vb/dotnet/string/getencoding.html

・MD5ハッシュ値を計算する
http://dobon.net/vb/dotnet/string/md5.html

ここでは、Button1を押すと、TextBox1の内容を16進数の文字列に変換してTextBox2に表示し、また戻しています。

Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button2.Click
TextBox2.Text = Encode(TextBox1.Text)
TextBox1.Text = Decode(TextBox2.Text)
End Sub

'文字列から16進数の文字列へ
Public Function Encode(ByVal str As String) As String
'文字列を配列に変換
Dim bs As Byte()
bs = System.Text.Encoding.UTF8.GetBytes(str)
'Byte配列を16進数文字列に
Return BitConverter.ToString(bs).Replace("-", "")
End Function

'16進数の文字列から文字列へ
Public Function Decode(ByVal str As String) As String
'Byte配列の作成
Dim bs As Byte()
ReDim bs(str.Length \ 2 - 1)
'バイト配列に変換
Dim i As Integer
For i = 0 To bs.Length - 1
bs(i) = Byte.Parse(str.Substring(i, 2), _
Globalization.NumberStyles.AllowHexSpecifier)
Next
'文字列に変換
Return System.Text.Encoding.UTF8.GetString(bs)
End Function
琴さん、管理人さんご回答有難うございござます。
両方とも試してみました結果、琴さんの書いていただいた
プログラムは'1文字ずつ10進数に変換
  iAsc = Uri.FromHex(Microsoft.VisualBasic.Left(sHex, 1)) * 16
  iAsc = iAsc + Uri.FromHex(Microsoft.VisualBasic.Right(sHex, 1))
の所でdigit系エラーがでてしまい、低レベルな私が直そうとしたのですが、今のところ
直っておりません^^;難しいです・・琴サンはあんな高度プログラムをすぐになんでできるのでしょうf^^;?
その後管理人さんのを新しいファイルで試してみたらText1"テスト"と書き実行
するとText1に"88n8"とText2に"E38386E382B9E38388"と出ます。
"テスト"→変換ボタン→"836583588367"→表示戻しボタン→"テスト"としたいので
私的にはまだ改良が必要です。と言いつつ改良をしているのですが、解決プログラムが
まだ解らないので何か良い提案がありましたら宜しくお願いいたしますm(__)m
■No1836に返信(水野さんの記事)
> 琴さん、管理人さんご回答有難うございござます。
> 両方とも試してみました結果、琴さんの書いていただいた
> プログラムは'1文字ずつ10進数に変換
>   iAsc = Uri.FromHex(Microsoft.VisualBasic.Left(sHex, 1)) * 16
>   iAsc = iAsc + Uri.FromHex(Microsoft.VisualBasic.Right(sHex, 1))
> の所でdigit系エラーがでてしまい、低レベルな私が直そうとしたのですが、今のところ
> 直っておりません^^;難しいです・・琴サンはあんな高度プログラムをすぐになんでできるのでしょうf^^;?
> その後管理人さんのを新しいファイルで試してみたらText1"テスト"と書き実行
> するとText1に"88n8"とText2に"E38386E382B9E38388"と出ます。
> "テスト"→変換ボタン→"836583588367"→表示戻しボタン→"テスト"としたいので
> 私的にはまだ改良が必要です。と言いつつ改良をしているのですが、解決プログラムが
> まだ解らないので何か良い提案がありましたら宜しくお願いいたしますm(__)m

digit系エラーですか…恐らくUri.FromHexに"0〜9、A〜F"以外の文字が入ってきているのかもしれないですね。
No1815のソースで操作しているTextBoxの内容は、No1791で変換された16進数コード("836583588367"等)でないとエラーが出るはずです。
一度エラーが出ている部分にブレークポイントを作成して、TextBox.Textの内容を確認してみてもらえるでしょうか?

No1815のソースに一部間違いがありましたので修正個所を記します。
(全角文字の下位2バイトを変換する部分です)

   '1文字ずつ10進数に変換
   iAsc_Low = Uri.FromHex(Microsoft.VisualBasic.Left(sHex_Low, 1)) * 16
   iAsc_Low = iAsc + Uri.FromHex(Microsoft.VisualBasic.Right(sHex_Low, 1))
    ↓
   '1文字ずつ10進数に変換
   iAsc_Low = Uri.FromHex(Microsoft.VisualBasic.Left(sHex_Low, 1)) * 16
   iAsc_Low = iAsc_Low + Uri.FromHex(Microsoft.VisualBasic.Right(sHex_Low, 1))
返信有難うございます。一様ブレイクは前から使ってはいるのですが
”テスト(836583588367)”をText1に入れてiAsc_Lowに入る値が
"101"→"88"→止まるみたいな感じですf^^;
私的には宣言や文の位置をずらしたりくらいしか試してないのですが、
現在でもなおっていませんね(;.;)ご意見お願いします☆
■No1838に返信(水野さんの記事)
> 返信有難うございます。一様ブレイクは前から使ってはいるのですが
> ”テスト(836583588367)”をText1に入れてiAsc_Lowに入る値が
> "101"→"88"→止まるみたいな感じですf^^;
> 私的には宣言や文の位置をずらしたりくらいしか試してないのですが、
> 現在でもなおっていませんね(;.;)ご意見お願いします☆

エラーが出た時点のiAsc_LowとsHex_Lowの内容が気になりますね。
こちらでは正常に動いているので再現しなくて原因がわからない状態です。

ちょっとコンパクトにしたソースも試してみてください。(やっていることは全く同じです)
※TextBox1に入っている16進数コードを文字コードに変換してTextBox2に表示するようにしています。
※TextBox1に「836583588367」と入力しButton1を押すと、TextBox2に「テスト」と表示されます。

 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  Dim I As Integer
  Dim sWork As String
  Dim iAsc As Integer
  Dim sHex1 As String
  Dim sHex2 As String

  sWork = ""
  If TextBox1.Text <> "" Then
   For I = 1 To TextBox1.Text.Length Step 2
    sHex1 = Mid$(TextBox1.Text, I, 1)
    sHex2 = Mid$(TextBox1.Text, I + 1, 1)
    iAsc = (Uri.FromHex(sHex1) * 16) + Uri.FromHex(sHex2)
    If TextBox1.Text.Length >= (I + 2) And iAsc > &H80 Then
     I = I + 2
     sHex1 = Mid$(TextBox1.Text, I, 1)
     sHex2 = Mid$(TextBox1.Text, I + 1, 1)
     iAsc = iAsc * (16 ^ 2) + (Uri.FromHex(sHex1) * 16) + Uri.FromHex(sHex2)
    End If
    sWork = sWork & Chr(iAsc)
   Next
  End If

  TextBox2.Text = sWork
 End Sub
有難うございます☆☆できました。何がいけなかったのか
よくわかりませんf^^;が最後に書かせてもらったプログラム
で完動しました♪本当に最後まで有難うございましたm(__)m
これからの資料的にも大変助かりました。これから文の細かい
意味などを理解して今度は私が琴さんのようにアドバイスでき
るようにしたいです。また何かありましたらお力を貸してくだ
さいm(__)m
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板