-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbase32.ads
210 lines (182 loc) · 6.4 KB
/
base32.ads
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
with Interfaces;
with LSC.Types;
with LSC.Byte_Arrays;
-- @summary
-- Base32 encoder and decoder
package Base32
with SPARK_Mode
is
-- Check if a character is in the Base32 alphabet
-- @param C Character to Check
-- @return True if C is in [a-zA-Z2-7]
function Valid_Base32_Character
(C : Character) return Boolean
is
(C in 'a' .. 'z' | 'A' .. 'Z' | '2' .. '7')
with
Depends => (Valid_Base32_Character'Result => C);
-- 8bit unsigned byte
subtype Byte is LSC.Types.Byte;
-- Array of bytes
subtype Buffer is LSC.Byte_Arrays.Byte_Array_Type
with
Dynamic_Predicate => Buffer'Length mod 5 = 0;
-- Base32 string that can only contain [a-zA-Z2-7]
subtype Base32_String is String
with
Dynamic_Predicate =>
Base32_String'Length mod 8 = 0 and
(for all C of Base32_String =>
Valid_Base32_Character (C));
-- Decode Base32 string into a byte array
-- @param S Valid Base32 string
-- @return Decoded byte array
function Decode (S : Base32_String) return Buffer
with
Depends => (Decode'Result => S),
Pre =>
S'Length < Integer (Natural'Last / 5) and
S'Length >= 8,
Post =>
Decode'Result'Length = S'Length * 5 / 8;
-- Encodes a byte array into a Base32 string
-- @param B byte array
-- @return Base32 string
function Encode (B : Buffer) return Base32_String
with
Depends => (Encode'Result => B),
Pre => B'Length < Natural'Last / 8;
-- Decodes Base32 into ASCII
-- @param S Base32 string
-- @return String
function Decode_String (S : Base32_String) return String
with
Depends => (Decode_String'Result => S),
Pre =>
S'Length < Natural'Last / 5 and S'Length >= 8;
-- Encodes an ASCII string into Base32
-- @param ASCII String
-- @return Base32 string
function Encode_String (S : String) return Base32_String
with
Depends => (Encode_String'Result => S),
Pre => S'Length mod 5 = 0 and S'Length < Natural'Last / 8;
private
use Interfaces;
function Decode_Map (C : Character) return Byte
with
Depends => (Decode_Map'Result => C),
Pre => Valid_Base32_Character (C),
Post => Decode_Map'Result < 32;
function Encode_Map (N : Byte) return Character
with
Depends => (Encode_Map'Result => N),
Pre => N < 32,
Post => Valid_Base32_Character (Encode_Map'Result);
subtype String_Chunk is Base32_String (1 .. 8);
subtype Buffer_Chunk is Buffer (1 .. 5);
function Decode_1 (C1 : Character;
C2 : Character) return Byte is
(Shift_Left (Decode_Map (C1), 3) or
Shift_Right (Decode_Map (C2), 2))
with
Depends => (Decode_1'Result => (C1, C2)),
Pre =>
Valid_Base32_Character (C1) and Valid_Base32_Character (C2);
function Decode_2 (C2 : Character;
C3 : Character;
C4 : Character) return Byte is
(Shift_Left (Decode_Map (C2), 6) or
Shift_Left (Decode_Map (C3), 1) or
Shift_Right (Decode_Map (C4), 4))
with
Depends => (Decode_2'Result => (C2, C3, C4)),
Pre =>
Valid_Base32_Character (C2) and
Valid_Base32_Character (C3) and
Valid_Base32_Character (C4);
function Decode_3 (C4 : Character;
C5 : Character) return Byte is
(Shift_Left (Decode_Map (C4), 4) or
Shift_Right (Decode_Map (C5), 1))
with
Depends => (Decode_3'Result => (C4, C5)),
Pre =>
Valid_Base32_Character (C4) and Valid_Base32_Character (C5);
function Decode_4 (C5 : Character;
C6 : Character;
C7 : Character) return Byte is
(Shift_Left (Decode_Map (C5), 7) or
Shift_Left (Decode_Map (C6), 2) or
Shift_Right (Decode_Map (C7), 3))
with
Depends => (Decode_4'Result => (C5, C6, C7)),
Pre =>
Valid_Base32_Character (C5) and
Valid_Base32_Character (C6) and
Valid_Base32_Character (C7);
function Decode_5 (C7 : Character;
C8 : Character) return Byte is
(Shift_Left (Decode_Map (C7), 5) or
Decode_Map (C8))
with
Depends => (Decode_5'Result => (C7, C8)),
Pre =>
Valid_Base32_Character (C7) and Valid_Base32_Character (C8);
function Encode_1 (B1 : Byte) return Character is
(Encode_Map (Shift_Right (B1, 3)))
with
Depends => (Encode_1'Result => B1),
Post =>
Valid_Base32_Character (Encode_1'Result);
function Encode_2 (B1 : Byte;
B2 : Byte) return Character is
(Encode_Map (Shift_Left (B1 and 7, 2) or
Shift_Right (B2, 6)))
with
Depends => (Encode_2'Result => (B1, B2)),
Post =>
Valid_Base32_Character (Encode_2'Result);
function Encode_3 (B2 : Byte) return Character is
(Encode_Map (Shift_Right (B2 and 63, 1)))
with
Depends => (Encode_3'Result => B2),
Post =>
Valid_Base32_Character (Encode_3'Result);
function Encode_4 (B2 : Byte;
B3 : Byte) return Character is
(Encode_Map (Shift_Left (B2 and 1, 4) or
Shift_Right (B3, 4)))
with
Depends => (Encode_4'Result => (B2, B3)),
Post =>
Valid_Base32_Character (Encode_4'Result);
function Encode_5 (B3 : Byte;
B4 : Byte) return Character is
(Encode_Map (Shift_Left (B3 and 15, 1) or
Shift_Right (B4, 7)))
with
Depends => (Encode_5'Result => (B3, B4)),
Post =>
Valid_Base32_Character (Encode_5'Result);
function Encode_6 (B4 : Byte) return Character is
(Encode_Map (Shift_Right (B4 and 127, 2)))
with
Depends => (Encode_6'Result => B4),
Post =>
Valid_Base32_Character (Encode_6'Result);
function Encode_7 (B4 : Byte;
B5 : Byte) return Character is
(Encode_Map (Shift_Left (B4 and 3, 3) or
Shift_Right (B5, 5)))
with
Depends => (Encode_7'Result => (B4, B5)),
Post =>
Valid_Base32_Character (Encode_7'Result);
function Encode_8 (B5 : Byte) return Character is
(Encode_Map (B5 and 31))
with
Depends => (Encode_8'Result => B5),
Post =>
Valid_Base32_Character (Encode_8'Result);
end Base32;