compress function
Compress v into a bytestring of length slen.
Returns null when the encoding does not fit in slen bytes (the
reference returns False in that case).
Implementation
Uint8List? compress(List<int> v, int slen) {
// Bit string built as a list of 0/1, matching the reference's string `u`.
final List<int> bits = <int>[];
for (final int coef in v) {
final int abs = coef.abs();
// Sign bit: '1' if negative, else '0'.
bits.add(coef < 0 ? 1 : 0);
// 7 low bits of abs(coef), MSB-first.
final int low = abs & 0x7f;
for (int i = 6; i >= 0; i--) {
bits.add((low >> i) & 1);
}
// High bits in unary: (abs >> 7) zeros, then a terminating '1'.
final int high = abs >> 7;
for (int i = 0; i < high; i++) {
bits.add(0);
}
bits.add(1);
}
final int totalBits = 8 * slen;
// The encoding is too long to fit.
if (bits.length > totalBits) {
return null;
}
// Zero-pad to the full byte length.
while (bits.length < totalBits) {
bits.add(0);
}
// Pack MSB-first into bytes.
final Uint8List out = Uint8List(slen);
for (int i = 0; i < slen; i++) {
int byte = 0;
for (int j = 0; j < 8; j++) {
byte = (byte << 1) | bits[8 * i + j];
}
out[i] = byte;
}
return out;
}