16進数文字列をデコード – プログラミング – Home

16進数文字列をデコード
 
通知
すべてクリア

[解決済] 16進数文字列をデコード


森盛男
 森盛男
(@森盛男)
ゲスト
結合: 19年前
投稿: 5
Topic starter  

はじめまして。森盛男と申します。

現在、パケットをキャプチャするAPを作っているのですが、
文字列となっている16進数41をAと変換する部分で躓いております。

文字列型の16進数をデコードする為の関数を
探してみたのですが、よくわかりません。

そこで、みなさまのお知恵を拝借したく、
書き込ませていただきました。

よろしくお願い致します。


引用未解決
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> 文字列型の16進数をデコードする為の関数
strtol関数を調べてみてはどうでしょうか?


返信引用
森盛男
 森盛男
(@森盛男)
ゲスト
結合: 19年前
投稿: 5
Topic starter  

Blue さま

早速のご返事、ありがとうございます。

すみません。上の書き方ですと、
16進数が文字列であることが問題であるように見えますね。。

問題は16進数の文字コードを1バイト文字や2バイト文字にデコードする部分が
知りたかったのです。
(1バイトにする部分は自己解決しております。。)


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

とりあえず、strtol関数からやる方法

const char s[] = 0041;

unsigned char low, hi;

long n = strtol( s, NULL, 16 );
low = ( unsigned char )n;
hi = ( unsigned char )( ( n >> 8 ) & 0xff );
/* // sscanfだと1行で済む
sscanf( s, %2x%2x, &hi, &low );
*/

char ret[ 8 ];
if ( hi )
sprintf( ret, %c%c, hi, low );
else
sprintf( ret, %c, low );

printf( %s\n, ret );


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> // sscanfだと1行で済む
コイツは、
41とかの場合は1行ではすまないですね。
sscanfの戻り値かなんかで判定しないといけないでしょう。

※文字コードはShift-JIS 環境は Windows として解答しています。


返信引用
REE
 REE
(@REE)
ゲスト
結合: 23年前
投稿: 240
 

質問がまだあいまいですので、入力と出力のそれぞれの型と、
具体的な入出力例(2バイト文字を含むもの)を示してください。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

もしSJISコードであるなら、リードバイトであるかの判断をしてリードバイトなら
次はトレールバイトであるとみて2バイトコードと判断します。
リードバイトでないのならそれは1バイトコードとして判断します。
但し、判定する時は2バイト文字が先頭なら必ずリードバイトから引き渡される事が
前提になります。2バイト文字のトレイルバイトから引き渡されてもそれが2バイトコードの
トレイルバイトであると言う判定は無理だと思います。


返信引用
森盛男
 森盛男
(@森盛男)
ゲスト
結合: 19年前
投稿: 5
Topic starter  

REEさま

自分の質問を読み返してみましたが、
仰る通り、曖昧でございます。

一から説明させていただきますと、

自端末内のパケットを拾い、そのデータを文字列型の16進数(2桁)として、
配列に格納します。
forループにて配列内の値を一つずつ取り出し、文字に変換し、
文字列型の変数に一文字ずつ足していきます。

その際、1バイト文字は即付け足し、
2バイト文字の1バイト目の場合は更に次のバイトを取り出して、
2バイト文字に変換してから、付け足すと言う形を取りたかったのです。

そしてその文字列型の変数に、指定した言葉が含まれている場合、
その変数の値をファイルに書き出すと言う仕様を考えています。

WinPcapのサンプルプログラムを参考に手直しをしている上、
VC++(C言語含む)の知識がない為におかしなことをしているかもしれません。

Blueさま

曖昧な質問だったにも関わらず、ご回答ありがとうございます。
申し訳ございませんが、

>low = ( unsigned char )n;
>hi = ( unsigned char )( ( n >> 8 ) & 0xff );

ここの部分を教えていただけませんでしょうか?

>low = ( unsigned char )n;
はなぜ、下位1バイト分しか代入されないのでしょうか?

そして
>hi = ( unsigned char )( ( n >> 8 ) & 0xff );
の& 0xffはなぜ必要なのでしょうか?

お手数をお掛けしますが、
以上、よろしくお願い致します。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> >low = ( unsigned char )n;
> はなぜ、下位1バイト分しか代入されないのでしょうか?
lowがunsgined char型だから、上位バイトが切り捨てられるからです。

> の& 0xffはなぜ必要なのでしょうか?
は正直よくワカリマセン。なくてもいいのかも、、、

これらは、
windef.h の HIBYTEマクロとHOBYTEマクロから持ってきたので。
> #define LOBYTE(w) ((BYTE)(w))
> #define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF))


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

バイト列として扱うだけであれば、2バイト文字判定はいらないと思いますけれど。
マルチバイト文字の場合、基本的にそのままで再現できるはずですし。
UNICODEならWORD値なのでロウバイトとハイバイトの逆転を意識する必要があると思いま
すが、
SJISなら2バイト文字もバイトデータが二つ連なっただけの扱いなので気にしないで
追加してしまっていいのでは?

あと、プログラミングの経験がまったくないのですか?
書き込まれている内容からするとまったくの初心者とも思えませんけれど。
& 0xffのくだりを見る限りでは。


返信引用
森盛男
 森盛男
(@森盛男)
ゲスト
結合: 19年前
投稿: 5
Topic starter  

BLUEさま
ありがとうございます。

> lowがunsgined char型だから、上位バイトが切り捨てられるからです。
すみません。
イマイチ変数の型がわかっていない為、馬鹿な質問をしてしまったようです。
書いて頂いた、ソースは大変参考になりました。
本当にありがとうございます。

PATIOさま
ご回答ありがとうございます。
文字確かにそうでした!
1バイト文字、2バイト文字を意識する必要は無かったみたいです。

プログラミングの経験は全く無いわけではありません。
ただ、VC関しては他の人の修正をやる程度だったんで、
上記の様に変数の型がわからないなど、基礎的なことがわかってません。

以上、何とかなりそうなんで、解決とさせていただきます。
アドバイスを下さいました皆様ありがとうございました。


返信引用
森盛男
 森盛男
(@森盛男)
ゲスト
結合: 19年前
投稿: 5
Topic starter  

チェックを入れ忘れてました。。
上の自分の文章も微妙におかしいし。。

申し訳ございませんm(._.)m


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました