可変長整数値
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 が表示されることは確認しましたが、何かエラーとか見つけた方はお知らせいただければです。