我还没有找到在swift中将base64URL解码为base64格式的正确方法。
根据base64url转base64,hJQWHABDBjoPHorYF5xghQ
(base64URL)应该是hJQWHABDBjoPHorYF5xghQ==
(base64)。这里可能存在更多差异。
stackoverflow上没有解决方案。
我还没有找到在swift中将base64URL解码为base64格式的正确方法。
根据base64url转base64,hJQWHABDBjoPHorYF5xghQ
(base64URL)应该是hJQWHABDBjoPHorYF5xghQ==
(base64)。这里可能存在更多差异。
stackoverflow上没有解决方案。
“base64url”与标准Base64编码有两个不同之处:
-
和_
代替了+
和/
)(参见https://en.wikipedia.org/wiki/Base64#Variants_summary_table)。
下面是一种可能的转换函数:
func base64urlToBase64(base64url: String) -> String {
var base64 = base64url
.replacingOccurrences(of: "-", with: "+")
.replacingOccurrences(of: "_", with: "/")
if base64.characters.count % 4 != 0 {
base64.append(String(repeating: "=", count: 4 - base64.characters.count % 4))
}
return base64
}
示例:
let base64url = "hJQWHABDBjoPHorYF5xghQ"
let base64 = base64urlToBase64(base64url: base64url)
print(base64) // hJQWHABDBjoPHorYF5xghQ==
if let data = Data(base64Encoded: base64) {
print(data as NSData) // <8494161c 0043063a 0f1e8ad8 179c6085>
}
为了完整起见,这将是相反的转换:
func base64ToBase64url(base64: String) -> String {
let base64url = base64
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "=", with: "")
return base64url
}
Swift 4更新:
func base64urlToBase64(base64url: String) -> String {
var base64 = base64url
.replacingOccurrences(of: "-", with: "+")
.replacingOccurrences(of: "_", with: "/")
if base64.count % 4 != 0 {
base64.append(String(repeating: "=", count: 4 - base64.count % 4))
}
return base64
}
import Foundation
/// Extension for making base64 representations of `Data` safe for
/// transmitting via URL query parameters
extension Data {
/// Instantiates data by decoding a base64url string into base64
///
/// - Parameter string: A base64url encoded string
init?(base64URLEncoded string: String) {
self.init(base64Encoded: string.toggleBase64URLSafe(on: false))
}
/// Encodes the string into a base64url safe representation
///
/// - Returns: A string that is base64 encoded but made safe for passing
/// in as a query parameter into a URL string
func base64URLEncodedString() -> String {
return self.base64EncodedString().toggleBase64URLSafe(on: true)
}
}
extension String {
/// Encodes or decodes into a base64url safe representation
///
/// - Parameter on: Whether or not the string should be made safe for URL strings
/// - Returns: if `on`, then a base64url string; if `off` then a base64 string
func toggleBase64URLSafe(on: Bool) -> String {
if on {
// Make base64 string safe for passing into URL query params
let base64url = self.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "=", with: "")
return base64url
} else {
// Return to base64 encoding
var base64 = self.replacingOccurrences(of: "_", with: "/")
.replacingOccurrences(of: "-", with: "+")
// Add any necessary padding with `=`
if base64.count % 4 != 0 {
base64.append(String(repeating: "=", count: 4 - base64.count % 4))
}
return base64
}
}
}
这是Base64URL转Base64的Objective-C版本
-(NSString *) base64urlToBase64 :(NSString *)base64url {
NSString * base64 = [base64url stringByReplacingOccurrencesOfString:@"-" withString:@"+"];
base64 = [base64 stringByReplacingOccurrencesOfString:@"_" withString:@"/"];
if(base64.length % 4 != 0)
{
base64 = [base64 stringByAppendingString:[self stringWithRepeatString:"=" times:(4 - base64.length % 4)]];
}
return base64;
}
- (NSString *)stringWithRepeatString:(char *)characters times:(unsigned int)repetitions; {
unsigned long stringLength = strlen(characters);
unsigned long repeatStringLength = stringLength * repetitions + 1;
char repeatString[repeatStringLength];
for (unsigned int i = 0; i < repetitions; i++) {
unsigned int pointerPosition = i * repetitions;
memcpy(repeatString + pointerPosition, characters, stringLength);
}
repeatString[repeatStringLength - 1] = 0;
return [NSString stringWithCString:repeatString encoding:NSASCIIStringEncoding];
}