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

68 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-12 15:38 +0100

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.6+ 

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 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 for char in hexstring[chunk:nbytes+chunk]: 

176 if (char >= '0') & (char <= '9'): nib = ord(char) 

177 if (char >= 'a') & (char <= 'f'): nib = ord(char) + 9 

178 if (char >= 'A') & (char <= 'F'): nib = ord(char) + 9 

179 i = (i << 4) | (nib & 0xf) 

180 out.append(i) 

181 return out 

182 

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

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

185 

186 Args: 

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

188 

189 Note: 

190 The passed integer value must be <= 127. 

191 

192 Raises: 

193 ValueError: If the passed integer is > 127. 

194 

195 Returns: 

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

197 

198 """ 

199 if i > 127: 

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

201 return chr(i) 

202 

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

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

205 

206 Args: 

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

208 

209 Note: 

210 The passed integer value must be <= 255. 

211 

212 Raises: 

213 ValueError: If the passed integer is > 255. 

214 

215 Returns: 

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

217 

218 """ 

219 if i > 255: # Limited to 1 byte. 

220 raise ValueError(f'Passed value exceeds 1 byte: i={i}') 

221 return ''.join(str((i >> shift) & 1) for shift in range(7, -1, -1)) 

222 

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

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

225 

226 Args: 

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

228 

229 Returns: 

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

231 value. 

232 

233 """ 

234 chars = '0123456789abcdef' 

235 out = '' 

236 out_ = '' 

237 while i > 0: 

238 out_ += chars[i % 16] 

239 i //= 16 

240 # Output string must be reversed. 

241 for x in range(len(out_)-1, -1, -1): 

242 out += out_[x] 

243 # Pad so all hex values are two characters. 

244 if len(out) < 2: 

245 out = '0' + out 

246 return out