Coverage for /var/devmt/py/utils4_1.8.0/utils4/convert.py: 100%
69 statements
« prev ^ index » next coverage.py v7.6.9, created at 2025-08-26 21:39 +0100
« prev ^ index » next coverage.py v7.6.9, created at 2025-08-26 21:39 +0100
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3"""
4:Purpose: This module contains various low-level conversion functions.
6:Developer: J Berendt
7:Email: development@s3dev.uk
9:Comments: Often, these types of conversions are called from a high-iteration
10 loop. Therefore, the implementation of these functions has been
11 written as close to core Python as possible, or in a C style, for
12 efficiency purposes.
14"""
16# TODO: Move repeated messages into a central messaging class.
18def ascii2bin(asciistring: str) -> str:
19 """Convert an ASCII string into a binary string representation.
21 Args:
22 asciistring (str): ASCII string to be converted.
24 Returns:
25 str: A binary string representation for the passed ASCII text, where
26 each ASCII character is represented by an 8-bit binary string.
28 """
29 return ''.join(map(int2bin, ascii2int(asciistring)))
31def ascii2hex(asciistring: str) -> str:
32 """Convert an ASCII string into a hexidecimal string.
34 Args:
35 asciistring (str): ASCII string to be converted.
37 Returns:
38 str: A hexidecimal string representation of the passed ASCII
39 text.
41 """
42 return ''.join(map(int2hex, ascii2int(asciistring)))
44def ascii2int(asciistring: str) -> list:
45 """Convert an ASCII string to a list of integers.
47 Args:
48 asciistring (str): ASCII string to be converted.
50 Returns:
51 list: A list of integers, as converted from he ASCII string.
53 """
54 return [ord(i) for i in asciistring]
56def bin2ascii(binstring: str, bits: int=8) -> str:
57 """Convert a binary string representation into ASCII text.
59 Args:
60 binstring (str): Binary string to be converted.
61 bits (int, optional): Bit chunks into which the binary string is
62 broken for conversion. Defaults to 8.
64 Returns:
65 str: An ASCII string representation of the passed binary string.
67 """
68 if len(binstring) % bits:
69 raise ValueError('The string length cannot be broken into '
70 f'{bits}-bit chunks.')
71 ints = []
72 for chunk in range(0, len(binstring), bits):
73 byte_ = binstring[chunk:chunk+bits]
74 ints.append(bin2int(byte_, bits=bits)[0])
75 text = ''.join(map(int2ascii, ints))
76 return text
78def bin2int(binstring: str, bits: int=8) -> int:
79 """Convert a binary string representation into an integer.
81 Args:
82 binstring (str): Binary string to be converted.
83 bits (int, optional): Bit chunks into which the binary string is
84 broken for conversion. Defaults to 8.
86 Returns:
87 int: Integer value from the binary string.
89 """
90 if len(binstring) % bits:
91 raise ValueError('The string length cannot be broken into '
92 f'{bits}-bit chunks.')
93 ints = []
94 for chunk in range(0, len(binstring), bits):
95 int_ = 0
96 s = 0
97 byte = binstring[chunk:chunk+bits]
98 for b in range(len(byte)-1, -1, -1):
99 int_ += int(byte[b]) << s
100 s += 1
101 ints.append(int_)
102 return ints
104def bin2hex(binstring: str, bits: int=8) -> str:
105 """Convert a binary string representation into a hex string.
107 Args:
108 binstring (str): Binary string to be converted.
109 bits (int, optional): Bit chunks into which the binary string is
110 broken for conversion. Defaults to 8.
112 Returns:
113 A hexidecimal string representation of the passed binary string.
115 """
116 if len(binstring) % bits:
117 raise ValueError('The string length cannot be broken into '
118 f'{bits}-bit chunks.')
119 return ''.join(int2hex(i) for i in bin2int(binstring, bits=bits))
121def hex2ascii(hexstring: str) -> str:
122 """Convert a hexidecimal string to ASCII text.
124 Args:
125 hexstring (str): Hex string to be converted.
127 Returns:
128 str: An ASCII string representation for the passed hex string.
130 """
131 return ''.join(map(int2ascii, hex2int(hexstring)))
133def hex2bin(hexstring: str) -> str:
134 """Convert a hexidecimal string into a binary string representation.
136 Args:
137 hexstring (str): Hex string to be converted.
139 Returns:
140 str: A binary string representation of the passed hex string.
142 """
143 return ''.join(map(int2bin, hex2int(hexstring)))
145def hex2int(hexstring: str, nbytes: int=1) -> int:
146 """Convert a hexidecimal string to an integer.
148 Args:
149 hexstring (str): Hex string to be converted.
150 nbytes (int, optional): Number of bytes to consider for each
151 decimal value. Defaults to 1.
153 :Examples:
154 Example usage::
156 hex2int(hexstring='c0ffee', nbytes=1)
157 >>> [192, 255, 238]
159 hex2int(hexstring='c0ffee', nbytes=2)
160 >>> [49407, 238]
162 hex2int(hexstring='c0ffee', nbytes=3)
163 >>> [12648430]
165 Returns:
166 list: A list of decimal values, as converted from the hex string.
168 """
169 # pylint: disable=multiple-statements
170 nbytes *= 2
171 out = []
172 # Split hex string into (n)-byte size chunks.
173 for chunk in range(0, len(hexstring), nbytes):
174 i = 0
175 nib = 0
176 for char in hexstring[chunk:nbytes+chunk]:
177 if (char >= '0') & (char <= '9'): nib = ord(char)
178 if (char >= 'a') & (char <= 'f'): nib = ord(char) + 9
179 if (char >= 'A') & (char <= 'F'): nib = ord(char) + 9
180 i = (i << 4) | (nib & 0xf)
181 out.append(i)
182 return out
184def int2ascii(i: int) -> str:
185 """Convert an integer to an ASCII character.
187 Args:
188 i (int): Integer value to be converted to ASCII text.
190 Note:
191 The passed integer value must be <= 127.
193 Raises:
194 ValueError: If the passed integer is > 127.
196 Returns:
197 str: The ASCII character associated to the passed integer.
199 """
200 if i > 127:
201 raise ValueError('The passed integer value must be <= 127.')
202 return chr(i)
204def int2bin(i: int) -> str:
205 """Convert an 8-bit integer to a binary string.
207 Args:
208 i (int): Integer value to be converted.
210 Note:
211 The passed integer value must be <= 255.
213 Raises:
214 ValueError: If the passed integer is > 255.
216 Returns:
217 str: A binary string representation of the passed integer.
219 """
220 if i > 255: # Limited to 1 byte.
221 raise ValueError(f'Passed value exceeds 1 byte: i={i}')
222 return ''.join(str((i >> shift) & 1) for shift in range(7, -1, -1))
224def int2hex(i: int) -> str:
225 """Convert an integer into a hexidecimal string.
227 Args:
228 i (int): Integer value to be converted.
230 Returns:
231 str: A two character hexidecimal string for the passed integer
232 value.
234 """
235 chars = '0123456789abcdef'
236 out = ''
237 out_ = ''
238 while i > 0:
239 out_ += chars[i % 16]
240 i //= 16
241 # Output string must be reversed.
242 for x in range(len(out_)-1, -1, -1):
243 out += out_[x]
244 # Pad so all hex values are two characters.
245 if len(out) < 2:
246 out = '0' + out
247 return out