In this example shows how to use the API of pyerasure
to encode and decode with
using the Reed Solomon Cauchy coefficient generator.
1#!/usr/bin/env python
2# encoding: utf-8
3
4# License for Commercial Usage
5# Distributed under the "PYERASURE EVALUATION LICENSE 1.3"
6# Licensees holding a valid commercial license may use this project in
7# accordance with the standard license agreement terms provided with the
8# Software (see accompanying file LICENSE.rst or
9# https://www.steinwurf.com/license), unless otherwise different terms and
10# conditions are agreed in writing between Licensee and Steinwurf ApS in which
11# case the license will be regulated by that separate written agreement.
12# License for Non-Commercial Usage
13# Distributed under the "PYERASURE RESEARCH LICENSE 1.2"
14# Licensees holding a valid research license may use this project in accordance
15# with the license agreement terms provided with the Software
16# See accompanying file LICENSE.rst or https://www.steinwurf.com/license
17
18import os
19import random
20
21import pyerasure
22import pyerasure.finite_field
23import pyerasure.generator
24
25
26def main():
27 """
28 Simple example showing how to encode and decode a block
29 of memory using a Cauchy Reed Solomon code.
30 """
31
32 # Pick the finite field to use for the encoding and decoding.
33 field = pyerasure.finite_field.Binary8()
34
35 # Pick the number of symbols to encode/decode.
36 symbols = 40
37
38 # Pick the size of each symbol in bytes
39 symbol_bytes = 1400
40
41 # Create an encoder and decoder. The encoder and decoder must be created
42 # identically to be compatible.
43 encoder = pyerasure.Encoder(field, symbols, symbol_bytes)
44 decoder = pyerasure.Decoder(field, symbols, symbol_bytes)
45
46 # The generator must similarly be created based on the encoder/decoder.
47 generator = pyerasure.generator.RSCauchy(field, symbols)
48
49 # Allocate some data to encode. In this case we make a buffer
50 # with the same size as the encoder's block size (the max.
51 # amount a single encoder can encode)
52 # Just for fun - fill data_in with random data
53 data_in = bytearray(os.urandom(encoder.block_bytes))
54
55 # Assign the data buffer to the encoder so that we may start
56 # to produce encoded symbols from it
57 encoder.set_symbols(data_in)
58
59 # Keep track of the number of systematic symbols
60 systematic_index = 0
61
62 # Lose packets with 10% probability
63 loss_probability = 10
64
65 while not decoder.is_complete():
66
67 if encoder.rank > systematic_index:
68
69 index = systematic_index
70 systematic_index += 1
71 symbol = encoder.symbol_data(index)
72
73 # Drop packet based on loss probability
74 if random.randint(0, 100) < loss_probability:
75 print(" - lost")
76 else:
77 decoder.decode_systematic_symbol(symbol, index)
78 print(f" - decoded, rank now {decoder.rank}")
79
80 elif generator.remaining_repair_symbols != 0:
81
82 coefficients, index = generator.generate()
83 symbol = encoder.encode_symbol(coefficients)
84
85 # Drop packet based on loss probability
86 if random.randint(0, 100) < loss_probability:
87 print(" - lost")
88 else:
89 coefficients = generator.generate_specific(index)
90 decoder.decode_symbol(symbol, bytearray(coefficients))
91 print(f" - decoded, rank now {decoder.rank}")
92 else:
93 print("Data was not decoded. No more repair available.")
94 return
95
96 if data_in != decoder.block_data():
97 print("Data was not decoded correctly. Something went wrong")
98 else:
99 print("Decoding was successful. Yay!")
100
101
102if __name__ == "__main__":
103 main()