-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathBase64Url.sol
76 lines (62 loc) · 2.24 KB
/
Base64Url.sol
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
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
/**
* @dev Encode (without '=' padding)
* @author evmbrahmin, adapted from hiromin's Base64URL libraries
*/
library Base64Url {
/**
* @dev Base64Url Encoding Table
*/
string internal constant ENCODING_TABLE =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
function encode(bytes memory data) internal pure returns (string memory) {
if (data.length == 0) return "";
// Load the table into memory
string memory table = ENCODING_TABLE;
string memory result = new string(4 * ((data.length + 2) / 3));
// @solidity memory-safe-assembly
assembly {
let tablePtr := add(table, 1)
let resultPtr := add(result, 32)
for {
let dataPtr := data
let endPtr := add(data, mload(data))
} lt(dataPtr, endPtr) {
} {
dataPtr := add(dataPtr, 3)
let input := mload(dataPtr)
mstore8(
resultPtr,
mload(add(tablePtr, and(shr(18, input), 0x3F)))
)
resultPtr := add(resultPtr, 1)
mstore8(
resultPtr,
mload(add(tablePtr, and(shr(12, input), 0x3F)))
)
resultPtr := add(resultPtr, 1)
mstore8(
resultPtr,
mload(add(tablePtr, and(shr(6, input), 0x3F)))
)
resultPtr := add(resultPtr, 1)
mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
resultPtr := add(resultPtr, 1)
}
// Remove the padding adjustment logic
switch mod(mload(data), 3)
case 1 {
// Adjust for the last byte of data
resultPtr := sub(resultPtr, 2)
}
case 2 {
// Adjust for the last two bytes of data
resultPtr := sub(resultPtr, 1)
}
// Set the correct length of the result string
mstore(result, sub(resultPtr, add(result, 32)))
}
return result;
}
}