v / vlib / crypto / bcrypt / base64.v
97 lines · 78 sloc · 1.62 KB · 008aaad99981918c51194d7aaaaaccb4c258f244
Raw
1module bcrypt
2
3const alphabet = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
4
5fn char64(c u8) u8 {
6 for i, ch in alphabet {
7 if ch == c {
8 return u8(i)
9 }
10 }
11 return 255
12}
13
14fn base64_decode(data string) []u8 {
15 mut dest_index := 0
16 mut result := []u8{}
17 for src_index := 0; src_index < data.len - 1; src_index += 4 {
18 c1 := char64(data[src_index])
19
20 if src_index + 1 >= data.len {
21 break
22 }
23
24 c2 := char64(data[src_index + 1])
25
26 // Invalid data */
27 if c1 == 255 || c2 == 255 {
28 break
29 }
30
31 result << ((c1 << 2) | ((c2 & 0x30) >> 4))
32 dest_index += 1
33
34 if src_index + 2 >= data.len || dest_index == 16 {
35 break
36 }
37
38 c3 := char64(data[src_index + 2])
39 if c3 == 255 {
40 break
41 }
42
43 result << (((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2))
44 dest_index += 1
45
46 if src_index + 3 >= data.len || dest_index == 16 {
47 break
48 }
49
50 c4 := char64(data[src_index + 3])
51 if c4 == 255 {
52 break
53 }
54
55 result << (((c3 & 0x03) << 6) | c4)
56 dest_index += 1
57
58 if dest_index == 16 {
59 break
60 }
61 }
62
63 return result
64}
65
66fn base64_encode(data []u8) string {
67 mut src_index := 0
68 mut result := []u8{}
69 for src_index < data.len {
70 mut c1 := data[src_index]
71 src_index += 1
72 result << alphabet[c1 >> 2]
73 c1 = (c1 & 0x03) << 4
74 if src_index >= data.len {
75 result << alphabet[c1]
76 break
77 }
78
79 mut c2 := data[src_index]
80 src_index += 1
81 c1 |= (c2 >> 4) & 0x0f
82 result << alphabet[c1]
83 c1 = (c2 & 0x0f) << 2
84 if src_index >= data.len {
85 result << alphabet[c1]
86 break
87 }
88
89 c2 = data[src_index]
90 src_index += 1
91 c1 |= (c2 >> 6) & 0x03
92 result << alphabet[c1]
93 result << alphabet[c2 & 0x3f]
94 }
95
96 return result.bytestr()
97}
98