Warning: This is a development version. The latest stable version is Version 1.3.0.
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()