Coverage for /var/devmt/py/utils4_1.6.0/utils4/convert.py: 100%

69 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-11-13 13:30 +0000

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3""" 

4:Purpose: This module contains various low-level conversion functions. 

5 

6:Platform: Linux/Windows | Python 3.7+ 

7:Developer: J Berendt 

8:Email: development@s3dev.uk 

9 

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. 

14 

15""" 

16 

17# TODO: Move repeated messages into a central messaging class. 

18 

19def ascii2bin(asciistring: str) -> str: 

20 """Convert an ASCII string into a binary string representation. 

21 

22 Args: 

23 asciistring (str): ASCII string to be converted. 

24 

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. 

28 

29 """ 

30 return ''.join(map(int2bin, ascii2int(asciistring))) 

31 

32def ascii2hex(asciistring: str) -> str: 

33 """Convert an ASCII string into a hexidecimal string. 

34 

35 Args: 

36 asciistring (str): ASCII string to be converted. 

37 

38 Returns: 

39 str: A hexidecimal string representation of the passed ASCII 

40 text. 

41 

42 """ 

43 return ''.join(map(int2hex, ascii2int(asciistring))) 

44 

45def ascii2int(asciistring: str) -> list: 

46 """Convert an ASCII string to a list of integers. 

47 

48 Args: 

49 asciistring (str): ASCII string to be converted. 

50 

51 Returns: 

52 list: A list of integers, as converted from he ASCII string. 

53 

54 """ 

55 return [ord(i) for i in asciistring] 

56 

57def bin2ascii(binstring: str, bits: int=8) -> str: 

58 """Convert a binary string representation into ASCII text. 

59 

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. 

64 

65 Returns: 

66 str: An ASCII string representation of the passed binary string. 

67 

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 

78 

79def bin2int(binstring: str, bits: int=8) -> int: 

80 """Convert a binary string representation into an integer. 

81 

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. 

86 

87 Returns: 

88 int: Integer value from the binary string. 

89 

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 

104 

105def bin2hex(binstring: str, bits: int=8) -> str: 

106 """Convert a binary string representation into a hex string. 

107 

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. 

112 

113 Returns: 

114 A hexidecimal string representation of the passed binary string. 

115 

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)) 

121 

122def hex2ascii(hexstring: str) -> str: 

123 """Convert a hexidecimal string to ASCII text. 

124 

125 Args: 

126 hexstring (str): Hex string to be converted. 

127 

128 Returns: 

129 str: An ASCII string representation for the passed hex string. 

130 

131 """ 

132 return ''.join(map(int2ascii, hex2int(hexstring))) 

133 

134def hex2bin(hexstring: str) -> str: 

135 """Convert a hexidecimal string into a binary string representation. 

136 

137 Args: 

138 hexstring (str): Hex string to be converted. 

139 

140 Returns: 

141 str: A binary string representation of the passed hex string. 

142 

143 """ 

144 return ''.join(map(int2bin, hex2int(hexstring))) 

145 

146def hex2int(hexstring: str, nbytes: int=1) -> int: 

147 """Convert a hexidecimal string to an integer. 

148 

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. 

153 

154 :Examples: 

155 Example usage:: 

156 

157 hex2int(hexstring='c0ffee', nbytes=1) 

158 >>> [192, 255, 238] 

159 

160 hex2int(hexstring='c0ffee', nbytes=2) 

161 >>> [49407, 238] 

162 

163 hex2int(hexstring='c0ffee', nbytes=3) 

164 >>> [12648430] 

165 

166 Returns: 

167 list: A list of decimal values, as converted from the hex string. 

168 

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 

184 

185def int2ascii(i: int) -> str: 

186 """Convert an integer to an ASCII character. 

187 

188 Args: 

189 i (int): Integer value to be converted to ASCII text. 

190 

191 Note: 

192 The passed integer value must be <= 127. 

193 

194 Raises: 

195 ValueError: If the passed integer is > 127. 

196 

197 Returns: 

198 str: The ASCII character associated to the passed integer. 

199 

200 """ 

201 if i > 127: 

202 raise ValueError('The passed integer value must be <= 127.') 

203 return chr(i) 

204 

205def int2bin(i: int) -> str: 

206 """Convert an 8-bit integer to a binary string. 

207 

208 Args: 

209 i (int): Integer value to be converted. 

210 

211 Note: 

212 The passed integer value must be <= 255. 

213 

214 Raises: 

215 ValueError: If the passed integer is > 255. 

216 

217 Returns: 

218 str: A binary string representation of the passed integer. 

219 

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)) 

224 

225def int2hex(i: int) -> str: 

226 """Convert an integer into a hexidecimal string. 

227 

228 Args: 

229 i (int): Integer value to be converted. 

230 

231 Returns: 

232 str: A two character hexidecimal string for the passed integer 

233 value. 

234 

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