2進数変換
次のような手順を踏めばいいと思います。
1.ファイルを開く
2.入力ファイルからデータを読み込む
3.データを変換する
4.出力ファイルに書き込む
5.読み込んでいないデータがあれば、2に戻る
6.ファイルを閉じる
コードは、次のようになるかと。
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を主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ありがとう御座います。
うまくできました、ありがとう御座います!!
そのres.txtの2進数のデータを10進数か16進数に変換したのですが、どうすればいいのですか。
教えてください。
そのres.txtの2進数のデータを10進数か16進数に変換したのですが、どうすればいいのですか。
教えてください。
次のようにすれば16進数に出来ます。
res.txtから再変換するのは効率が悪いので、元のファイルから直接求めています。
うまく応用してください。
res.txtから再変換するのは効率が悪いので、元のファイルから直接求めています。
[ここをクリックすると内容が表示されます]
10進数の場合は値によって桁数が変わるので、ここではカンマで区切る事にします。コード: 全て選択
#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)
'変換
ToHex(buf2,buf1)
'書き込み
WriteFile(hOutFile,buf2,2,VarPtr(dummy),ByVal 0)
'後処理
i=i+1
If i=InFileLength then Exit Do
Loop
'後処理
CloseHandle(hInFile)
CloseHandle(hOutFile)
Print "終了しました。"
Sleep(-1)
Sub ToHex(d As *Byte,s As Byte)
Dim h="0123456789ABCDEF" As *Byte
d[0]=h[(s>>4) And 15]
d[1]=h[s And 15]
End Sub
うまく応用してください。
[ここをクリックすると内容が表示されます]
なお、この二つのコードはきちんと動くか確かめてません。バグがあったら教えてください。コード: 全て選択
#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,l 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)
'変換
l=ToDec(buf2,buf1)
'書き込み
WriteFile(hOutFile,buf2,l,VarPtr(dummy),ByVal 0)
'後処理
i=i+1
If i=InFileLength then Exit Do
Loop
'後処理
CloseHandle(hInFile)
CloseHandle(hOutFile)
Print "終了しました。"
Sleep(-1)
Function ToDec(d As *Byte,s As Byte) As Long
If s>99 then
d[0]=s\100+48
d[1]=((s\10) Mod 10)+48
d[2]=(s Mod 10)+48
d[3]=Asc(",")
ToDec=4
Else
d[0]=((s\10) Mod 10)+48
d[1]=(s Mod 10)+48
d[2]=Asc(",")
ToDec=3
End If
End Function
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
2進数→元 [ここをクリックすると内容が表示されます]
コード: 全て選択
#console
Const InputFileName="res.txt"
Const OutputFileName="out.txt"
Dim hInFile As HANDLE,hOutFile As HANDLE
Dim buf1 As Byte,buf2[7] As Byte
Dim InFileLength 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)
'本処理
Do
'読み込み
ReadFile(hInFile,buf2,8,VarPtr(dummy),ByVal 0)
'変換
buf1=FromBin(buf2)
'書き込み
WriteFile(hOutFile,VarPtr(buf1),1,VarPtr(dummy),ByVal 0)
'後処理
InFileLength=InFileLength-8
If InFileLength=0 then Exit Do
Loop
'後処理
CloseHandle(hInFile)
CloseHandle(hOutFile)
Print "終了しました。"
Sleep(-1)
Function FromBin(d As *Byte) As Byte
Dim i As Long
For i=0 To 7
FromBin=FromBin+(1<<(7-i))*(d And 1)
Next
End Function
16進数→元 [ここをクリックすると内容が表示されます]
コード: 全て選択
#console
Const InputFileName="res.txt"
Const OutputFileName="out.txt"
Dim hInFile As HANDLE,hOutFile As HANDLE
Dim buf1 As Byte,buf2[1] As Byte
Dim InFileLength 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)
'本処理
Do
'読み込み
ReadFile(hInFile,buf2,2,VarPtr(dummy),ByVal 0)
'変換
buf1=FromHex(buf2)
'書き込み
WriteFile(hOutFile,VarPtr(buf1),1,VarPtr(dummy),ByVal 0)
'後処理
InFileLength=InFileLength-2
If InFileLength=0 then Exit Do
Loop
'後処理
CloseHandle(hInFile)
CloseHandle(hOutFile)
Print "終了しました。"
Sleep(-1)
Function FromHex(d As *Byte) As Long
FromHex=(td(d[0])<<4)+td(d[1])
End Function
Function td(h As Long) As Long
td=h-48
If td>9 then td=td-7
End Function
10進から元に戻すのはたまに(入力が)3桁になったりして面倒くさいから勘弁。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
表現するための記号さえあれば、どんなに基数が大きくても理論上作れる。
身近な例だと、BASE64が64進数だったかと。
身近な例だと、BASE64が64進数だったかと。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
> 10進から元に戻すのはたまに(入力が)3桁になったりして面倒くさいから勘弁。
Val関数を使えばよいかと。
http://www.activebasic.com/help_center/ ... on/Val.htm
Val関数を使えばよいかと。
http://www.activebasic.com/help_center/ ... on/Val.htm
String型を使ってもいいなら、丁度カンマで区切られているしValが役に立ちますが、
「Byte配列に、ファイルから数字ではない文字を読み込むまでデータを読み込み続ける」関数を作るのが少し面倒だったんですよね。
>>Z13さん
1バイトを2バイト32進数に変換するだけなら元を16進数に変換する奴のToHexの部分をのようにするだけでいいのですが、これだとファイルサイズが元の2倍になります。
「5バイト読み込み、うまく変換して8バイト書き込む」という過程を踏めば、ファイルサイズは元の1.6倍程度に収まるのですが、変換も逆変換も少し面倒です。
それでいいなら少し頑張ってみますが、どうしましょうか?
「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
「5バイト読み込み、うまく変換して8バイト書き込む」という過程を踏めば、ファイルサイズは元の1.6倍程度に収まるのですが、変換も逆変換も少し面倒です。
それでいいなら少し頑張ってみますが、どうしましょうか?
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
次のような感じになるかと思います。
ただし、変換前の入力ファイルのサイズが5で割り切れないとき、変換後の逆変換が上手にいかない可能性があります。
#元ファイルの0.4倍程度のファイルサイズが気になるなら素直にBASE64でいい気もしますが。
変換 [ここをクリックすると内容が表示されます]
コード: 全て選択
#console
Const InputFileName="in.txt"
Const OutputFileName="res.txt"
Dim hInFile As HANDLE,hOutFile As HANDLE
Dim buf1[4] As Byte,buf2[7] As Byte
Dim InFileLength 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)
'本処理
Do
'読み込み
ReadFile(hInFile,buf1,5,VarPtr(dummy),ByVal 0)
If dummy-5 then
Dim j As Long
For j=dummy to 5
buf1[j]=0
Next
End If
'変換
To32(buf2,buf1)
'書き込み
WriteFile(hOutFile,buf2,8,VarPtr(dummy),ByVal 0)
'後処理
InFileLength=InFileLength-5
If InFileLength<=0 then Exit Do
Loop
'後処理
CloseHandle(hInFile)
CloseHandle(hOutFile)
Print "終了しました。"
Sleep(-1)
Sub To32(d As *Byte,s As *Byte)
Dim i As Long,k As Int64
Dim h="0123456789ABCDEFGHIJKLMNOPQRSTUV" As *Byte
k=0
For i=0 To 4
k=k*256+s
Next
For i=0 To 7
d[7-i]=h[k And 31]
k=k\32
Next
End Sub
逆変換 [ここをクリックすると内容が表示されます]
コード: 全て選択
#console
Const InputFileName="res.txt"
Const OutputFileName="out.txt"
Dim hInFile As HANDLE,hOutFile As HANDLE
Dim buf1[4] As Byte,buf2[7] As Byte
Dim InFileLength 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)
'本処理
Do
'読み込み
ReadFile(hInFile,buf2,8,VarPtr(dummy),ByVal 0)
'変換
From32(buf1,buf2)
'書き込み
WriteFile(hOutFile,buf1,5,VarPtr(dummy),ByVal 0)
'後処理
InFileLength=InFileLength-8
If InFileLength=0 then Exit Do
If InFileLength<0 then
CloseHandle(hInFile)
CloseHandle(hOutFile)
Print "入力ファイルのサイズが変ですが、終了しました。"
Sleep(-1)
End If
Loop
'後処理
CloseHandle(hInFile)
CloseHandle(hOutFile)
Print "終了しました。"
Sleep(-1)
Sub From32(d As *Byte,s As *Byte)
Dim i As Long,k As Int64
k=(td(s[0])*1024*1024*1024*32)+(td(s[1])*1024*1024*1024)+(td(s[2])*1024*1024*32)+(td(s[3])*1024*1024)+(td(s[4])*1024*32)+(td(s[5])*1024)+(td(s[6])*32)+td(s[7])
For i=0 To 4
d[4-i]=k And 255
k=k\256
Next
End Sub
Function td(h As Long) As Long
td=h-48
If td>9 then td=td-7
End Function
ただし、変換前の入力ファイルのサイズが5で割り切れないとき、変換後の逆変換が上手にいかない可能性があります。
#元ファイルの0.4倍程度のファイルサイズが気になるなら素直にBASE64でいい気もしますが。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。