This repository has been archived by the owner on Feb 29, 2024. It is now read-only.
/
Base58.swift
63 lines (52 loc) · 1.76 KB
/
Base58.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
//
// Base58Conversion.swift
// Indy-demoTests
//
// Created by Anastasia Tarasova on 06/06/2019.
// Copyright © 2019 Hyperledger. All rights reserved.
//
import Foundation
import BigInt
public enum Base58Alphabet {
public static let btc = [UInt8]("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".utf8)
public static let flickr = [UInt8]("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ".utf8)
}
@objc(Base58)
public class Base58: NSObject {
@objc
public static func encode(_ bytes: Data) -> String?
{
let alphabet: [UInt8] = Base58Alphabet.btc
var x = BigUInt(bytes)
let radix = BigUInt(alphabet.count)
var answer = [UInt8]()
answer.reserveCapacity(bytes.count)
while x > 0 {
let (quotient, modulus) = x.quotientAndRemainder(dividingBy: radix)
answer.append(alphabet[Int(modulus)])
x = quotient
}
let prefix = Array(bytes.prefix(while: {$0 == 0})).map { _ in alphabet[0] }
answer.append(contentsOf: prefix)
answer.reverse()
return String(bytes: answer, encoding: .utf8)
}
@objc
public static func decode(_ string: String) -> Data? {
let alphabet: [UInt8] = Base58Alphabet.btc
var answer = BigUInt(0)
var j = BigUInt(1)
let radix = BigUInt(alphabet.count)
let byteString = [UInt8](string.utf8)
for ch in byteString.reversed() {
if let index = alphabet.firstIndex(of: ch) {
answer = answer + (j * BigUInt(index))
j *= radix
} else {
return nil
}
}
let bytes = answer.serialize()
return byteString.prefix(while: { i in i == alphabet[0]}) + bytes
}
}