phpのバイナリデータ操作で詰まっています

このQ&Aのポイント
  • バイナリデータ操作で詰まっている方へ。phpのバイナリデータ操作で2byteのデータを4bitずつに取り出し、データをチェックする方法を教えてください。
  • バイナリデータ操作の方法を教えてください。phpでバイナリファイルから読み込んだ2byteのデータを4bitずつに取り出し、データをチェックする方法を試してみましたがうまくいきません。
  • phpのバイナリデータ操作に詳しい方へ。バイナリファイルから読み込んだデータをマスクしてシフトし、2byteのデータを4bitずつに取り出す方法を教えてください。試してみた結果、意図したデータではなくなってしまいました。
回答を見る
  • ベストアンサー

php のバイナリデータ操作について

php のバイナリデータ操作で詰まっています。 やりたいことは、バイナリファイルから読み込んだ2byteのデータを 4bitずつに取り出して、データをチェックしたいです。 マスクして、シフトしてと考えたのですが マスクの時点で意図するデータではなくなっています。 良い方法はありますでしょうか。 以下、試してみた結果です。 //2byteづつ読む $bin_data = fread( $handle, 2 );  ■bin2hex()の後にマスク $dataStr = bin2hex($bin_data); print ( $dataStr ); →結果 ABCD $mask = ($dataStr & "FFFF") ; print ( $dataStr ); →結果 @BBD $mask = ($dataStr & 0xFFFF) ; print ( $dataStr ); →結果 0  ■bin2hex()の後にマスク $mask_data = ( $bin_data & 0xFFFF ) ; $dataStr = bin2hex($mask_data); print ( $mask_data ); →結果 0 $mask_data = ( $bin_data & "FFFF" ) ; $dataStr = bin2hex($mask_data); print ( $mask_data ); →結果 文字ばけ

  • PHP
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
回答No.2

まずは衝撃の実験結果から。 http://ideone.com/MSHFT そう。「ABCDではない」のです。 …つまり、「0xFFFF」と論理積をとっても、それは「下位16bitではない」のです。 というわけで、下位16bitがとれるよう、16bit全てが1となるようなものを pack関数にかましたものとビット演算を行ってみると自分の希望通りのものが出力されました。(このサイトPHP 5.2.11でhex2binの対応バージョンが書かれていないので、多分使えないのでしょう) http://ideone.com/hbV1U

colagum_love
質問者

お礼

回答遅れました。すみません。 衝撃でした。 ありがとうございます。

その他の回答 (1)

  • shimix
  • ベストアンサー率54% (865/1590)
回答No.1

私だったら、こんな感じでバラしますかねぇ。 <?php $str = chr(126) . chr(14); $out = array(); for ($i = 0; $i < strlen($str); $i++) { $tmp = bin2hex(substr($str, $i, 1)); $tmp = (strlen($tmp) == 1) ? '0' . $tmp : $tmp; $out[] = substr($tmp, 0, 1); $out[] = substr($tmp, 1, 1); } print "<pre>"; print_r($out); print "</pre>"; ?> >4bitずつに取り出して、データをチェックしたいです。 のチェックがどういうものか次第で最適解も変わってくると思います(上記は文字列で比較する前提です)。どういうチェックをするかを書いていただくといいかもしれません。

colagum_love
質問者

お礼

回答遅れました。すみません。 サンプルまで作っていただき ありがとうございます。 参考にさせていただきました。

関連するQ&A

  • PHPのバイナリ型文字列の取り扱いについて

    お世話になります。 PHPについて困っている事がありまして、ご質問させて頂きます。 現在標準入力でバイナリ型とアスキー型の混ざった文字列を 受け取り処理をするコーディングをしているのですが ------------------------------------------------ FFFF1B ------------------------------------------------ ※FFFF(バイナリ型:2byte)1B(アスキー型:2byte) 上記の文字列を標準入力し、以下のコードを実行すると $fp = fopen("php://stdin", "rb"); $contents = fread($fp, 4); echo $contents; --------------------------------------------- 出力結果 ---------------------------------------------                FFFF _______________________________________________________________________ と表示され、FFFFはバイナリ型なので2バイト(だと思うのですが、、) なのに、php上では4バイトと認識されてしまいます。 どこかおかしい所があればご指摘頂きたく思います。 また、勘違いしている点があれば是非ご指摘くださいます様 宜しくお願いします。 大変お手数ですが宜しくお願いします。

    • ベストアンサー
    • PHP
  • C++でバイナリデータの扱い方

    以下のプログラムで接続先からバイナリデータを取得しているのですが coutで出力しても画面に何も表示されません。 ------------------------------------------------------ /*include部分は省きます*/ std::string bin; //1 clx::http session(clx::uri::encode(ip), 80); //2 session.get(clx::uri::encode(param)); //3 bin = session.body(); //4 std::cout << bin << std::endl; //5 ------------------------------------------------------ 上記プログラムを空ファイルにリダイレクトしバイナリエディタで見たら ちゃんとデータは書き込まれていました。 5行目を以下のように変えても空欄が出力されただけで文字は表示されませんでした std::cout << std::hex << bin << std::endl; しかし以下のようにすると文字数は表示されました。 std::cout << bin.length() << std::endl; やりたいこととしてはphpのpack()、unpack()的な部分です。 例えば 値をフォーマットを指定してバイナリデータとして出力 $val=pack("L", 35); とか バイナリデータを変数から指定バイト分取り出して10進数で画面に出力 $bin=(バイナリデータ); $val=unpack("c",$bin); echo(sprintf("%d",$val)); です。 バイナリの扱いはリトルエンディアンです。 ご教示お願いしますm(__)m

  • バイナリデータについて

    バイナリデータについて 先日関連した質問をさせていただいただのですが、 質問内容があやふやでしたのであらためて 今回POS連携システムにてPOSへ渡すデータを固定長バイナリ型式で作成いたします。 JAVAにてデータ作成を行うのですが、その作成方法がよくわかりません。 例えば次の6項目があるとして 元のデータ[0001] → 属性[K] 長さ[2Byte] 元のデータ[20100901] → 属性[K] 長さ[4Byte] 元のデータ[1234567890123456ffff] → 属性[K] 長さ[10Byte] 元のデータ[000100] → 属性[P] 長さ[3Byte] 元のデータ[0000001c] → 属性[P] 長さ[4Byte] 元のデータ[01] → 属性[B] 長さ[1Byte] 元のデータから各属性への変換、ファイル出力がイメージがわきません。 属性のK,P,Bというのもよくわかりません。 どなたかヒントでもいただけたら幸いです。 よろしくお願いいたします。

    • ベストアンサー
    • Java
  • またまたバイナリ→テクスト

    VBは5で、Excle2000のVBAでやってます。バイナリデータ→テクストデータに 128バイナリデータを添え字を使って1バイトごとに抽出DATA_PS = DATA_PS & 変換関数 というふたつの部分のリファレンスが正しくかけなくて 困ってます。Getを使って1バイトづつとりだして、Hexを使って変換するというものだそうです。 誰か教えてください。

  • memcmp バイナリデータの比較方法

    ------------------------------------ Visual Studio 2008 pro VC++ ------------------------------------ 基本的な質問で申し訳ないのですが、memcmp()などでバイナリデータとの比較方法について教えてください。 例えばバイナリファイルを開き、その先頭から10バイト分が特定のバイトコードであるかを調べ用とした場合、fread()で10バイト分読み込んだバッファーをmemcmpで比較すればよろしいのでしょうか? また、その際に比較対象のバイトコードはどのように指定したらよいのでしょうか? --------------------------------- 例:比較対象のバイトコードが0xFFFFFFFFFFFFFFFFFFFFの場合 fread( szBuffer, 1, 10, fp ); memcmp( szBuffer, ???, 10 ); ---------------------------------

  • MIMEとバイナリデータの読み方

    バイナリファイルの中、MIME boundary1の後、ヘッダーの部分のXMLで書かれたテキストファイルあります。そのXMLヘッダー文をパースしたい。 バイナリファイルのほかのところにMIME boundary2の後バイナリ形式のデータあります。 Googleで調べたけど、なにかは見つかったけど、理解できず困っています。 バイナリファイルを一バイトづつ読んで、Integer.toHexString()を使うとASCIIの形でXMLの部分はそのまま (フォーマットなしで)、バイナリデータの分は化けた表示されます。 だいたいのアウトラインでよいです。やり方ご存知の方、教えてください。 (1)boundary1の後書かれたXML式データを読む方法 (2)boundary2の後、決まったキーワードが入っていたら、そこから決まったバイト数までのバイナリデータを読む方法 その決まったキーワードと決まったバイト数はヘッダーのXML内に書かれています。

    • ベストアンサー
    • Java
  • バイナリデータの取り方

    VB6を使用して、バイナリファイルをバイナリデータとして文字列にとりたいのですが、全角文字が絡んだ時の処理がうまくいきません。 バイナリファイルをString型の変数に丸ごと読み込んで、後は何バイトから何バイト目を抜き取り数値に変換…という処理をしようとしています。 本来は、バイナリでファイルをオープンして、Getコマンドで取得するのが手っ取り早いのですが、ファイルアクセス回数を減らすため、このような面倒な方法をとっております。 そこで仮に、 dim test as string dim i as integer test = "aあ" & chr(1) & "0 " For i = 1 to 6 Debug.Print Asc(Strconv( _ MidB(Strconv(test,vbFromUnicode),i,1), _ vbUnicode)) Next のようなソースを作ってみました。(本来は文字列は数100KByte…) しかしながら、この方法ですと上の例では2Byte目、つまり「あ」の文字の1Byte目が「&H00」になってしまいます。その次は「&HA0」、他の箇所も問題ないのですが… おそらくは根本的に違う方法で解決すべきではないかと思うのですがその方法がわかりません。 なお、この格納データはバイナリデータなので、意図的に全角文字にしていくてもその値によって(偶然)全角文字になったり制御文字になったりしますので前もって全角文字に対する処理は難しいと考えてます。 質問の仕方が良くなく、質問の内容がなかなかご理解いただけないとは思いますが、ご存知の方、ご経験者の方、ご教授お願いいたします。

  • バイナリファイルの操作(配列の操作について)

    こんにちは。 大変お世話になっております。 配列要素の先頭[0]から[5]までを文字列N、[6]から[1029]までをバイナリデータの計1030バイトの配列要素を使用しています。 [現在行なっている操作方法] 1. Buf[1500]とBuff[1500]を用意 2. fread関数により、Bufに1024バイトずつ格納 3. sprintf関数により、Buffの先頭[0]から[5]まで文字列挿入 4. strcat関数により、BuffとBufを結合 と言う形をとっています。 そこで、sprintfにて先頭から[5]までの文字列を挿入後、先頭から[5]までの配列要素を削除(不要になるため)し、バイナリデータのみにしたいのですが、何か方法はありますでしょうか? NNNNNNDDDDDDDDDDDDDDDDD・・・・・DDDDD←1029番 から NNNNNNを削除し、 DDDDDDD・・・・・DDDDD のみにしたいと思っています。 よろしくお願いします。

  • C言語 バイナリデータのサイズの調べ方

    windows7 64bitでcygwinを使用しています。 32bitを1つの組として、いくつかの組で構成されたバイナリデータがあります。 このバイナリデータにいくつの組があるのか調べるため、以下のようなソースを記述したのですが、うまくいきません。 どこを修正すればよろしいでしょうか。 御教授願います。 int main() { long long int i; long long int hex[1]; long long int aaaa; int bb; int ret; FILE * fp; i = 1; bb = 1; for(;;){ fp = fopen("kimi.dat", "r"); bb = fread(&hex[1],4,i,fp); aaaa = i; i = aaaa + 1; ret = fclose(fp); if (bb != aaaa) { printf("%lld\n",aaaa); printf("%lld\n",i); printf("%d\n",bb); exit(1); } } } gcc -std=c99でコンパイルしました。 結果は 1431440333 1431440334 1 のように表示されました。 データファイルは900MB以上あります。

  • テキストファイルのデータからバイナリを作りたい

    現在、テキストデータとしてCSVファイル1つあたり8バイトのデータが1000個ほどのデータが書かれているファイルがあります。このデータをバイナリファイルへ数値も変換して行きたいと思っています。 たとえば1個目のデータ”12345678”というテキストデータをバイナリの"12345678"に変換したらそれを0x00番地に並べて、そして2個目のデータ”87654321”というデータをバイナリにしたらそれを0x90離れた場所に置いていき、それを1000回繰り返して、結果をバイナリファイルで出力したいのですが、何か簡単にできるフリーソフトなどありませんでしょうか? また、プログラムとかでも簡単にできるのならそうしたいのですが、どうしたらよいか教えていただけないでしょうか?