Coverage for /var/devmt/py/utils4_1.7.0/utils4/convert.py: 100%
69 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-21 20:06 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-21 20:06 +0000
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3"""
4:Purpose: This module contains various low-level conversion functions.
6:Platform: Linux/Windows | Python 3.7+
7:Developer: J Berendt
8:Email: development@s3dev.uk
10:Comments: Often, these types of conversions are called from a high-iteration
11 loop. Therefore, the implementation of these functions has been
12 written as close to core Python as possible, or in a C style, for
13 efficiency purposes.
15"""
17# TODO: Move repeated messages into a central messaging class.
19def ascii2bin(asciistring: str) -> str:
20 """Convert an ASCII string into a binary string representation.
22 Args:
23 asciistring (str): ASCII string to be converted.
25 Returns:
26 str: A binary string representation for the passed ASCII text, where
27 each ASCII character is represented by an 8-bit binary string.
29 """
30 return ''.join(map(int2bin, ascii2int(asciistring)))
32def ascii2hex(asciistring: str) -> str:
33 """Convert an ASCII string into a hexidecimal string.
35 Args:
36 asciistring (str): ASCII string to be converted.
38 Returns:
39 str: A hexidecimal string representation of the passed ASCII
40 text.
42 """
43 return ''.join(map(int2hex, ascii2int(asciistring)))
45def ascii2int(asciistring: str) -> list:
46 """Convert an ASCII string to a list of integers.
48 Args:
49 asciistring (str): ASCII string to be converted.
51 Returns:
52 list: A list of integers, as converted from he ASCII string.
54 """
55 return [ord(i) for i in asciistring]
57def bin2ascii(binstring: str, bits: int=8) -> str:
58 """Convert a binary string representation into ASCII text.
60 Args:
61 binstring (str): Binary string to be converted.
62 bits (int, optional): Bit chunks into which the binary string is
63 broken for conversion. Defaults to 8.
65 Returns:
66 str: An ASCII string representation of the passed binary string.
68 """
69 if len(binstring) % bits:
70 raise ValueError('The string length cannot be broken into '
71 f'{bits}-bit chunks.')
72 ints = []
73 for chunk in range(0, len(binstring), bits):
74 byte_ = binstring[chunk:chunk+bits]
75 ints.append(bin2int(byte_, bits=bits)[0])
76 text = ''.join(map(int2ascii, ints))
77 return text
79def bin2int(binstring: str, bits: int=8) -> int:
80 """Convert a binary string representation into an integer.
82 Args:
83 binstring (str): Binary string to be converted.
84 bits (int, optional): Bit chunks into which the binary string is
85 broken for conversion. Defaults to 8.
87 Returns:
88 int: Integer value from the binary string.
90 """
91 if len(binstring) % bits:
92 raise ValueError('The string length cannot be broken into '
93 f'{bits}-bit chunks.')
94 ints = []
95 for chunk in range(0, len(binstring), bits):
96 int_ = 0
97 s = 0
98 byte = binstring[chunk:chunk+bits]
99 for b in range(len(byte)-1, -1, -1):
100 int_ += int(byte[b]) << s
101 s += 1
102 ints.append(int_)
103 return ints
105def bin2hex(binstring: str, bits: int=8) -> str:
106 """Convert a binary string representation into a hex string.
108 Args:
109 binstring (str): Binary string to be converted.
110 bits (int, optional): Bit chunks into which the binary string is
111 broken for conversion. Defaults to 8.
113 Returns:
114 A hexidecimal string representation of the passed binary string.
116 """
117 if len(binstring) % bits:
118 raise ValueError('The string length cannot be broken into '
119 f'{bits}-bit chunks.')
120 return ''.join(int2hex(i) for i in bin2int(binstring, bits=bits))
122def hex2ascii(hexstring: str) -> str:
123 """Convert a hexidecimal string to ASCII text.
125 Args:
126 hexstring (str): Hex string to be converted.
128 Returns:
129 str: An ASCII string representation for the passed hex string.
131 """
132 return ''.join(map(int2ascii, hex2int(hexstring)))
134def hex2bin(hexstring: str) -> str:
135 """Convert a hexidecimal string into a binary string representation.
137 Args:
138 hexstring (str): Hex string to be converted.
140 Returns:
141 str: A binary string representation of the passed hex string.
143 """
144 return ''.join(map(int2bin, hex2int(hexstring)))
146def hex2int(hexstring: str, nbytes: int=1) -> int:
147 """Convert a hexidecimal string to an integer.
149 Args:
150 hexstring (str): Hex string to be converted.
151 nbytes (int, optional): Number of bytes to consider for each
152 decimal value. Defaults to 1.
154 :Examples:
155 Example usage::
157 hex2int(hexstring='c0ffee', nbytes=1)
158 >>> [192, 255, 238]
160 hex2int(hexstring='c0ffee', nbytes=2)
161 >>> [49407, 238]
163 hex2int(hexstring='c0ffee', nbytes=3)
164 >>> [12648430]
166 Returns:
167 list: A list of decimal values, as converted from the hex string.
169 """
170 # pylint: disable=multiple-statements
171 nbytes *= 2
172 out = []
173 # Split hex string into (n)-byte size chunks.
174 for chunk in range(0, len(hexstring), nbytes):
175 i = 0
176 nib = 0
177 for char in hexstring[chunk:nbytes+chunk]:
178 if (char >= '0') & (char <= '9'): nib = ord(char)
179 if (char >= 'a') & (char <= 'f'): nib = ord(char) + 9
180 if (char >= 'A') & (char <= 'F'): nib = ord(char) + 9
181 i = (i << 4) | (nib & 0xf)
182 out.append(i)
183 return out
185def int2ascii(i: int) -> str:
186 """Convert an integer to an ASCII character.
188 Args:
189 i (int): Integer value to be converted to ASCII text.
191 Note:
192 The passed integer value must be <= 127.
194 Raises:
195 ValueError: If the passed integer is > 127.
197 Returns:
198 str: The ASCII character associated to the passed integer.
200 """
201 if i > 127:
202 raise ValueError('The passed integer value must be <= 127.')
203 return chr(i)
205def int2bin(i: int) -> str:
206 """Convert an 8-bit integer to a binary string.
208 Args:
209 i (int): Integer value to be converted.
211 Note:
212 The passed integer value must be <= 255.
214 Raises:
215 ValueError: If the passed integer is > 255.
217 Returns:
218 str: A binary string representation of the passed integer.
220 """
221 if i > 255: # Limited to 1 byte.
222 raise ValueError(f'Passed value exceeds 1 byte: i={i}')
223 return ''.join(str((i >> shift) & 1) for shift in range(7, -1, -1))
225def int2hex(i: int) -> str:
226 """Convert an integer into a hexidecimal string.
228 Args:
229 i (int): Integer value to be converted.
231 Returns:
232 str: A two character hexidecimal string for the passed integer
233 value.
235 """
236 chars = '0123456789abcdef'
237 out = ''
238 out_ = ''
239 while i > 0:
240 out_ += chars[i % 16]
241 i //= 16
242 # Output string must be reversed.
243 for x in range(len(out_)-1, -1, -1):
244 out += out_[x]
245 # Pad so all hex values are two characters.
246 if len(out) < 2:
247 out = '0' + out
248 return out