2進数変換

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
メッセージ
作成者
Z13

2進数変換

#1 投稿記事 by Z13 »

.txtファイル(英字含む)などを、2進数で表して、
そのデータをres.txtに書き込みたいのですが、どうすればいいのですか。
教えてくださ
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

#2 投稿記事 by konisi »

次のような手順を踏めばいいと思います。

1.ファイルを開く
2.入力ファイルからデータを読み込む
3.データを変換する
4.出力ファイルに書き込む
5.読み込んでいないデータがあれば、2に戻る
6.ファイルを閉じる

コードは、次のようになるかと。

コード: 全て選択

#console
Const InputFileName="in.txt"
Const OutputFileName="res.txt"
Dim hInFile As HANDLE,hOutFile As HANDLE
Dim buf1 As Byte,buf2[7] As Byte
Dim InFileLength As Int64,i As Int64
Dim dummy As Long


'ファイルを開く
hInFile=CreateFile(InputFileName,GENERIC_READ,FILE_SHARE_READ,ByVal NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0)
If hInFile=INVALID_HANDLE_VALUE then
	Print "入力ファイルを開けませんでした。"
	Print "ファイル名:",InputFileName
	Sleep(-1)
End If
hOutFile=CreateFile(OutputFileName,GENERIC_WRITE,FILE_SHARE_READ,ByVal NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0)
If hOutFile=INVALID_HANDLE_VALUE then
	Print "出力ファイルを新規作成できませんでした。"
	Print "ファイル名:",OutputFileName
	CloseHandle(hInFile)
	Sleep(-1)
End If

'入力ファイルのサイズを調べる。
SetDWord(VarPtr(InFileLength),SetFilePointer(hInFile,0,VarPtr(InFileLength)+4,FILE_END))

'前処理
SetFilePointer(hInFile,0,0,FILE_BEGIN)
i=0
'本処理
Do
	'読み込み
	ReadFile(hInFile,VarPtr(buf1),1,VarPtr(dummy),ByVal 0)
	'変換
	ToBin(buf2,buf1)
	'書き込み
	WriteFile(hOutFile,buf2,8,VarPtr(dummy),ByVal 0)
	'後処理
	i=i+1
	If i=InFileLength then Exit Do
Loop

'後処理
CloseHandle(hInFile)
CloseHandle(hOutFile)

Print "終了しました。"
Sleep(-1)

Sub ToBin(d As *Byte,s As Byte)
	Dim i As Long
	For i=0 To 7
		d=((s>>(7-i)) And 1)+48
	Next
End Sub
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
z13

ありがとう御座います。

#3 投稿記事 by z13 »

うまくできました、ありがとう御座います!!

そのres.txtの2進数のデータを10進数か16進数に変換したのですが、どうすればいいのですか。
教えてください。
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

#4 投稿記事 by konisi »

次のようにすれば16進数に出来ます。
res.txtから再変換するのは効率が悪いので、元のファイルから直接求めています。
10進数の場合は値によって桁数が変わるので、ここではカンマで区切る事にします。
うまく応用してください。
なお、この二つのコードはきちんと動くか確かめてません。バグがあったら教えてください。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
Z13

完璧です

#5 投稿記事 by Z13 »

すばやい回答ありがとう御座います。
非の打ち所がありません。

ありがとう御座いました。
ゲスト

#6 投稿記事 by ゲスト »

ループの終了判定はlpNumberOfBytesReadを使ってもよさそうですね。

コード: 全て選択

Do
	'読み込み
	ReadFile(hInFile,VarPtr(buf1),1,VarPtr(dummy),ByVal 0)
	'終了判定
	If dummy=0 Then Exit Do
	'変換
	ToBin(buf2,buf1)
	'書き込み
	WriteFile(hOutFile,buf2,8,VarPtr(dummy),ByVal 0)
Loop
Z13

修復

#7 投稿記事 by Z13 »

2or 10or 16に変換するのは早いんですね。

元に戻すやり方を教えてください。
お願いします。
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

#8 投稿記事 by konisi »


10進から元に戻すのはたまに(入力が)3桁になったりして面倒くさいから勘弁。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
Z13

#9 投稿記事 by Z13 »

>10進から元に戻すのはたまに(入力が)3桁になったりして面倒くさいから勘弁。
そうですよね・・・

ありがとう御座います。

ところで、16進数以上のもの(32進数?)は作れるのでしょうか?
また最高で何進数ぐらいでしょうか、教えてください。
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

#10 投稿記事 by konisi »

表現するための記号さえあれば、どんなに基数が大きくても理論上作れる。
身近な例だと、BASE64が64進数だったかと。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
z13

#11 投稿記事 by z13 »

すばやい回答ありがとうございます。

でわ、0~9&A~Vの32進数はどのようにして作るのですか?
教えてください
ゲスト

#12 投稿記事 by ゲスト »

> 10進から元に戻すのはたまに(入力が)3桁になったりして面倒くさいから勘弁。

Val関数を使えばよいかと。
http://www.activebasic.com/help_center/ ... on/Val.htm
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

#13 投稿記事 by konisi »

String型を使ってもいいなら、丁度カンマで区切られているしValが役に立ちますが、
「Byte配列に、ファイルから数字ではない文字を読み込むまでデータを読み込み続ける」関数を作るのが少し面倒だったんですよね。

>>Z13さん
1バイトを2バイト32進数に変換するだけなら元を16進数に変換する奴のToHexの部分を

コード: 全て選択

Sub ToHex(d As *Byte,s As Byte) 
    Dim h="0123456789ABCDEFGHIJKLMNOPQRSTUV" As *Byte 
    d[0]=h[(s>>5) And 31] 
    d[1]=h[s And 31] 
End Sub
のようにするだけでいいのですが、これだとファイルサイズが元の2倍になります。

「5バイト読み込み、うまく変換して8バイト書き込む」という過程を踏めば、ファイルサイズは元の1.6倍程度に収まるのですが、変換も逆変換も少し面倒です。
それでいいなら少し頑張ってみますが、どうしましょうか?
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
z13

#14 投稿記事 by z13 »

32進数、うまくできました!

konisi さん
>・・・それでいいなら少し頑張ってみますが、どうしましょうか?
ファイルは軽いほうがいいので、お願いします。
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

#15 投稿記事 by konisi »

次のような感じになるかと思います。
ただし、変換前の入力ファイルのサイズが5で割り切れないとき、変換後の逆変換が上手にいかない可能性があります。

#元ファイルの0.4倍程度のファイルサイズが気になるなら素直にBASE64でいい気もしますが。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
返信する