42 lines
1.0 KiB
C
42 lines
1.0 KiB
C
#include "liblocky.h"
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
|
|
|
|
void blky_encoder_feed(blky_encoder_t* enc, uint8_t data) {
|
|
assert(enc);
|
|
assert(enc->block_num > 0);
|
|
assert(enc->feat_bits > 0);
|
|
assert(enc->feat_bits <= sizeof(enc->scrap)*8);
|
|
assert(enc->seed > 0);
|
|
|
|
if (enc->count++ == 0) enc->scrap_bits = 1;
|
|
|
|
assert(enc->scrap_bits+8 <= 32);
|
|
enc->scrap |= data << enc->scrap_bits;
|
|
enc->scrap_bits += 8;
|
|
}
|
|
|
|
bool blky_encoder_pop(blky_encoder_t* enc, uint32_t* feat, bool force) {
|
|
assert(enc);
|
|
assert(feat);
|
|
|
|
if (force) {
|
|
if (enc->scrap_bits > 0) return false;
|
|
} else {
|
|
if (enc->scrap_bits < enc->feat_bits) return false;
|
|
}
|
|
|
|
const uint32_t feat_max = 1 << enc->feat_bits;
|
|
assert(feat_max < enc->block_num);
|
|
|
|
enc->seed = blky_numeric_xorshift64(enc->seed);
|
|
*feat = blky_numeric_hop(enc->block_index, enc->scrap%feat_max, enc->seed)%enc->block_num;
|
|
|
|
enc->block_index = *feat;
|
|
enc->scrap >>= enc->feat_bits;
|
|
enc->scrap_bits -= enc->feat_bits;
|
|
return true;
|
|
}
|