blob: 9d4c5216f0c9a171829c93176971ef57916a0f6a [file] [log] [blame]
Philipp Le41fbef42022-05-29 17:53:27 +02001# SPDX-License-Identifier: MPL-2.0
2# Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
3# This Source Code Form is subject to the terms of the Mozilla Public
4# License, v. 2.0. If a copy of the MPL was not distributed with this
5# file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
7from __future__ import annotations
8
9from dataclasses import dataclass
10from typing import List
11
12
13@dataclass
14class Symbols:
15 symbols: List[int]
16 bits_per_symbol: int
17
18 def reencode(self, new_bits_per_symbol: int) -> Symbols:
19 assert new_bits_per_symbol > 0, 'Number of bits must be at least 1'
20 mask = (1 << new_bits_per_symbol) - 1
21 tmp_word = 0
22 head = 0
23 new_symbols = []
24 for sym in self.symbols:
25 tmp_word |= (sym << head)
26 head += self.bits_per_symbol
27 while head >= new_bits_per_symbol:
28 new_symbols.append(tmp_word & mask)
29 tmp_word >>= new_bits_per_symbol
30 head -= new_bits_per_symbol
31 if head > 0:
32 new_symbols.append(tmp_word & mask)
33
34 return Symbols(
35 symbols=new_symbols,
36 bits_per_symbol=new_bits_per_symbol,
37 )
38
39 def to_bit_str(self) -> List[str]:
40 fmt = '{:0%db}' % self.bits_per_symbol
41 return [fmt.format(sym) for sym in self.symbols]
42
43 def __len__(self):
44 return len(self.symbols)
45
46
47class MessageBinarySerializer:
48 def __init__(self, message: str):
49 self.message = message
50 self.symbols = None
51
52 def to_symbols(self) -> Symbols:
53 if self.symbols is None:
54 ba = bytearray(self.message, 'utf-8')
55 self.symbols = Symbols(
56 symbols=[int(sym) for sym in ba],
57 bits_per_symbol=8,
58 )
59 return self.symbols