@port139 Blog

基本的にはデジタル・フォレンジックの技術について取り扱っていますが、記載内容には高確率で誤りが含まれる可能性があります。

可変長整数値

SQLite3ではデータタイプを示すのに Variable Length Integer Format という形式が使われているんですが、これの日本語訳は何が適切なんでしょうかね?ここではとりあえず可変長整数としておきますが...

2.3.2 Database Record Format
http://www.sqlite.org/fileformat.html#varint_format

たとえば、「abcdefg」という7文字がテキストフィールドに保存されている場合、SQLite3 では次の計算によってその長さがタイプの値として保存されます。
あ、いま気がついたけど昨日の FNG09 での説明を間違えてますね...orz、タイプの値として12以上で奇数値の場合には、SQLITE_TEXT と判断するということで、偶数の場合には SQLITE_BLOB タイプということですね!?(昨日はいつ偶数になるのか?という話題が出てましたが、そもそも偶数になるパターンは型が違うってことですね)

ということで?、レコードヘッダのタイプで 12 以上の奇数値値は SQLITE_TEXT タイプとして考えると、まず文字列のバイト数 × 2 を行い、7 × 2 = 14 を算出し、次に SQLITE_TEXT タイプなので +13 します。

( 7 x 2 )+ 13 = 27(0x1B)

SQLite3のレコードヘッダのタイプとして、0x1B という値が定義されている場合、続くデータ部分で何バイト分がこのデータタイプなのかを確認するには、逆算することになり、奇数なので -13 してから値を ÷ 2 とします。

(27 - 13) / 2 = 7

値が小さい場合には簡単なのですが、例えば 1,000 バイト長の半角英数文字列が UTF-8 で入力されている場合には、次の計算になります。

例えば可変長整数で 1,000 バイトのテキストの長さを示す値として定義される値は 0x8F 5D になります。2バイト(14 bit)のビットパターンは 1xxxxxxx 0xxxxxxx と定義されていますので以下のように算出することになります。

(1000 x 2 ) +13 = 2013(0x7DD)
2進数だと 0000 0111 1101 1101 になります。

2バイトのビットパターンを適用すると

00000111 11011101
1xxxxxxx 0xxxxxxx

10001111 01011101

8F 5D

0x8F 5D を 1,000 に戻すにはイカ以下のようになります。

8F 5D

1000 1111 0101 1101

00 0111 1101 1101 = 7DD

7DD = 2013 → (2013 ‐ 13)/ 2 = 1,000byte

赤字のビット部分は、以降のバイトも継続して含めるかどうかのフラグになりますので、最初の 1 で次のバイトも含まれることがわかります、次のバイトでは 0 ですのでデータがここまでということがわかります。赤色のビット部分は計算には含めませんので、計算するビット部分だけを残してマスクすると 0x7DD になります。

なんとなく戻せているので OK な気がしていますが、誤り等ありましたら教えていただければです。<1/18 追記>
隣の席な人が、計算してくれるツール(VLICalculator.exe)を作ってくれました!!以下の URL からダウンロードできますが、実行には .NET Framework が必要だと思います。

VLICalculator.exe
http://www.ji2.co.jp/forensics/tools/index.html

とりあえず、8F5D を入力すると 2013 と 1000 が表示されることは確認しましたが、何かエラーとか見つけた方はお知らせいただければです。