バイナリデータを変換するには2?


たか  2004-05-12 00:04:02  No: 83310

大変申し訳ありませんが、前回と同様の質問ですが、
前回の質問は、分かりづらかったため新規に質問をします。

DIM aaa As Byte()
DIM bbb As String

aaa(0) = "&H"+"E2"
aaa(1) = "&H"+"E2"
この後、aaaを文字列型にしたい。

bbb = aaa ? ← どのように文字列型にすればよろしいでしょうか?

aaa(0),aaa(1)の値をバイナリデータとして【文字列型】で
返すにはどのようにしたらよろしいのでしょうか?
また、変換した、文字列型のデータをバイナリエディタを
使用した時『E2』『E2』となるようにしたいのですが・・・。

宜しくお願い新ます。


魔界の仮面弁士  2004-05-12 01:24:34  No: 83311

> DIM aaa As Byte()
この表現は…VB.NETですね。

> aaa(0) = "&H"+"E2"
左辺がバイト型、右辺が文字列型になってしまっていますね。
明示的に型変換を行いましょう。

> この後、aaaを文字列型にしたい。
質問内容が曖昧すぎます。もう少し具体的な仕様を教えてください。

今回の場合、
>  aaa(0) = "&H"+"E2"
>  aaa(1) = "&H"+"E2"
この {&HE2, &HE2} というデータから、どのような文字列を得たいのでしょう?

16進数で並べた、「e2e2」という文字列ですか?
それとも、Chr(&HE2E2)にて得られる「粐」という文字ですか?
あるいは、EUCコードで E2E2に相当する、「矜」の文字でしょうか?
それとも、もっと別の文字列を得たいのでしょうか?


のん  2004-05-12 01:36:42  No: 83312

つまり&HE2E2のシフトJISコードを持つ「粐」という文字が取得できればよいのでしょうか?
であればChr関数で実現できます

Dim aaa(1)  As Byte
Dim bbb     As String
  
aaa(0) = &HE2
aaa(1) = &HE2
  
bbb = Chr((CLng(aaa(0)) * &H100& And &HFF00&) + (CLng(aaa(1)) And &HFF&))

バイト型は符号付なので符号を消して2バイトを合成するところがポイントでしょうか


のん  2004-05-12 01:44:16  No: 83313

あ。。上のはVBでの話です
VB.NETは分からないので参考程度にして下さい。


魔界の仮面弁士  2004-05-12 01:48:30  No: 83314

バイト配列を、どの文字コードと認識させるかによって、得られる文字列は異なります。

これは、逆に、文字列をバイト配列に変換する際も同様です。
元の文字列を、どの文字コードとしてバイト配列に変換するかによって、
得られるバイトデータは異なってきます。

> また、変換した、文字列型のデータをバイナリエディタを

というか、バイナリデータとして吐き出したいのであれば、
わざわざ文字列に変換せず、バイト配列のまま扱えば良いのでは? (^-^;

> 使用した時『E2』『E2』となるようにしたいのですが・・・。

とりあえず、E2 E2なバイトデータを、任意の文字コードで
文字列変換するサンプル。(VB6版)
=======
Const adTypeBinary = 1
Const adTypeText = 2
Dim St As Object
Set St = CreateObject("ADODB.Stream")
St.Open

'バイナリが E2 E2 なデータを
Dim B(1) As Byte
St.Type = adTypeBinary
B(0) = &HE2
B(1) = &HE2
St.Write B

'Shift_JISの文字列として得る
Dim S1 As String
St.Position = 0
St.Type = adTypeText
St.Charset = "Shift_JIS"
S1 = St.ReadText()
MsgBox S1, , "Shift_JIS"

'EUC-JPの文字列として得る
Dim S2 As String
St.Position = 0
St.Type = adTypeText
St.Charset = "euc-jp"
S2 = St.ReadText()
MsgBox S2, , "euc-jp"

St.Close
Set St = Nothing


魔界の仮面弁士  2004-05-12 01:57:35  No: 83315

> とりあえず、E2 E2なバイトデータを、任意の文字コードで
> 文字列変換するサンプル。(VB6版)

今度は、VB.NET版。

=================
Dim Enc As System.Text.Encoding

'バイナリが E2 E2 なデータを
Dim B() As Byte = New Byte(1) {&HE2, &HE2}

'Shift_JISの文字列として得る
Dim S1 As String= Enc.GetEncoding("Shift_JIS").GetString(B)

'EUC-JPの文字列として得る
Dim S2 As String= Enc.GetEncoding("EUC-JP").GetString(B)

'16進数表記の文字列として得る
Dim S3 As String = System.BitConverter.ToString(B)


たか  2004-05-12 02:13:57  No: 83316

魔界の仮面弁士様、早速のご返答ありがとうございます。
質問内容が曖昧すぎて大変申し訳ありません。
>『DIM aaa As Byte()』
上記表現ですがこちら側のミスです。
正確には、『Dim aaa As Byte()』です。VB5.0(SP3)を使用しています。
>この後、aaaを文字列型にしたい。
「粐」という文字を得たかったのですが、StrConv関数で取得できました。
バイナリエディタで確認しても『E2』『E2』となりました。
質問が変わってしまいますが、 

Dim aaa As Byte()
Dim bbb As String

aaa(0) = &HE2
bbb = StrConv(aaa,vbUnicode) 

という記述から、「・」という文字列を取得したのですが、
バイナリエディタで確認した所、『00』となってしまいます。
バイナリデータで16進数の『E2』を返したいのですが、
『E2』とするような方法がありますでしょうか?


魔界の仮面弁士  2004-05-12 02:47:01  No: 83317

> 正確には、『Dim aaa As Byte()』です。VB5.0(SP3)を使用しています。

????
VB5であれば、なおの事、その文法は使えませんけど……。

> bbb = StrConv(aaa,vbUnicode) 

vbUnicodeは、指定されたデータをShift_JISのバイナリと見なして、
 Shift_JIS → Unicode 変換を行うための指定です。

逆にvbFromUnicodeは、指定されたデータがUnicodeのバイナリと見なして、
 Unicode → Shift_JIS 変換を行おうための物です。

つまりこの場合、変数aaaが Shift_JISとして正しい形式になっていなければ、
変換は正しく行われません。(データが化けてしまいます)

E2 E2 というバイト データは、Shift_JISとして正しい形式ですが、
E2 というバイトデータだと、Shift_JIS としては正しい形式ではありません。
そのため、正しく処理されなかったのでしょう。

これは、StrConv関数による変換の場合だけではなく、
Asc, Chr, AscW, ChrW関数による変換の場合にも言える事です。
(正しいShift_JIS文字/Unicode文字でないと、変換時に化ける事があります)


たか  2004-05-12 19:47:06  No: 83318

魔界の仮面弁士様、ご返答ありがとうございます。

>E2 E2 というバイト データは、Shift_JISとして正しい形式ですが、
>E2 というバイトデータだと、Shift_JIS としては正しい形式ではありません。
>そのため、正しく処理されなかったのでしょう。

E2というバイトデータをどうしても使用したいのですが、
E2というバイトデータをShift_JISとして正しい形式にする方法は、
ありませんでしょうか?

また、上記の回避案などがありましたら教えていただきたいのですが。


魔界の仮面弁士  2004-05-12 20:33:22  No: 83319

>> 正確には、『Dim aaa As Byte()』です。VB5.0(SP3)を使用しています。
「Dim aaa() As Byte」なら、VB5というのも納得できるのですけれどね。
『As Byte()』という記述では、やはり.NETを連想してしまいます。(^_^;)

# VB6なら、「Function aaa() As Byte()」なんていう記述もできますけど、
# VB5では使えなかったと思いますし。

> E2というバイトデータをどうしても使用したいのですが、
# お互い(質問者と回答者)の認識が、どこかずれているのかな?

Shift_JISが、どういう文字コード体系であるかは御存知ですよね?
バイトの並びによって、1バイト文字と、2バイト文字が混在する文字コードです。

バイトデータでいうと、
  21〜7E: JIS X 0201 ローマ字
  A1〜DF: JIS X 0201 片仮名
にあるものが、1バイトで1文字を表す事になっています。

そして、81〜9F, E0〜EF の範囲が 2バイト文字の先導バイトです。
これらのデータは、直後に 40〜7E, 80〜FC の範囲のデータを伴い、
2バイトで1文字を表す仕様となっています。

……さて。元の質問に話を戻しますと。

> E2というバイトデータをShift_JISとして正しい形式にする方法は、
> ありませんでしょうか?

今回、上記に説明しました Shift_JIS の仕様を見てください。
[E2]というのは、1バイト文字ではなく、2バイト文字の一部です。
つまり[E2]1バイトだけでは、Shift_JIS の文字にはならないのです。

Shift_JISとして扱われるには、E2 40(磧)、E2 E2(粐)、81 E2(≫)など、
2バイト単位で指定される必要があります。

> また、上記の回避案などがありましたら教えていただきたいのですが。
回避策といわれても、最終的に「何がしたいのか」がさっぱりわからないので…。

やりたい事が、たとえば『E2という1バイトのデータをファイルに吐き出し、
それをバイナリエディタで見た時にも、「E2」という1バイトだけになってほしい』
というだけであれば、Shift_JIS 変換などは考えずとも、E2 というByte型の値を、
Put #ステートメントで吐き出せば済みます。この場合、String型は使いません。

あるいは『E2というデータをバイナリファイルとしては吐く事は無いが、データは
Byte配列ではなく、String型のまま保持しておきたい』という事であれば、
「S = ChrB(&HE2)」などと書けば済みます。こうすると、String型変数Sには、
VB既定のUnicode文字列を示すデータではなく、バイナリデータを格納できます。

ただし、文字列型変数に、非Unicodeなバイナリデータを保存した場合は、
Mid関数, Left関数, Asc関数, Print#ステートメントなどといった
「文字列操作」を行う処理は一切使えません(データが化ける原因となります)ので、
バイト操作系の命令(AscB関数, LeftB関数など)を利用する必要があります。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加