-
Notifications
You must be signed in to change notification settings - Fork 0
/
InterleaverEncoding.js
54 lines (45 loc) · 1.51 KB
/
InterleaverEncoding.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// 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;
}