1
// Copyright © 2017-2020 Trust Wallet.
2
//
3
// This file is part of Trust. The full Trust copyright notice, including
4
// terms governing use, modification, and redistribution, is contained in the
5
// file LICENSE at the root of the source code distribution tree.
6

7
#include "Base64.h"
8

9
#include <boost/algorithm/string.hpp>
10
#include <boost/archive/iterators/base64_from_binary.hpp>
11
#include <boost/archive/iterators/binary_from_base64.hpp>
12
#include <boost/archive/iterators/transform_width.hpp>
13

14
namespace TW::Base64 {
15

16
using namespace TW;
17
using namespace std;
18

19 1
Data decode(const string& val) {
20
    using namespace boost::archive::iterators;
21
    using It = transform_width<binary_from_base64<string::const_iterator>, 8, 6>;
22 1
    return boost::algorithm::trim_right_copy_if(Data(It(begin(val)), It(end(val))),
23 1
                                                [](char c) { return c == '\0'; });
24
}
25

26 1
string encode(const Data& val) {
27
    using namespace boost::archive::iterators;
28
    using It = base64_from_binary<transform_width<Data::const_iterator, 6, 8>>;
29 1
    auto encoded = string(It(begin(val)), It(end(val)));
30 1
    return encoded.append((3 - val.size() % 3) % 3, '=');
31
}
32

33
/// Convert from Base64Url format to regular
34 1
void convertFromBase64Url(string& b) {
35
    // '-' and '_' (Base64URL format) are changed to '+' and '/'
36
    // in-place replace
37 1
    size_t n = b.length();
38 1
    char* start = b.data();
39 1
    char* end = start + n;
40 1
    for(auto p = start; p < end; ++p) {
41 1
        if (*p == '-') { *p = '+'; }
42 1
        else if (*p == '_') { *p = '/'; }
43
    }
44
}
45

46
/// Convert from regular format to Base64Url
47 1
void convertToBase64Url(string& b) {
48
    // '+' and '/' are changed to '-' and '_' (Base64URL format)
49
    // in-place replace
50 1
    size_t n = b.length();
51 1
    char* start = b.data();
52 1
    char* end = start + n;
53 1
    for(auto p = start; p < end; ++p) {
54 1
        if (*p == '+') { *p = '-'; }
55 1
        else if (*p == '/') { *p = '_'; }
56
    }
57
}
58

59 1
Data decodeBase64Url(const string& val) {
60 1
    Data bytes;
61
    try {
62 1
        return decode(val);
63 1
    } catch (const exception& ex) {
64
        // 2nd try: Base64URL format (replaced by '-' and '_' by '+' and '/' )
65 1
        string base64Url = val;
66 1
        convertFromBase64Url(base64Url);
67 1
        return decode(base64Url);
68
    }
69
}
70

71 1
string encodeBase64Url(const Data& val) {
72
    using namespace boost::archive::iterators;
73
    using It = base64_from_binary<transform_width<Data::const_iterator, 6, 8>>;
74 1
    auto encoded = string(It(begin(val)), It(end(val)));
75 1
    encoded.append((3 - val.size() % 3) % 3, '=');
76 1
    convertToBase64Url(encoded);
77 1
    return encoded;
78
}
79

80
} // namespace TW::Base64

Read our documentation on viewing source code .

Loading