1
2 """smartcard.util package
3
4 __author__ = "http://www.gemalto.com"
5
6 Copyright 2001-2012 gemalto
7 Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
8
9 This file is part of pyscard.
10
11 pyscard is free software; you can redistribute it and/or modify
12 it under the terms of the GNU Lesser General Public License as published by
13 the Free Software Foundation; either version 2.1 of the License, or
14 (at your option) any later version.
15
16 pyscard is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU Lesser General Public License for more details.
20
21 You should have received a copy of the GNU Lesser General Public License
22 along with pyscard; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 """
25
26 PACK = 1
27 HEX = 2
28 UPPERCASE = 4
29 COMMA = 8
30
31
32 -def padd(bytelist, length, padding='FF'):
33 """ Padds a byte list with a constant byte value (default is x0FF)
34 @param bytelist: the byte list to padd
35 @param length: the total length of the resulting byte list;
36 no padding if length is smaller than the byte list length
37 @param padding: padding value (default is 0xff)
38
39 @return: the padded bytelist
40
41 >>> padd([59, 101, 0, 0, 156, 17, 1, 1, 3], 16)
42 [59, 101, 0, 0, 156, 17, 1, 1, 3, 255, 255, 255, 255, 255, 255, 255]
43 >>> padd([59, 101, 0, 0, 156, 17, 1, 1, 3], 12, '80')
44 [59, 101, 0, 0, 156, 17, 1, 1, 3, 128, 128, 128]
45 >>> padd([59, 101, 0, 0, 156, 17, 1, 1, 3], 8)
46 [59, 101, 0, 0, 156, 17, 1, 1, 3]
47 """
48
49 if len(bytelist) < length:
50 for index in range(length - len(bytelist)):
51 bytelist.append(eval('0x' + padding))
52
53 return bytelist
54
55
57 """Returns a list of ASCII bytes from a string.
58
59 @param stringtoconvert: the string to convert into a byte list
60
61 @return: a byte list of the ASCII codes of the string characters
62
63 L{toASCIIBytes()} is the reverse of L{toASCIIString()}
64
65 >>> toASCIIBytes("Number 101")
66 [78, 117, 109, 98, 101, 114, 32, 49, 48, 49]
67 """
68
69 return list(map(ord, list(stringtoconvert)))
70
71
73 """Returns a string representing a list of ASCII bytes.
74
75 @param bytelist: list of ASCII bytes to convert into a string
76
77 @return: a string from the ASCII code list
78
79 L{toASCIIString()} is the reverse of L{toASCIIBytes()}
80
81 >>> toASCIIString([0x4E,0x75,0x6D,0x62,0x65,0x72,0x20,0x31,0x30,0x31])
82 'Number 101'
83 """
84
85 return ''.join(map(chr, bytelist))
86
87
89 """Returns a list of bytes from a byte string
90
91 bytestring: a byte string
92
93 >>> toBytes("3B 65 00 00 9C 11 01 01 03")
94 [59, 101, 0, 0, 156, 17, 1, 1, 3]
95 >>> toBytes("3B6500009C11010103")
96 [59, 101, 0, 0, 156, 17, 1, 1, 3]
97 >>> toBytes("3B6500 009C1101 0103")
98 [59, 101, 0, 0, 156, 17, 1, 1, 3]
99 """
100 packedstring = bytestring.replace(' ', '').replace(' ','').replace('\n', '')
101 try:
102 return list(map(lambda x: int(''.join(x), 16), zip(*[iter(packedstring)] * 2)))
103 except (KeyError, ValueError):
104 raise TypeError('not a string representing a list of bytes')
105
106
107 """GSM3.38 character conversion table."""
108 __dic_GSM_3_38__ = {
109 u'@': 0x00,
110 u'£': 0x01,
111 u'$': 0x02,
112 u'¥': 0x03,
113 u'è': 0x04,
114 u'é': 0x05,
115 u'ù': 0x06,
116 u'ì': 0x07,
117 u'ò': 0x08,
118 u'Ç': 0x09,
119 u'\n': 0x0A,
120 u'Ø': 0x0B,
121 u'ø': 0x0C,
122 u'\r': 0x0D,
123 u'Å': 0x0E,
124 u'å': 0x0F,
125 u'_': 0x11,
126 u'Æ': 0x1C,
127 u'æ': 0x1D,
128 u'ß': 0x1E,
129 u'É': 0x1F,
130 u' ': 0x20,
131 u'!': 0x21,
132 u'"': 0x22,
133 u'#': 0x23,
134 u'¤': 0x24,
135 u'¡': 0x40,
136 u'Ä': 0x5B,
137 u'ä': 0x7B,
138 u'Ö': 0x5C,
139 u'ö': 0x7C,
140 u'Ñ': 0x5D,
141 u'ñ': 0x7D,
142 u'Ü': 0x5E,
143 u'ü': 0x7E,
144 u'§': 0x5F,
145 u'¿': 0x60,
146 u'à': 0x7F,
147 }
148
149
151 """Returns a list of bytes from a string using GSM 3.38 conversion table.
152
153 @param stringtoconvert: string to convert
154
155 @return: a list of bytes
156
157 >>> toGSM3_38Bytes("@ùPascal")
158 [0, 6, 80, 97, 115, 99, 97, 108]
159 """
160 if isinstance(stringtoconvert, bytes):
161 stringtoconvert = stringtoconvert.decode('iso8859-1')
162
163 result = []
164 for char in stringtoconvert:
165 if ((char >= "%") and (char <= "?")):
166 result.append(ord(char))
167 elif ((char >= "A") and (char <= "Z")):
168 result.append(ord(char))
169 elif ((char >= "a") and (char <= "z")):
170 result.append(ord(char))
171 else:
172 result.append(__dic_GSM_3_38__[char])
173 return result
174
175
177 """Returns an hex string representing bytes
178
179 @param bytes: a list of bytes to stringify,
180 e.g. [59, 22, 148, 32, 2, 1, 0, 0, 13]
181 @param format: a logical OR of
182 - COMMA: add a comma between bytes
183 - HEX: add the 0x chars before bytes
184 - UPPERCASE: use 0X before bytes (need HEX)
185 - PACK: remove blanks
186
187 >>> vals = [0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03]
188 >>> toHexString(vals)
189 '3B 65 00 00 9C 11 01 01 03'
190 >>> toHexString(vals, COMMA)
191 '3B, 65, 00, 00, 9C, 11, 01, 01, 03'
192 >>> toHexString(vals, HEX)
193 '0x3B 0x65 0x00 0x00 0x9C 0x11 0x01 0x01 0x03'
194 >>> toHexString(vals, HEX | COMMA)
195 '0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03'
196 >>> toHexString(vals, PACK)
197 >>> toHexString(vals, HEX | UPPERCASE)
198 '0X3B 0X65 0X00 0X00 0X9C 0X11 0X01 0X01 0X03'
199 >>> toHexString(vals, HEX | UPPERCASE | COMMA)
200 '0X3B, 0X65, 0X00, 0X00, 0X9C, 0X11, 0X01, 0X01, 0X03'
201 """
202
203 for byte in tuple(bytes):
204 pass
205
206 if type(bytes) is not list:
207 raise TypeError('not a list of bytes')
208
209 if bytes == None or bytes == []:
210 return ""
211 else:
212 pformat = "%-0.2X"
213 if COMMA & format:
214 separator = ","
215 else:
216 separator = ""
217 if not PACK & format:
218 separator = separator + " "
219 if HEX & format:
220 if UPPERCASE & format:
221 pformat = "0X" + pformat
222 else:
223 pformat = "0x" + pformat
224 return (separator.join(map(lambda a: pformat % ((a + 256) % 256), bytes))).rstrip()
225
226
227
229 """
230 >>> HexListToBinString([78, 117, 109, 98, 101, 114, 32, 49, 48, 49])
231 'Number 101'
232 """
233 return ''.join(map(chr, hexlist))
234
235
236
238 """
239 >>> BinStringToHexList("Number 101")
240 [78, 117, 109, 98, 101, 114, 32, 49, 48, 49]
241 """
242 return list(map(ord, binstring))
243
244
246 """An alias for HexListToBinString
247
248 >>> hl2bs([78, 117, 109, 98, 101, 114, 32, 49, 48, 49])
249 'Number 101'
250 """
251 return HexListToBinString(hexlist)
252
253
255 """An alias for BinStringToHexList
256
257 >>> bs2hl("Number 101")
258 [78, 117, 109, 98, 101, 114, 32, 49, 48, 49]
259 """
260 return BinStringToHexList(binstring)
261