46
46
# # let decoded = decode("SGVsbG8gV29ybGQ=")
47
47
# # assert decoded == "Hello World"
48
48
# #
49
+ # # URL Safe Base64
50
+ # # ---------------
51
+ # #
52
+ # # .. code-block::nim
53
+ # # import base64
54
+ # # doAssert encode("c\xf7>", safe = true) == "Y_c-"
55
+ # # doAssert encode("c\xf7>", safe = false) == "Y/c+"
49
56
# #
50
57
# # See also
51
58
# # ========
56
63
57
64
const
58
65
cb64 = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
66
+ cb64safe = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
59
67
invalidChar = 255
60
68
61
- template encodeInternal(s: typed ): untyped =
69
+ template encodeInternal(s: typed , alphabet: string ): untyped =
62
70
# # encodes `s` into base64 representation.
63
71
proc encodeSize(size: int ): int =
64
72
return (size * 4 div 3 ) + 6
@@ -78,7 +86,7 @@ template encodeInternal(s: typed): untyped =
78
86
inc inputIndex
79
87
80
88
template outputChar(x: untyped ) =
81
- result [outputIndex] = cb64 [x and 63 ]
89
+ result [outputIndex] = alphabet [x and 63 ]
82
90
inc outputIndex
83
91
84
92
template outputChar(c: char ) =
@@ -112,32 +120,46 @@ template encodeInternal(s: typed): untyped =
112
120
113
121
result .setLen(outputIndex)
114
122
115
- proc encode* [T: SomeInteger| char ](s: openArray [T]) : string =
123
+ proc encode* [T: SomeInteger| char ](s: openArray [T], safe = false ) : string =
116
124
# # Encodes `s` into base64 representation.
117
125
# #
118
126
# # This procedure encodes an openarray (array or sequence) of either integers
119
127
# # or characters.
120
128
# #
129
+ # # If ``safe`` is ``true`` then it will encode using the
130
+ # # URL-Safe and Filesystem-safe standard alphabet characters,
131
+ # # which substitutes ``-`` instead of ``+`` and ``_`` instead of ``/``.
132
+ # # * https://en.wikipedia.org/wiki/Base64#URL_applications
133
+ # # * https://tools.ietf.org/html/rfc4648#page-7
134
+ # #
121
135
# # **See also:**
122
136
# # * `encode proc<#encode,string>`_ for encoding a string
123
137
# # * `decode proc<#decode,string>`_ for decoding a string
124
138
runnableExamples:
125
139
assert encode(['n' , 'i' , 'm' ]) == " bmlt"
126
140
assert encode(@ ['n' , 'i' , 'm' ]) == " bmlt"
127
141
assert encode([1 , 2 , 3 , 4 , 5 ]) == " AQIDBAU="
128
- encodeInternal(s)
142
+ if safe: encodeInternal(s, cb64safe)
143
+ else : encodeInternal(s, cb64)
129
144
130
- proc encode* (s: string ): string =
145
+ proc encode* (s: string , safe = false ): string =
131
146
# # Encodes ``s`` into base64 representation.
132
147
# #
133
148
# # This procedure encodes a string.
134
149
# #
150
+ # # If ``safe`` is ``true`` then it will encode using the
151
+ # # URL-Safe and Filesystem-safe standard alphabet characters,
152
+ # # which substitutes ``-`` instead of ``+`` and ``_`` instead of ``/``.
153
+ # # * https://en.wikipedia.org/wiki/Base64#URL_applications
154
+ # # * https://tools.ietf.org/html/rfc4648#page-7
155
+ # #
135
156
# # **See also:**
136
157
# # * `encode proc<#encode,openArray[T]>`_ for encoding an openarray
137
158
# # * `decode proc<#decode,string>`_ for decoding a string
138
159
runnableExamples:
139
160
assert encode(" Hello World" ) == " SGVsbG8gV29ybGQ="
140
- encodeInternal(s)
161
+ if safe: encodeInternal(s, cb64safe)
162
+ else : encodeInternal(s, cb64)
141
163
142
164
proc encodeMIME* (s: string , lineLen = 75 , newLine = " \r\n " ): string =
143
165
# # Encodes ``s`` into base64 representation as lines.
@@ -232,6 +254,3 @@ proc decode*(s: string): string =
232
254
outputChar(a shl 2 or b shr 4 )
233
255
outputChar(b shl 4 or c shr 2 )
234
256
result .setLen(outputIndex)
235
-
236
-
237
-
0 commit comments