• ベストアンサー

CGI 16進数をバイナリ-に変換

sea_clear_sky8です。 今、2バイトの漢字の文字をCGIで、ブラウザに出力するために、 サンプルを解読しています。それは16進数の文字コードを バイナリ-に変換する方法が載っています。 その部分のほんの一部分ですが、この計算しきの意味がわかりません。 char calc; if(src[i]='A')[ /*'A'から'F'のときは10-15*/] calc =src[i]-'A'+10; この計算の仕方と意味がわかりません。 SRC[i]には文字の値(文字コードの値?)が入っていて、 それから、文字のAを引いて10足すと どんな結果が返ってくるのかわかりません。 /*また、4ビット左シフトで上位ビットに*/ calc=calc << 4 というのも意味がわかりません。 ご教授願います。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

> calc =src[i]-'A'+10; は src[i]の内容から 'A'(0x41)を減算して 10を加算するという意味です srcに ABCDといった文字列がある場合 src[0] = 'A', src[1] = 'B', src[2] = 'C', src[3] = 'D' といった具合に格納されています 上記の式を適用すると i=0の場合 calc = 'A' - 'A' + 10 = 0 + 10 = 10 = 0x0A i=1の場合 calc = 'B' - 'A' + 10 = 1 + 10 = 11 = 0x0B i=2の場合 calc = 'C' - 'A' + 10 = 2 + 10 = 12 = 0x0C i=3の場合 calc = 'D' - 'A' + 10 = 3 + 10 = 13 = 0x0D となります calc = calc << 4 は calcの内容を 左へ4ビットシフトしたものを calcに代入となります calc = 0x0A の場合 2進数では 0000 1010 と表記できます これを4ビット左シフトすると 1010 0000 となり 0xA0を生成できます calc << 1 1ビットのシフト 0001 0100 0x14 calc << 2 2ビットのシフト 0010 1000 0x28 calc << 3 3ビットのシフト 0101 0000 0x50 calc << 4 4ビットのシフト 1010 0000 0xA0 といったことです > if(src[i]='A')[ このif文は期待通りの結果を生まないでしょう 比較演算ならば == にしないといけません > /*'A'から'F'のときは10-15*/] のコメントのあるような場合なら if ( src[i] >= 'A' && src[i] <= 'F' ) { といった記述の方が望ましいでしょう

sea_clear
質問者

お礼

回答ありがとうございます。 詳しく回答して頂いて、よくわかりました。 ありがとうございました。

その他の回答 (1)

  • eroermine
  • ベストアンサー率18% (83/444)
回答No.1

src[i] に 'A' が入ってる場合 'A' を引いて 10 を足すと 10 これは 0xA に相当します。 'F' まで同様。 シフト演算子 << は 代入よりも優先なので calc = (calc<<4) と同様

sea_clear
質問者

お礼

回答ありがとうございます。 参考になりました。 ありがとうございました。

関連するQ&A

  • バイナリ表記を表示するコードが分かりません(C言語)

    下記のプログラムはビットごとのANDを使って、 キーボードから入力された文字のASCIIコードをバイナリ表記で表示します。 #include <stdio.h> #include <conio.h> int main(void) { char ch; int i; printf("文字を入力してください: "); ch = getche(); printf("\n"); /* バイナリ表記を表示する */ for(i=128; i>0; i=i/2) if(i & ch) printf("1 "); else printf("0 "); return 0; } 【質問】 「バイナリ表記を表示する」部分のコードで、 1バイト(8bit)の最上位ビットは128(2の7乗)の重みがあり、それを初期値に与えて、 「i=i/2」で64,32,16,8,4,2,1と重みが下がっていくというのは分かりますが、 if(i & ch) で、どうして「i & ch」とすることで、バイナリ表記が表示できるのでしょうか? どなたか教えて頂けないでしょうか?お願いします。

  • [VBS] 16進数でバイナリファイル出力したい

    すいません、教えて下さい。 VBSを利用して16進数にてバイナリファイルを生成したいです。 例えばSJIS文字コードの文字列"あ"の場合だと16進数では"82A0"です。 その"82A0"を指定してバイナリファイル出力を行いたいです。 自分で色々と試しましたが、何故か出力ファイルの結果がバイナリで"81 45 A0"となってしまい 結果的に"あ"が表示されません、、、。 目的としてはVBSでビット演算子の論理和による暗号化を行いたいです。 申し訳ありませんが、ご教示頂ければ幸いです。

  • 配列の添え字の計算について

    sea_clear_sky8です。 CGIのGETまたはPOSTからのクエリストリングの値 を処理していることはわかりますが、 次ののコードの計算の結果がわかりません。 value[nCur] = src + i + 1; name[nCur] = src + i +1; 配列に添え字をどうしているのか意味がわかりません。 ご教授願います。 よろしくお願いします。 [コード] int urlSplit( char *src, char **name, char **value ) { int i,nCur; nCur = 0; if( src[0] == 0x00){ /* srcの中身がない時は0 */ return 0; } /* 1つ目のnameにまずすべてセット */ name[0] = src; /* 1文字ずつずらしていって切り分け */ for( i = 0 ; src[i] != '\0' ; ++i ){ /* = が見つかったときは、valueにセット */ if ( src[i] == '=' ){ /* 前name値のラストにする */ src[i] = '\0'; この行の計算です。 value[nCur] = src + i + 1; } /* & が見つかったときは、 フィールド1つ増やしてnameにセット */ if( src[i] == '&' ){ /* 前Value値のラストにする */ src[i] = '\0'; nCur++; この行の計算です。  name[nCur] = src + i +1; } } return (nCur+1); } int main() { int i,nFields; int nLength; char *query; char *name[2]; char *value[2]; nFields = urlSplit( query, name, value ); ]

  • 16進数変換

    文字列16進数をバイナリ16進数に変換する参考ソースが以下のようになっていたのですが、どういう意味でしょうか? strSerial ..... 文字列16進数 ForwardBuf ..... char BackBuf .....char /* 文字列16進数長を代入 */ Len_strSerial = strlen(strSerial); /* 文字列16進数を大文字に変換 */ for (iToupCnt=0; iToupCnt < Len_strSerial; iToupCnt++) { tmpbuf[iToupCnt] = toupper(strSerial[iToupCnt]); } for (iStrsCnt = 0; iStrsCnt < Len_strSerial; iStrsCnt += 2) { ForwardBuf = (tmpbuf[iStrsCnt] >= 'A' ? tmpbuf[iStrsCnt] - 'A' + 10 : tmpbuf[iStrsCnt] - '0'); BackBuf = (tmpbuf[iStrsCnt + 1] >= 'A' ? tmpbuf[iStrsCnt + 1] - 'A' + 10 : tmpbuf[iStrsCnt + 1] - '0'); binSerial[iBSLCnt] = ForwardBuf * 16 + BackBuf; iBSLCnt++; } ちょっと見にくいですね・・・すみません よろしくお願いします ちなみに最終的にはバイナリ16進数とバイナリ16進数長が 求められるようです。

  • バイナリデータからの値の取得について教えてください

    今、バイナリデータから値を取りだそうとがんばっています。 しかし、うまくいかずに困っています。 困っていることは2点あります。 (1)バイナリデータにはリトルエンディアンで格納していると書いています。 まず、リトルエンディアンで書かれている場合、どのような処理を考えることが必要なのでしょうか? (2)バイナリデータには、 はじめに文字列(char)型4バイトで「RIFF]という値 次に32ビット符号なし整数で4バイトの数字、 次に4052バイトの構造体 などと収納されているようです。 このように入っているデータから値を取得するにはどのようにしたらよいのでしょうか? 全然できなくて困っています。 教えていただけないでしょうか? よろしくお願いいたします。

  • 3進数を10進数に変換

    3進数や5進数のように2の階乗ではない任意の進数の文字列を、C言語のビットシフトを使って10進数に変換するプログラムについて、質問させていただきます。 ビットシフトを使わないで、任意の進数の文字列を10進数に変換する方法は分かっていますが、ビットシフトを使った方が非常に計算が高速で出来るので、ビットシフトを使いたいと思っています。 下記のプログラムは4進文字列を10進整数に変換するものです。2進、8進文字列の場合は、シフトするビット数を1ビット、3ビット(つまり、ans <<= 1、ans <<= 3)にすれば計算することが可能です。しかし、3進数や5進数の場合、いろいろと考えたのですが、どのようにすれば良いのか分かりません。 下記のプログラムのようにビットシフトを使って3進数や5進数の文字列を10進数に変換するには、どのように工夫すれば良いでしょうか? どなたかご教授をお願いいたします。 #define STRING_NUM 2 /* 文字列の長さ */ int main(void) { int i; int ans = 0; /* 10進数の整数 */ char buf[STRING_NUM]; /* 4進数の文字列 */ buf[0] = '3'; buf[1] = '1'; for ( i = 0 ; i < STRING_NUM; i++ ){ printf(" %c", buf[i]); } printf("\n"); for ( i = 0 ; i < STRING_NUM; i++ ){ if ( buf[i] == '0' ){ ans <<= 2; /* シフトするビット数 */ ans |= 0; } if ( buf[i] == '1' ){ ans <<= 2; ans |= 1; } if ( buf[i] == '2' ){ ans <<= 2; ans |= 2; } if ( buf[i] == '3' ){ ans <<= 2; ans |= 3; } } printf( "ans = %d\n", ans ); return 0; }

  • バイナリファイルとバイナリ文字列の違い

    がわかりません。 例えば >http://e-words.jp/w/E38390E382A4E3838AE383AAE58897.html をみるとバイナリ列は1バイトを連ねたものだというらしいです。 つまり【文】という文字列を文字コードUTF-8でバイト配列化すると [1] => 230 [2] => 150 [3] => 135 となります。 (これはPHPでunpackかけましたが他の言語のGetBytes()などでも同じバイト値がでました。) この【文】という文字列はバイナリ列になるわけですよね? 例えばこの【文】という文字だけを保存したbun.txtというファイルはバイナリーファイルに なるのでしょうか? バイナリファイルの定義をみると >http://e-words.jp/w/E38390E382A4E3838AE383AAE38395E382A1E382A4E383AB.html 上記URLだと >文字コードの範囲などを考慮せずに作成されたファイル というのがバイナリファイルであるとあります。 つまりバイナリファイルとは 1バイト・・つまり8ビット(0~255)までの数値で表したものを連ねたもので なおかつ、文字コードなどの解釈を一切行わなずに、バイト値のみが記述されたデータと おもってもよいのでしょうか?

  • バイナリデータの書き方が分かりません・・。

    シリアルポートでバイナリデータを送信したいのですが、バイナリをどう書けがいいのか分りません。 送りたいコードは16進数で02 00 02 00です。 以下のソースの"123"の部分を書き換えるのだと思うのですが、どう書けば良いのでしょうか? よろしくお願いします。 char* wbuf; DWORD wbyte; lstrcpy(wbuf,"123"); WriteFile(hCom,wbuf,lstrlen(wbuf),&wbyte,&old

  • 16進数から10進数に変換

    いつもお世話になります。 先日バイナリデータを読み込み、ある特定のデータを検索し、 そのデータを10進数に変換する処理がしたいです。 FILE *fp; char buf[1024]; fp = fopen("sample.jpg","rb"); fread(buf, siZeof(char), 1024, fp); for( int i=0; i<1024; i++ ){ if( (buf[i]==0xff) && (buf[i+1] == 0xe0) ){ //※質問詳細下記します。 } } ※ f文で、buf[i+2]buf[i+3]、例えばprintf("%02x,%02x",buf[i+2],buf[i+3]); で出力すると、所望の(11 00 )の16進数で得られています。 このbuf[i+2] buf[i+3]の値を10進数に変換して得るには、 どうしたらいいでしょうか? 0x1100→4352 どうぞよろしくお願い致します。

  • お願いします、教えてください。10進数を2進数に変換するには・・・。

    10進数を2進数に変換するプログラムを作成したのですが、うまく動作しません、どうしても解らないので教えてください。 サンプルコードを元に「define」は5で稼動出来る様にしたいのですが、動作せず困っています。以下の、どの部分を修正すれば変換出来るのでしょうか? ご教授よろしくお願いいたします。 //10進数文字を数字の2進数で表示 #include "stdafx.h" #define HEX 5 //「function」:入力文字された文字の処理///////////////////////////////////// char ToInt( char cInt) { int mal=0; switch (cInt){ case '0': mal=0; break; case '1': mal=1; break; case '2': mal=2; break; case '3': mal=3; break; case '4': mal=4; break; case '5': mal=5; break; case '6': mal=6; break; case '7': mal=7; break; case '8': mal=8; break; case '9': mal=9; break; } return (mal); } //「function」:入力文字された文字数//////////////////////////////////////////// char HexInt( char eInt) { char mul=0; switch (eInt){ case 0: mul='0'; break; case 1: mul='1'; break; } return (mul); } //「function」:桁数の計算(10×指数を計算)/////////////////////////////////// int HexAcc( int n ) { int i; int ans=1; for( i=0; i<n; i++ ){ ans *= 10; } return (ans); } int _tmain(int argc, _TCHAR* argv[]) { int i=0,n=0,j=0,s=0,k=0,m=0,e=0,ans=0, add=0; char decimal[255], ditto[255],sub[255],temp[255],chg[255],siu[255]; //入力されない場合// if( 1 > argc ){ } else{ printf("10進数を入力してください。\n"); return 1; } for( k=0; k<255; k++ ){ //文字として'0'を代入// sub[k] = '0'; //subに文字として'0'を代入// temp[k] = '0'; //tempに文字として'0'を代入// chg[k] = '0'; //chgに文字として'0'を代入// siu[k] = '0'; //siuに文字として'0'を代入// } //入力された文字数を受取る// for( i=0; argv[1][i] != '\0'; i++ ){ decimal[i] = argv[1][i]; } decimal[i] = '\0'; //空白文字のチェック// for( i=0; decimal[i] != '\0'; i++ ){ if( decimal[i] != ' ' ){ ditto[n] = decimal[i]; n++; } } //'\0'を代入(文字列の終端)// ditto[n]='\0'; //「0」から「9」のループ// for( n=0; ditto[n] != '\0'; n++ ){ if(( ditto[n] == '0' ) || ( ditto[n] == '1' ) || ( ditto[n] == '2' ) || ( ditto[n] == '3' ) || ( ditto[n] == '4' ) || ( ditto[n] == '5' ) || ( ditto[n] == '6' ) || ( ditto[n] == '7' ) || ( ditto[n] == '8' ) || ( ditto[n] == '9' )){ }else{ printf("エラー\n 10進数を入力してください。\n"); return 0; } } //桁数のループ// for( n=0; ditto[n] != '\0'; n++ ){ m = m + 1 ; } //桁数の判断// if( m <= HEX ){ }else{ printf("エラー\n入力文字数は、%d文字以内にしてください。\n",HEX); return 0; } //subにdittoを代入// for( n=0; ditto[n] != '\0'; n++){ sub[HEX-m+n] = ditto[n]; } sub[HEX] = '\0'; //'\0'を代入(文字列の終端)// //sub[0]からsub[9]の計算// for( n=0; sub[n] != '\0'; n++){ ans = ToInt(sub[n]); add += ans * HexAcc(HEX-n-1); } //2進数の計算・商が0になるまで// for( n=0; sub[n] != '\0'; n++ ){ temp[n] = add % 2; add = add / 2; if( add == 0){ break; } } temp[HEX] = '\0'; //'\0'を代入(文字列の終端)// //桁数のチェック(商・余り)// for( ; n>=0; n-- ){ e = e++; } //temp・値の入替え「tempからchg」// for( n=0; sub[n] != '\0'; n++ ){ chg[HEX-n-2] = temp[n]; } chg[HEX]='\0'; //'\0'を代入(文字列の終端)// //2進数に変換// for( ; n>=0; n-- ){ siu[n] = HexInt(chg[n]); } siu[HEX]='\0'; //'\0'を代入(文字列の終端)// printf("\n10進数文字を2進数で変換した値は・・・ %s \n",siu); }

専門家に質問してみよう