Add Base64 safe (#13672)

* Implement RFC-4648 Section-7
* https://github.com/nim-lang/Nim/pull/13672#issuecomment-600993466
This commit is contained in:
Juan Carlos
2020-03-20 06:21:42 -03:00
committed by GitHub
parent dd362ab4c0
commit 70d93636cb
3 changed files with 45 additions and 9 deletions

View File

@@ -46,6 +46,13 @@
## let decoded = decode("SGVsbG8gV29ybGQ=")
## assert decoded == "Hello World"
##
## URL Safe Base64
## ---------------
##
## .. code-block::nim
## import base64
## doAssert encode("c\xf7>", safe = true) == "Y_c-"
## doAssert encode("c\xf7>", safe = false) == "Y/c+"
##
## See also
## ========
@@ -56,9 +63,10 @@
const
cb64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
cb64safe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
invalidChar = 255
template encodeInternal(s: typed): untyped =
template encodeInternal(s: typed, alphabet: string): untyped =
## encodes `s` into base64 representation.
proc encodeSize(size: int): int =
return (size * 4 div 3) + 6
@@ -78,7 +86,7 @@ template encodeInternal(s: typed): untyped =
inc inputIndex
template outputChar(x: untyped) =
result[outputIndex] = cb64[x and 63]
result[outputIndex] = alphabet[x and 63]
inc outputIndex
template outputChar(c: char) =
@@ -112,12 +120,18 @@ template encodeInternal(s: typed): untyped =
result.setLen(outputIndex)
proc encode*[T: SomeInteger|char](s: openArray[T]): string =
proc encode*[T: SomeInteger|char](s: openArray[T], safe = false): string =
## Encodes `s` into base64 representation.
##
## This procedure encodes an openarray (array or sequence) of either integers
## or characters.
##
## If ``safe`` is ``true`` then it will encode using the
## URL-Safe and Filesystem-safe standard alphabet characters,
## which substitutes ``-`` instead of ``+`` and ``_`` instead of ``/``.
## * https://en.wikipedia.org/wiki/Base64#URL_applications
## * https://tools.ietf.org/html/rfc4648#page-7
##
## **See also:**
## * `encode proc<#encode,string>`_ for encoding a string
## * `decode proc<#decode,string>`_ for decoding a string
@@ -125,19 +139,27 @@ proc encode*[T: SomeInteger|char](s: openArray[T]): string =
assert encode(['n', 'i', 'm']) == "bmlt"
assert encode(@['n', 'i', 'm']) == "bmlt"
assert encode([1, 2, 3, 4, 5]) == "AQIDBAU="
encodeInternal(s)
if safe: encodeInternal(s, cb64safe)
else: encodeInternal(s, cb64)
proc encode*(s: string): string =
proc encode*(s: string, safe = false): string =
## Encodes ``s`` into base64 representation.
##
## This procedure encodes a string.
##
## If ``safe`` is ``true`` then it will encode using the
## URL-Safe and Filesystem-safe standard alphabet characters,
## which substitutes ``-`` instead of ``+`` and ``_`` instead of ``/``.
## * https://en.wikipedia.org/wiki/Base64#URL_applications
## * https://tools.ietf.org/html/rfc4648#page-7
##
## **See also:**
## * `encode proc<#encode,openArray[T]>`_ for encoding an openarray
## * `decode proc<#decode,string>`_ for decoding a string
runnableExamples:
assert encode("Hello World") == "SGVsbG8gV29ybGQ="
encodeInternal(s)
if safe: encodeInternal(s, cb64safe)
else: encodeInternal(s, cb64)
proc encodeMIME*(s: string, lineLen = 75, newLine = "\r\n"): string =
## Encodes ``s`` into base64 representation as lines.
@@ -232,6 +254,3 @@ proc decode*(s: string): string =
outputChar(a shl 2 or b shr 4)
outputChar(b shl 4 or c shr 2)
result.setLen(outputIndex)