ラベル ビット演算 の投稿を表示しています。 すべての投稿を表示
ラベル ビット演算 の投稿を表示しています。 すべての投稿を表示

2015年10月10日土曜日

複数バイトにまたがるビット演算

ADTS形式のAACファイルのヘッダ解析等において、複数バイトにまたがるビット列を解析したい場合があります。
今回はそのような場合におけるビット列の読み込み・書き込みの例題を示します。

bitbuffer.h/bitbuffer.cpp がビット演算を行うヘッダ及びソース。

sample.cpp にて ADTS形式のヘッダを生成するための例を用意しています(AAC LC 形式のヘッダ)。
また、生成した ADTS形式のヘッダの内容を解析して構造体に読み込み直すための例(ParseAdtsHeader 関数)も用意しています。
適当なADTS形式のAACファイルの解析を行う場合には、syncword 等により ADTSヘッダの先頭位置を検索し、ParseAdtsHeader 関数によりヘッダを読みこめば AACファイル内のチャンネル数やサンプリングレート等の情報を読み込むことができます。

bitbuffer.cpp では、InitiBitBuffer により解析に用いるバッファや長さを指定し、その中のビットを徐々にシフトしながら読み込み・書き込みを行っています。
指定された長さ以上の読み込みや書き込みを行おうとした際には、何も起きずにエラーが返ります。

sample.cpp bitbuffer.h bitbuffer.cpp 実行結果

2013年12月30日月曜日

ビット演算:ビットの置換

ビットを指定して置換する例題です。

以下の例題では、8ビット内の開始位置、長さを指定して値を挿入しています。
挿入する値が指定した長さのビットの値より大きい場合には、値を変更しないようになっています(repBits 内 bitsthr でのチェック)。 実行結果

2011年5月7日土曜日

ビットシフトによる掛算

ビットシフトによる掛算の例題です。

計算をループさせ、通常の掛け算との計算時間を比較していますが、通常の計算の方が早くなっています。
また、単純なビットシフトにより2の冪乗の計算も行っていますが、pow 関数による計算の方が早くもなっています。

特殊な計算が必要な場合以外には、掛け算として用いるのは得策ではないようです。


実行結果

2011年3月26日土曜日

共用体による1ビット毎のデータアクセス

共用体を用いて1バイトデータの各ビット毎にアクセスする例題です。

実行結果

2011年3月22日火曜日

CRC の計算

ランダムに生成された数値データに対し、誤りチェックのためのCRCを計算する例題です。

CRCでは、
(1)送信すべきビット列を2進数とみなし、
(2)検査用の2進数ビット列で割り算し、
(3)最後はあまりを出す。
という手順を取ります。

相手側には、送信すべきビット列と余りを送ります。
受信側でも同じ割り算を行い、余りが一致すれば正しく受信できたことになります。
(割り算と言っても「桁借り」の無い特殊な割り算です)

多項式:2進ビット列のビットは上に行くほど桁の重みが大きい。
    そこで、重みを考慮した多項式表示(足し算の形)で表現します。
(例)1011100111001011 (16bit)
   最上位は2^15、最下位は2^0=1です。
   
   すると上のビット列は
   x^15 + x^13 + x^12 + x^11 + x^8 + x^7 + x^6 + x^3 + x + 1 (x=2)
   で表せます。
これが(送信すべきビット列の)多項式です。

生成多項式:検査用のビット列(割る数)も同じように多項式の形で表します。
      (余りを生成するもとの式という意味で)生成多項式と呼びます。

例題では、多項式を用い直接計算する方式と(calculateCRC16)と、余剰テーブルを用いて高速化を図った方式(calculateCRC16t/calculateCRC32t)の2種類の計算を行っていますが、それぞれの結果は同じです。
配列のサイズが大きくなると計算量も大きくなるため、このような工夫が取られています。
また、検査用ビット数を16/32ビットとした計算の2種類用意しています。

生成された配列にCRCを付与した配列に対し、再度CRCを計算(CRCデータも含め)するとCRCが0になることを確認することにより、CRCの計算結果が正しいことが確認できます。

CRCを配列に格納する場合のバイトオーダーは、ビッグエンディアンで格納する必要があります。
ネットワークでやり取りされるデータは、通常ビッグエンディアンになりますので、ホスト内のバイトオーダーとは異なる点に注意が必要です。
例題では、htons/htonl 関数により、16/32 ビットのデータをビッグエンディアンに変更し格納しています。

ソース等をまとめたもの:DL

crc.h

crc.cpp

crcTest.cpp

実行結果

2011年3月21日月曜日

半角・全角カナ文字の変換

SJIS ファイル中に含まれる半角カナ文字を全角に変換する例題です。
小文字の英単語も大文字に変換を行っています。
例題に用いられたテキストは SJIS で保存を行ってください。


hankaku.txt
英数字を含む文字列:

When he smiled with NIYARI, he lifted the glasses of a black spot and
floated a haughty expression. Where [ of such a fellow ] will be said
"Really trust"? A command of a superior official still cannot oppose
absolutely and poor. It is being [ such YATSU- of I CHI O U - /
asuperior official ] DA mosquito RA-. The moment such thinking emerged
on the head, it has appeared in expression. It seems that he also has
full knowledge of my thinking enough by years of association, and the
present thinking is also already read. When considering soon, my life
began to turn around a corner of a street greatly from this
moment. Although it is the thing of the future, it will be known
personally that just the slack of this momentary mind was fatal.

日本語文章(半角カナ含む):

彼はニヤリと微笑むと、黒斑の眼鏡を持ち上げ不遜な表情を浮かべた。一体、こんな
奴のどこを信用しろと言うのであろうか?それでも、上司の命令は絶対であり下
手に逆らうことはできない。こんなヤ・ツ・でも、イ・チ・オ・ウ・は、上司なのダ・カ・ラ・。と、
そんな思考が頭に浮かび上がった瞬間、それが表情に出てしまった。長年の付き
合いで彼は私の思考も十分熟知しており、現在の思考もすでに読まれているよ
うだ。今に思えばこの瞬間から、私の人生は大きく曲がり角を回り始めたのであ
る。後々のことであるが、この一瞬の気の緩みこそが命取りであった、というこ
とを身をもって知ることになる。

実行結果
% ./list_xxx
英数字を含む文字列:

WHEN HE SMILED WITH NIYARI, HE LIFTED THE GLASSES OF A BLACK SPOT AND
FLOATED A HAUGHTY EXPRESSION. WHERE [ OF SUCH A FELLOW ] WILL BE SAID
"REALLY TRUST"? A COMMAND OF A SUPERIOR OFFICIAL STILL CANNOT OPPOSE
ABSOLUTELY AND POOR. IT IS BEING [ SUCH YATSU- OF I CHI O U - /
ASUPERIOR OFFICIAL ] DA MOSQUITO RA-. THE MOMENT SUCH THINKING EMERGED
ON THE HEAD, IT HAS APPEARED IN EXPRESSION. IT SEEMS THAT HE ALSO HAS
FULL KNOWLEDGE OF MY THINKING ENOUGH BY YEARS OF ASSOCIATION, AND THE
PRESENT THINKING IS ALSO ALREADY READ. WHEN CONSIDERING SOON, MY LIFE
BEGAN TO TURN AROUND A CORNER OF A STREET GREATLY FROM THIS
MOMENT. ALTHOUGH IT IS THE THING OF THE FUTURE, IT WILL BE KNOWN
PERSONALLY THAT JUST THE SLACK OF THIS MOMENTARY MIND WAS FATAL.

日本語文章(半角カナ含む):

彼はニヤリと微笑むと、黒斑の眼鏡を持ち上げ不遜な表情を浮かべた。一体、こんな
奴のどこを信用しろと言うのであろうか?それでも、上司の命令は絶対であり下
手に逆らうことはできない。こんなヤ・ツ・でも、イ・チ・オ・ウ・は、上司なのダ・カ・ラ・。と、
そんな思考が頭に浮かび上がった瞬間、それが表情に出てしまった。長年の付き
合いで彼は私の思考も十分熟知しており、現在の思考もすでに読まれているよ
うだ。今に思えばこの瞬間から、私の人生は大きく曲がり角を回り始めたのであ
る。後々のことであるが、この一瞬の気の緩みこそが命取りであった、というこ
とを身をもって知ることになる。

%

2011年3月20日日曜日

10進・2進文字列の変換

10進・2進文字列の変換を行う例題です。

相互変換した結果を表示しています。


実行結果

2011年3月16日水曜日

10進・16進[文字列]の変換(バイナリデータからアスキーテキストへの変換)

10進数字から16進文字列への変換(1234 → "04 D2")、
16進文字列から10進数字への変換("04 02" → 1234)、
を行う例題です。

16進数のデータはchar型データの文字列として扱います。
バイナリエディタなどでは、char 型で扱われる 0〜255 までの文字を1バイトずつ printf にて %x 形式で出力すれば良い話です。
一方古い通信機器等では、通信を行う際の形式がアスキー形式かつ1バイト(char)を変換した "AA" ではなく、2バイト(short)、4バイト(int)等の場合があり、一文字のデータを送る場合にも "000000AA" のように "00" 文字を埋めた形のアスキーテキストを送る必要があります。
また、そのアスキーデータを受信した後にバイナリデータとして変換する必要があります。

例題では、バイナリダンプで行うような1バイトずつの16進文字列への変換と、変換するバイト数(1バイト・8バイト)を指定した変換を行っています。
バイナリダンプを行うような場合は、hexdump/dump2char 関数のみを参考にしてください。

バイト数を指定する例ではバイトオーダーを考慮し、リトルエンディアン[最下位のバイト順](Intel) の並びで変換が行われた結果が表示されています(Intel OSX)。
バイトオーダーの違いによるバイト列の並びは以下のようなものです。
例:2バイト(16ビット)の数値(1)
ビッグエンディアン  00000000 00000001  (Byte4:Byte3:Byte2:Byte1)
リトルエンディアン  00000001 00000000  (Byte1:Byte2:Byte3:Byte4)

実行結果