Skip to content

Commit c2b570f

Browse files
committed
chore: use uint32 to simplify the code
1 parent 18b23d8 commit c2b570f

File tree

2 files changed

+30
-33
lines changed

2 files changed

+30
-33
lines changed

test/lt.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { binaryToBlock, blockToBinary, createDecoder, encodeFountain } from '../
66

77
it('slice binary', async () => {
88
const input = (await fs.readFile(join('test', 'SampleJPGImage_100kbmb.jpg'), null)).buffer
9-
const data = new Uint8Array(input)
9+
const data = new Uint32Array(input)
1010

1111
const decoder = createDecoder()
1212
let count = 0
@@ -24,6 +24,6 @@ it('slice binary', async () => {
2424

2525
const result = decoder.getDecoded()!
2626
expect(result).toBeDefined()
27-
expect(result).toBeInstanceOf(Uint8Array)
27+
expect(result).toBeInstanceOf(Uint32Array)
2828
expect(result.length).toBe(data.length)
2929
})

utils/lt-codes.ts

+28-31
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,33 @@ interface EncodingMeta {
1515

1616
interface EncodingBlock extends EncodingMeta {
1717
indices: number[]
18-
data: Uint8Array
18+
data: Uint32Array
1919
}
2020

21-
export function blockToBinary(block: EncodingBlock): Uint8Array {
21+
export function blockToBinary(block: EncodingBlock): Uint32Array {
2222
const { k, length, sum, indices, data } = block
23-
const header = new Uint32Array([
23+
const header = [
2424
indices.length,
2525
...indices,
2626
k,
2727
length,
2828
sum,
29-
])
30-
const binary = new Uint8Array(header.length * 4 + data.length)
31-
let offset = 0
32-
binary.set(new Uint8Array(header.buffer), offset)
33-
offset += header.length * 4
34-
binary.set(data, offset)
29+
]
30+
const binary = new Uint32Array(header.length + data.length)
31+
binary.set(header)
32+
binary.set(data, header.length)
3533
return binary
3634
}
3735

38-
export function binaryToBlock(binary: Uint8Array): EncodingBlock {
39-
const degree = new Uint32Array(binary.buffer, 0, 4)[0]!
40-
const headerRest = Array.from(new Uint32Array(binary.buffer, 4, degree + 3))
41-
const indices = headerRest.slice(0, degree)
36+
export function binaryToBlock(binary: Uint32Array): EncodingBlock {
37+
const degree = binary[0]!
38+
const indices = Array.from(binary.slice(1, degree + 1))
4239
const [
4340
k,
4441
length,
4542
sum,
46-
] = headerRest.slice(degree) as [number, number, number]
47-
const data = binary.slice(4 * (degree + 4))
43+
] = Array.from(binary.slice(degree + 1)) as [number, number, number]
44+
const data = binary.slice(degree + 1 + 3)
4845
return {
4946
k,
5047
length,
@@ -55,7 +52,7 @@ export function binaryToBlock(binary: Uint8Array): EncodingBlock {
5552
}
5653

5754
// CRC32 checksum
58-
function checksum(data: Uint8Array): number {
55+
function checksum(data: Uint32Array): number {
5956
let crc = 0xFFFFFFFF
6057
for (let i = 0; i < data.length; i++) {
6158
crc = crc ^ data[i]!
@@ -92,25 +89,25 @@ function getRandomIndices(k: number, degree: number): number[] {
9289
return Array.from(indices)
9390
}
9491

95-
function xorUint8Array(a: Uint8Array, b: Uint8Array): Uint8Array {
96-
const result = new Uint8Array(a.length)
92+
function xorUint32Array(a: Uint32Array, b: Uint32Array): Uint32Array {
93+
const result = new Uint32Array(a.length)
9794
for (let i = 0; i < a.length; i++) {
9895
result[i] = a[i]! ^ b[i]!
9996
}
10097
return result
10198
}
10299

103-
function sliceData(data: Uint8Array, blockSize: number): Uint8Array[] {
104-
const blocks: Uint8Array[] = []
100+
function sliceData(data: Uint32Array, blockSize: number): Uint32Array[] {
101+
const blocks: Uint32Array[] = []
105102
for (let i = 0; i < data.length; i += blockSize) {
106-
const block = new Uint8Array(blockSize)
103+
const block = new Uint32Array(blockSize)
107104
block.set(data.slice(i, i + blockSize))
108105
blocks.push(block)
109106
}
110107
return blocks
111108
}
112109

113-
export function *encodeFountain(data: Uint8Array, indiceSize: number): Generator<EncodingBlock> {
110+
export function *encodeFountain(data: Uint32Array, indiceSize: number): Generator<EncodingBlock> {
114111
const sum = checksum(data)
115112
const indices = sliceData(data, indiceSize)
116113
const k = indices.length
@@ -123,10 +120,10 @@ export function *encodeFountain(data: Uint8Array, indiceSize: number): Generator
123120
while (true) {
124121
const degree = getRandomDegree(k)
125122
const selectedIndices = getRandomIndices(k, degree)
126-
let encodedData = new Uint8Array(indiceSize)
123+
let encodedData = new Uint32Array(indiceSize)
127124

128125
for (const index of selectedIndices) {
129-
encodedData = xorUint8Array(encodedData, indices[index]!)
126+
encodedData = xorUint32Array(encodedData, indices[index]!)
130127
}
131128

132129
yield {
@@ -142,7 +139,7 @@ export function createDecoder(blocks?: EncodingBlock[]) {
142139
}
143140

144141
export class LtDecoder {
145-
public decodedData: (Uint8Array | undefined)[] = []
142+
public decodedData: (Uint32Array | undefined)[] = []
146143
public decodedCount = 0
147144
public encodedBlocks: Set<EncodingBlock> = new Set()
148145
public meta: EncodingBlock = undefined!
@@ -172,7 +169,7 @@ export class LtDecoder {
172169

173170
for (const index of indices) {
174171
if (this.decodedData[index] != null) {
175-
data = xorUint8Array(data, this.decodedData[index]!)
172+
data = xorUint32Array(data, this.decodedData[index]!)
176173
indices = indices.filter(i => i !== index)
177174
}
178175
}
@@ -190,16 +187,16 @@ export class LtDecoder {
190187
return this.decodedCount === this.meta.k
191188
}
192189

193-
getDecoded(): Uint8Array | undefined {
190+
getDecoded(): Uint32Array | undefined {
194191
if (this.decodedCount !== this.meta.k) {
195192
return
196193
}
197194
if (this.decodedData.some(block => block == null)) {
198195
return
199196
}
200197
const indiceSize = this.meta.data.length
201-
const blocks = this.decodedData as Uint8Array[]
202-
const decodedData = new Uint8Array(this.meta.length)
198+
const blocks = this.decodedData as Uint32Array[]
199+
const decodedData = new Uint32Array(this.meta.length)
203200
blocks.forEach((block, i) => {
204201
const start = i * indiceSize
205202
if (start + indiceSize > decodedData.length) {
@@ -219,8 +216,8 @@ export class LtDecoder {
219216
}
220217
}
221218

222-
export function tringToUint8Array(str: string): Uint8Array {
223-
const data = new Uint8Array(str.length)
219+
export function tringToUint32Array(str: string): Uint32Array {
220+
const data = new Uint32Array(str.length)
224221
for (let i = 0; i < str.length; i++) {
225222
data[i] = str.charCodeAt(i)
226223
}

0 commit comments

Comments
 (0)