• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C言語のビット演算をPHPでやりたいです。)

C言語のビット演算をPHPで実装する方法

このQ&Aのポイント
  • C言語のビット演算をPHPで実装する方法を教えてください。
  • 具体的には、bitを左シフトしている箇所と - 0x30の箇所をどのように書けば良いのかわかりません。
  • また、Value[i]の配列内には整数が1桁ずつ格納されています。この配列からビット演算を行い、最終的な結果を求めたいです。

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

  • ベストアンサー
  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.7

function MakeScramble($nVers, $nScramble, &$Value) { $Cnt1 = $Cnt2 = $Cnt3 = 0; $c = array_values(unpack('C*', $Value)); for ($i=0, $j=1; $i<=28; $i++) { if ($i==4 || $i==9 || $i==18 || $i==21 || $i==28) { $j ++; continue; } $Cnt1 += bit_count_as_byte($c[$i] & 0xAA); if ( $j == 2 || $j == 5 ) { $Cnt2 += bit_count_as_byte($c[$i]); } if( (10<=$i && $i<=13) || $j == 4 || $j == 5 ) { $Cnt3 += $c[$i] - 0x30; } } return $Value .= sprintf('%d%d%04d', $nVers, $nScramble, (($Cnt1 + $Cnt2)*2) + $Cnt3); } function bit_count_as_byte($byte) { $byte = ($byte & 0x55) + (($byte >> 1) & 0x55); $byte = ($byte & 0x33) + (($byte >> 2) & 0x33); return ($byte + ($byte >> 4)) & 0xF; } ============================================================================= $Value = 'C01R-0021-20101119-01-011456-'; MakeScramble(1, 1, $Value); var_dump($Value); これで、同じ動作になっていると思います。 PHP で文字コードを取り出す場合は ord や unpack などがありますので、それらを通してやれば、後は C と同じです。 注意点としては、数値文字列に対する関数も多く用意されているので、それらと混同しないように気をつけてください。

cubic037
質問者

お礼

yuu_xさん、ありがとうございます!! Cとまったく同じ値が出るようになりました! これでずっと何日も悩んでいたので本当に感謝です。 すでに納期がかなり迫ってきていたので 涙が出そうなくらいうれしいです。 明日から残りの開発に邁進できそうです。 本当にありがとうございました!

その他の回答 (7)

  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.8

補足 pdf の説明と C のプログラムに食い違いがありましたので、C のプログラムにあわせて書いてありますが、pdf の説明に合わせる場合は、 if( (10<=$i && $i<=13) || $j == 4 || $j == 5 ) { $Cnt3 += $c[$i] - 0x30; } の部分を if( $j == 3 || $j == 4 || $j == 5 ) { $Cnt3 += $c[$i] - 0x30; } としてください。

  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.6

> 掲載いたしましたが実際にはValue[0]とValue[3]はアルファベットが入っています。 なんとなくそんな気はしてたんですが、配列の値が整数ではなく数字文字ということはないですか? もし、そうだとするなら、$Value を $Value = array_map( 'ord', array (1, 0, 1, 1, 2, 0, 0, 2, 1, 8, 2, 0, 0, 9, 1, 2, 1, 1, 4, 0, 1, 3, 1, 0, 4) ); // 念のため、他の部分も $Cnt1 = $Cnt2 = 0; for ($i=0; $i<=24; $i++) { for($j=0,$bit=1; $j<8; $j++,$bit<<=1) { if($Value[$i] & $bit) { if(($j%2)==1) { $Cnt1 ++; } } } $Cnt2 += ($Value[$i] - 0x30); } $Ans = $Cnt1 + $Cnt2; としてみてください。 0xD0 は見当違いだったようなので - 0x30 の部分はそのままにしてください。 何のプログラムか分からないので、または外してるかもしれないけど。 差し障りなければ、質問文にある配列で実行したときの Ans を教えてもらえると考えやすかったりします。

cubic037
質問者

補足

ありがとうございます。 結果の値は違っていましたがかなり違いです!! あともう少しな感じがしてきました。 でもやはりもっとソースコードをお見せしないと ご相談もうまくできないので下記のURLにソースと 求めたい結果の値を掲載いたしました。 重要な部分は除いてありますが、お伝えしたいことは これでほぼ分かると思います。 http://sample.flop.jp/sample.pdf お手数をおかけいたしますが こちらを見ていただけると幸いです。

  • t140
  • ベストアンサー率39% (59/150)
回答No.5

なるほどValueってのはchar型なんですね。 これだとどうですか? $Value = array(1, 0, 1, 1, 2, 0, 0, 2, 1, 8, 2,0,0,9,1,2,1,1,4,0,1,3,1,0,4); $Cnt1 = $Cnt2 = 0; for($i=0; $i<=24; $i++) { for($j=0,$bit=1; $j<8; $j++,$bit<<=1) { if(ord($Value[$i]) & $bit) { if(($j%2)==1) { $Cnt1++; } } } $Cnt2 += $Value[$i]; } $Ans = $Cnt1 + $Cnt2; echo $Ans;

cubic037
質問者

お礼

何とか解決しました! t140さん、一緒に考えてくださりありがとうございました。

cubic037
質問者

補足

ありがとうございます。 しかし値がだいぶ大きくなり違うようです・・・。 やはりもっとソースコードをお見せしないと ご相談もうまくできないので下記のURLにソースと 求めたい結果の値を掲載いたしました。 重要な部分は除いてありますが、お伝えしたいことは これでほぼ分かると思います。 http://sample.flop.jp/sample.pdf お手数をおかけいたしますが こちらを見ていただけると幸いです。

  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.4

$Value[$i] - 0x30 を $Value[$i] + 0xDO でやったらどうなりますか?

cubic037
質問者

補足

回答ありがとうございます! $Value[$i] + 0xD0 でやってみたのですが 結果の値がやはり異なるようです。 C言語でのプログラムの方は例として結果が146だとすると PHPでのプログラムの方は(+ 0xD0の場合)812になります。 質問には例としてValue[i]の中には0から9までの整数が入るとして 掲載いたしましたが実際にはValue[0]とValue[3]はアルファベットが入っています。 それも関係ありますでしょうか?

  • t140
  • ベストアンサー率39% (59/150)
回答No.3

$cnt2 += ($Value[$i] - 0x30); これでいいと思いますが、結果どんな感じでしょうか?

cubic037
質問者

補足

回答ありがとうございます! $cnt2 += ($Value[$i] - 0x30); でやってみたのですが C言語でのプログラムの結果とまったく異なる値が返ってきてしまいます。 計算の経過をechoで取ってみたのですが $Valueが0のとき - 0x30 することで -48 になり $Valueが1のとき - 0x30 することで -47 になり 結果 大きなマイナス数値が返ってきます。 C言語の方はプラスの整数になります。 ソースを公開できないためうまく説明できずすみません。 C言語のプログラムを作成した人にもコンタクトを取って相談してみます。 その結果をまたご連絡させていただきます。

  • t140
  • ベストアンサー率39% (59/150)
回答No.2

宣言部分のソースが載ってないので初期値がわからないのと結果が何になるかがわからないですが、 まずbit<<=1と代入してあるので$bit<<1ではなく$bit<<=1としましょう。 0x30はただ単に整数定数の16進表現を引いているだけなのでそのままでいいと思います。

cubic037
質問者

補足

すみません、ソースをすべて公開することができず 抜粋にて掲載させていただきました。 分かりづらくすみません! 「0x30はただ単に整数定数の16進表現を引いているだけなのでそのままでいい」 というのは、下記のコードのように何もしなくていいということなのでしょうか? $cnt2 += $Value[$i]; それともPHPでも同様に下記のように書くということなのでしょうか? $cnt2 += ($Value[$i] - 0x30); よろしくお願いいたします。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

まずはこちら

参考URL:
http://www.php.net/manual/ja/language.operators.bitwise.php
cubic037
質問者

補足

回答ありがとうございます! 教えていただいたページを見ながら自分なりにコードを書いてみたのですが C言語での結果の値と異なってくるのでやっぱり違うみたいです。 下記のコードが自分なりにPHPに書き直してみたコードなのですが どのように違うのか教えていただけるとうれしいです。 それとも全く違うのか・・・。 何となくデータ型に問題があるような気がするのですがどうなんでしょう? ご教授よろしくお願いいたします。 【PHP】 for($i=0; $i<=24; $i++) { for($j=0,$bit=1; $j<8; $j++,$bit<<1) { if($Value[$i] & $bit) { if(($j%2) == 1) { $cnt1 ++; } } } $cnt2 += hexdec($Value[$i]); } $ans = $cnt1 + $cnt2;

関連するQ&A

専門家に質問してみよう