Nguyen Hung Nguyen Hung - 1 month ago 15
Swift Question

How to encode string (use encrypt MessageDigest in Java) to Base64 string in swift?

In Java, i used this:

public void encryptData() {
String data = "Hello World";
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
if (md == null) {
String dataEncoded = Base64.encodeToString(md.digest(), 11);
return dataEncoded; //print: sQqNsWTgdUEFt6mb5y4_5Q

How do I do have the same results in Swift ?



func test() -> Void {
var data: String = "Hello World"
data = md5(data)
data = base64Encode(data)
print("data = \(data)") //YjEwYThkYjE2NGUwNzU0MTA1YjdhOTliZTcyZTNmZTU=

md5 and base64Encode function used from md5 here and base64 here

Any hints will be helpful.


Your code does not produce the expected result because the referenced md5() function returns the message digest as a hex-encoded string, which is then Base64 encoded. So instead of

 String -> UTF-8 data -> MD5 digest -> Base64 encoding

you are doing

 String -> UTF-8 data -> MD5 digest -> hex encoding -> Base64 encoding

A small modification of the function returns the message digest as data:

func md5(string string: String) -> NSData {
    var digest = [UInt8](count: Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)
    let data = string.dataUsingEncoding(NSUTF8StringEncoding)! // Conversion to UTF-8 cannot fail
    CC_MD5(data.bytes, CC_LONG(data.length), &digest)
    return NSData(bytes: digest, length: digest.count)

Now you can compute the Base 64 encoded MD5 digest:

let string = "Hello World"

// Compute MD5 message digest:
let md5data = md5(string: string)
print("md5data = \(md5data)") // md5data = <b10a8db1 64e07541 05b7a99b e72e3fe5>

// Convert to Base 64 encoded string:
let base64 = md5data.base64EncodedStringWithOptions([])
print("base64 = \(base64)") // base64 = sQqNsWTgdUEFt6mb5y4/5Q==

This is almost what you expect. The Java code apparently produces the so-called "base64url" variant without padding (compare

Therefore we have to modify two characters and remove the padding:

let base64url = base64
    .stringByReplacingOccurrencesOfString("+", withString: "-")
    .stringByReplacingOccurrencesOfString("/", withString: "_")
    .stringByReplacingOccurrencesOfString("=", withString: "")
print("base64url = \(base64url)") // base64url = sQqNsWTgdUEFt6mb5y4_5Q

Now the result is sQqNsWTgdUEFt6mb5y4_5Q, and identical to what you got from the Java code.