54 lines
1.5 KiB
JavaScript
54 lines
1.5 KiB
JavaScript
// InterleaverEncoding
|
|
|
|
// Rolls / shifts elements of an array so that each
|
|
// block of N data elements contains the minimal
|
|
// amount of original data possible.
|
|
// Elements toward the end of an array are wrapped
|
|
// around to the beginning
|
|
|
|
// This is primarily used for data transfer where
|
|
// multiple channels representing various bits in
|
|
// the same block may be subsceptable to noise and
|
|
// provide the wrong value for one or more bits in
|
|
// a block
|
|
|
|
let BLOCK_SIZE = 1;
|
|
|
|
export const blockSize = () => ({
|
|
encoded: BLOCK_SIZE,
|
|
decoded: BLOCK_SIZE
|
|
});
|
|
|
|
export const changeConfiguration = ({
|
|
blockSize
|
|
}) => {
|
|
BLOCK_SIZE = blockSize ?? 1;
|
|
}
|
|
|
|
export const decode = bits => encode(bits, true);
|
|
|
|
export const encode = (bits, undo = false) => {
|
|
// Block sizes of 1 or less are unable to move bits
|
|
if(BLOCK_SIZE <= 1) return bits;
|
|
|
|
// We need at least 1 extra bit for one bit to escape the block
|
|
if(bits.length <= BLOCK_SIZE ) return bits;
|
|
|
|
// loop through indexes of a block
|
|
for(let blockMovement = 1; blockMovement < BLOCK_SIZE; blockMovement++) {
|
|
// Move every N bit N blocks over...
|
|
bits.filter((_, i) =>
|
|
// values to be moved to different blocks
|
|
i % BLOCK_SIZE === blockMovement
|
|
).map((_,i,a) => {
|
|
// values moved N blocks
|
|
if(undo) i -= blockMovement; else i += blockMovement;
|
|
i = ((i % a.length) + a.length) % a.length;
|
|
return a[i];
|
|
}).forEach((v, i) => {
|
|
// replace with new values
|
|
bits[blockMovement + (i * BLOCK_SIZE)] = v;
|
|
})
|
|
};
|
|
return bits;
|
|
} |