hiro99ma blog

何か技術的なこと

値の表現

最終更新日: 2024/12/11

数値は 2の補数の little endian で表す。
固定長の場合はそのバイト数のデータ型、可変長は Compact Size型が使われている。

Compact Size型はあまり見慣れないと思う。
例えば 0xfc までなら 1バイトでそのまま表現できるが、0xfd0xfdfd00(little endian)になる。
データ長を表すのに使われることがほとんどだと思う。

gist

uint64_t varint(const uint8_t *p_varint)
{
    uint64_t val;
    if (p_varint[0] < 0xfd) {
        val = p_varint[0];
    } else if (p_varint[0] == 0xfd) {
        val = ((uint16_t)p_varint[2] << 8) | (uint16_t)p_varint[1];
    } else if (p_varint[0] == 0xfe) {
        val = ((uint32_t)p_varint[4] << 24) |
              ((uint32_t)p_varint[3] << 16) |
              ((uint32_t)p_varint[2] <<  8) |
               (uint32_t)p_varint[1];
    } else {
        val = ((uint64_t)p_varint[8] << 56) |
              ((uint64_t)p_varint[7] << 48) |
              ((uint64_t)p_varint[6] << 40) |
              ((uint64_t)p_varint[5] << 32) |
              ((uint64_t)p_varint[4] << 24) |
              ((uint64_t)p_varint[3] << 16) |
              ((uint64_t)p_varint[2] <<  8) |
               (uint64_t)p_varint[1];
    }
    return val;
}

VarInt, varint, var_int

Compact Size型という名称だが、BIP には VarIntvarint もあれば var_int として書かれているところもある。
GitHub の BIP を検索したところこういう状況だった。
あまり区別されていないようなので、Bitcoin 関連でこれらの型が出てきたらだいたい Compact Size型だと思ってよいのではなかろうか。

スクリプトの中に数値が使われる場合は命令と組み合わせて使うため Compact Size型とは別の表現になる(Constants)。
LevelDBにVarIntがあるが、あれとは関係ない。

< Top page