This repository has been archived by the owner on Jun 27, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 50
/
Data+Base64URL.swift
133 lines (119 loc) 路 4.4 KB
/
Data+Base64URL.swift
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
import Bits
extension Data {
/// Decodes a base64-url encoded string to data.
///
/// https://tools.ietf.org/html/rfc4648#page-7
public init?(base64URLEncoded: String, options: Data.Base64DecodingOptions = []) {
self.init(base64Encoded: base64URLEncoded.base64URLUnescaped(), options: options)
}
/// Decodes base64-url encoded data.
///
/// https://tools.ietf.org/html/rfc4648#page-7
public init?(base64URLEncoded: Data, options: Data.Base64DecodingOptions = []) {
self.init(base64Encoded: base64URLEncoded.base64URLUnescaped(), options: options)
}
/// Encodes data to a base64-url encoded string.
///
/// https://tools.ietf.org/html/rfc4648#page-7
///
/// - parameter options: The options to use for the encoding. Default value is `[]`.
/// - returns: The base64-url encoded string.
public func base64URLEncodedString(options: Data.Base64EncodingOptions = []) -> String {
return base64EncodedString(options: options).base64URLEscaped()
}
/// Encodes data to base64-url encoded data.
///
/// https://tools.ietf.org/html/rfc4648#page-7
///
/// - parameter options: The options to use for the encoding. Default value is `[]`.
/// - returns: The base64-url encoded data.
public func base64URLEncodedData(options: Data.Base64EncodingOptions = []) -> Data {
return base64EncodedData(options: options).base64URLEscaped()
}
}
/// MARK: String Escape
extension String {
/// Converts a base64-url encoded string to a base64 encoded string.
///
/// https://tools.ietf.org/html/rfc4648#page-7
public func base64URLUnescaped() -> String {
let replaced = replacingOccurrences(of: "-", with: "+")
.replacingOccurrences(of: "_", with: "/")
/// https://stackoverflow.com/questions/43499651/decode-base64url-to-base64-swift
let padding = replaced.count % 4
if padding > 0 {
return replaced + String(repeating: "=", count: 4 - padding)
} else {
return replaced
}
}
/// Converts a base64 encoded string to a base64-url encoded string.
///
/// https://tools.ietf.org/html/rfc4648#page-7
public func base64URLEscaped() -> String {
return replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "=", with: "")
}
/// Converts a base64-url encoded string to a base64 encoded string.
///
/// https://tools.ietf.org/html/rfc4648#page-7
public mutating func base64URLUnescape() {
self = base64URLUnescaped()
}
/// Converts a base64 encoded string to a base64-url encoded string.
///
/// https://tools.ietf.org/html/rfc4648#page-7
public mutating func base64URLEscape() {
self = base64URLEscaped()
}
}
/// MARK: Data Escape
extension Data {
/// Converts base64-url encoded data to a base64 encoded data.
///
/// https://tools.ietf.org/html/rfc4648#page-7
public mutating func base64URLUnescape() {
for (i, byte) in enumerated() {
switch byte {
case .hyphen: self[i] = .plus
case .underscore: self[i] = .forwardSlash
default: break
}
}
/// https://stackoverflow.com/questions/43499651/decode-base64url-to-base64-swift
let padding = count % 4
if padding > 0 {
self += Data(repeating: .equals, count: 4 - count % 4)
}
}
/// Converts base64 encoded data to a base64-url encoded data.
///
/// https://tools.ietf.org/html/rfc4648#page-7
public mutating func base64URLEscape() {
for (i, byte) in enumerated() {
switch byte {
case .plus: self[i] = .hyphen
case .forwardSlash: self[i] = .underscore
default: break
}
}
self = split(separator: .equals).first ?? .init()
}
/// Converts base64-url encoded data to a base64 encoded data.
///
/// https://tools.ietf.org/html/rfc4648#page-7
public func base64URLUnescaped() -> Data {
var data = self
data.base64URLUnescape()
return data
}
/// Converts base64 encoded data to a base64-url encoded data.
///
/// https://tools.ietf.org/html/rfc4648#page-7
public func base64URLEscaped() -> Data {
var data = self
data.base64URLEscape()
return data
}
}