-
Notifications
You must be signed in to change notification settings - Fork 13
/
base64url.clj
103 lines (87 loc) · 3.52 KB
/
base64url.clj
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
; Copyright (c) Alan Thompson. All rights reserved.
; The use and distribution terms for this software are covered by the Eclipse Public
; License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can be found in the
; file epl-v10.html at the root of this distribution. By using this software in any
; fashion, you are agreeing to be bound by the terms of this license.
; You must not remove this notice, or any other, from this software.
(ns tupelo.base64url
"Convert to/from traditional base64url encoding."
(:use tupelo.core)
(:require
[tupelo.types :as types]
[schema.core :as s] ))
; #todo -> code-chars (& other ns's)
(def encoding-char-set
"A set of chars used for traditional base64url encoding (incl. padding char)"
(set (glue
(chars-thru \a \z)
(chars-thru \A \Z)
(chars-thru \0 \9)
[\- \_ \=])))
(def ^:private b64-code-62 (byte \+))
(def ^:private b64-code-63 (byte \/ ))
(def ^:private b64-code-pad (byte \= ))
(def ^:private b64url-code-62 (byte \- ))
(def ^:private b64url-code-63 (byte \_ ))
(def ^:private b64url-code-pad (byte \= ))
(s/defn ^:no-doc b64->b64url :- [s/Int] ; #todo need test
"Converts a vector of byte values from base64 -> base64url encoding."
[byte-vec :- [s/Int]]
(forv [byte-val byte-vec]
(cond
(= byte-val b64-code-62) b64url-code-62
(= byte-val b64-code-63) b64url-code-63
(= byte-val b64-code-pad) b64url-code-pad
:default byte-val)))
(s/defn ^:no-doc b64url->b64 :- [s/Int]
"Converts a vector of byte values from base64url -> base64 encoding."
[byte-vec :- [s/Int]]
(forv [byte-val byte-vec]
(cond
(= byte-val b64url-code-62) b64-code-62
(= byte-val b64url-code-63) b64-code-63
(= byte-val b64url-code-pad) b64-code-pad
:default byte-val)))
(defn base64url-encoder []
(if-java-1-8-plus
(java.util.Base64/getUrlEncoder)
(throw (RuntimeException. "Unimplemented prior to Java 1.8: "))))
(defn base64url-decoder []
(if-java-1-8-plus
(java.util.Base64/getUrlDecoder)
(throw (RuntimeException. "Unimplemented prior to Java 1.8: "))))
(defn encode-byte-array
"Encodes a byte array into base64url, returning a new byte array."
[byte-arr]
(types/byte-array? byte-arr)
(.encode (base64url-encoder) byte-arr))
(defn decode-byte-array
"Decodes a byte array from base64url, returning a new byte array."
[byte-arr]
(types/byte-array? byte-arr)
(.decode (base64url-decoder) byte-arr))
(s/defn encode-byte-array->str :- s/Str
"Encodes a byte array into base64url, returning a String."
[byte-arr]
(types/byte-array? byte-arr)
(.encodeToString (base64url-encoder) byte-arr))
(s/defn decode-str->byte-array
"Decodes a base64url encoded String, returning a byte array"
[code-str :- s/Str]
(.decode (base64url-decoder) code-str))
(s/defn encode-bytes->str :- s/Str ; #todo need test
"Encodes a vector of byte values into base64url, returning a String."
[src-bytes :- [s/Int]]
(encode-byte-array->str (byte-array src-bytes)))
(s/defn decode-str->bytes :- [s/Int] ; #todo need test
"Decodes a base64url encoded String, returning a vector of byte values"
[code-str :- s/Str]
(vec (decode-str->byte-array code-str)))
(s/defn encode-str :- s/Str
"Encodes a String into base64url, returning a String."
[src-str :- s/Str]
(-> src-str types/str->byte-array encode-byte-array->str))
(s/defn decode-str :- s/Str
"Decodes a base64url encoded String, returning a String."
[code-str :- s/Str]
(-> code-str decode-str->byte-array types/byte-array->str))