GF2::Vector — Encode a Bit-Vector as a String.

Methods to encode a bit-vector as a string in a binary or hex format.

std::string
to_string(bool bit_order=false, char off='0', char on='1') const;   (1)

std::string to_bit_order(char off='0', char on='1') const;          (2)

std::string to_hex() const;                                         (3)
1 Get a binary-string representation for the bit-vector using the given characters for set and unset elements.
2 Get a binary-string representation for the bit-vector in bit-order using the given characters for set and unset elements.
3 Get a hex-string representation for the bit-vector.
Parameters

bit_order

Defaults to false but if true the bit-vector is encoded with v0, the least significant element on the right. By default for a GF2::Vector it is printed on the left. This parameter is only for binary strings.

on, off

The characters to use for set and unset elements in binary encodings. Defaults to the usual 1 and 0. Characters for hex-strings are fixed to the standard set of 0123456789ABCDE.

Hex strings for bit-vectors whose size is not a muliple of 4

The most straightforward character encoding for any bit-vector is a binary string containing just 0’s and 1’s, e.g. "10101". We allow for an optional prefix "0b" or "0B" to act as a visual clue to the string’s contents, e.g. "0b10101". Apart from the optional prefix, each character in the binary string will translate to one element in the vector.

The other supported encoding is a compact hex type string containing just the 16 hex characters 0123456789ABCDEF. For example, the string "3ED02". Again, we allow for an optional prefix "0x" or "0X" e.g. "0x3ED02".

Each hex character naturally translates to 4 elements in a GF2::Vector. The hex string "0x0" is equivalent to the binary string "0b0000", and so on, up to string "0xF" which is the same as the binary "0b1111".

The hex pair "0x0F" will be interpreted in the vector as 0b00001111. This is of course the advantage of hex—​it is a more compact format that occupies a quarter of the space needed to write out a full binary string.

However, what happens if you want to encode a vector whose size is not a multiple of 4? We handle that by allowing the final character in the string to have a base that is not 16. This is achieved by allowing for an optional suffix which must be one of "_2", "_4", or "_8". If present, the prefix gives the base for just the _final_ character in the otherwise hex based string. If there is no suffix the final character is assumed to be hex just like all the others.

So the string "0x1" (no suffix so the last character is the default hex base 16) is equivalent to "0b0001". On the other hand, the string "0x1_8" (the last character is base 8) is equivalent to "0b001". Similarly the string "0x1_4" (the last character is base 4) is equivalent to "0b01" and finally, the string "0x1_2" (the last character is base 2) is equivalent to "0b1"

In the string "0x3ED01_8", the first four characters '3', 'E', 'D', and '0' are interpreted as hex values and each will consume four slots in the vector. However, that final "1_8" is parsed as an octal 1 so only takes up three slots 0b001. In all then this particular vector has size 4 x 4 + 3 = 19.

If the suffix is present, the final character must fit inside the base given by that suffix. The string "0x3_8" is fine but trying to parse "0x3_2" will result in a std::invalid_argument exception as the final character is not either 0 or 1 which are the only valid options for something that is supposed to be base 2.
Example: Binary encodings
#include <GF2/GF2.h>
int main()
{
    GF2::Vector v(32, [&](size_t k) { return (k + 1) % 2; });   (1)
    std::cout << "v: " << v.to_string() << '\n';                (2)
    std::cout << "v: " << v.to_bit_order() << '\n';             (3)
    std::cout << "v: " << v.to_bit_order('.', '-') << '\n';     (4)
}
1 v has all the even elements set to 1.
2 Printing v in vector_order using the default 0’s and 1’s for the element values. v0 is on the left.
3 Printing v in bit_order using the default 0’s and 1’s for the element values. v0 is on the right.
4 Printing v in bit_order using dots and dashes for the element values. v0 is on the right.
Output
v: 10101010101010101010101010101010
v: 01010101010101010101010101010101
v: .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
Example: Hex encodings
#include <GF2/GF2.h>

int main()
{
    auto v5 = GF2::Vector<>::ones(5);
    auto v6 = GF2::Vector<>::ones(6);
    auto v7 = GF2::Vector<>::ones(7);
    auto v8 = GF2::Vector<>::ones(8);
    auto v9 = GF2::Vector<>::ones(9);
    std::cout << "v5: " << v5.to_string() << "\t hex: " << v5.to_hex() << '\n';
    std::cout << "v6: " << v6.to_string() << "\t hex: " << v6.to_hex() << '\n';
    std::cout << "v7: " << v7.to_string() << "\t hex: " << v7.to_hex() << '\n';
    std::cout << "v8: " << v8.to_string() << "\t hex: " << v8.to_hex() << '\n';
    std::cout << "v9: " << v9.to_string() << "\t hex: " << v9.to_hex() << '\n';
}
Output
v5: 11111        hex: F1_2
v6: 111111       hex: F3_4
v7: 1111111      hex: F7_8
v8: 11111111     hex: FF
v9: 111111111    hex: FF1_2
Example: Reconstituting bit-vectors from hex encodings
#include <GF2/GF2.h>

int main()
{
    auto v5 = GF2::Vector<>::random(5);     (1)
    auto v6 = GF2::Vector<>::random(6);
    auto v7 = GF2::Vector<>::random(7);
    auto v8 = GF2::Vector<>::random(8);
    auto v9 = GF2::Vector<>::random(9);

    GF2::Vector<> u5(v5.to_hex());          (2)
    GF2::Vector<> u6(v6.to_hex());
    GF2::Vector<> u7(v7.to_hex());
    GF2::Vector<> u8(v8.to_hex());
    GF2::Vector<> u9(v9.to_hex());

    std::cout << "v5 " << v5 << "\t u5 " << u5 << (v5 == u5 ? "\t match " : "\t FAIL") << '\n';
    std::cout << "v6 " << v6 << "\t u6 " << u6 << (v6 == u6 ? "\t match " : "\t FAIL") << '\n';
    std::cout << "v7 " << v7 << "\t u7 " << u7 << (v7 == u7 ? "\t match " : "\t FAIL") << '\n';
    std::cout << "v8 " << v8 << "\t u8 " << u8 << (v8 == u8 ? "\t match " : "\t FAIL") << '\n';
    std::cout << "v9 " << v9 << "\t u9 " << u9 << (v9 == u9 ? "\t match " : "\t FAIL") << '\n';
}
1 Set up some bit-vectors of various lengths with random 50-50 fills.
2 Convert the bit-vectors to hex-strings and use those to construct bit-vectors. Check that the two sets of vectors match.
Output
v5 01011         u5 01011        match
v6 000111        u6 000111       match
v7 1101011       u7 1101011      match
v8 11010110      u8 11010110     match
v9 110111001     u9 110111001    match