@@ -80,6 +80,37 @@ library Base58 {
8080 }
8181 }
8282
83+ /// @dev Encodes the `data` word into a Base58 string.
84+ function encodeWord (bytes32 data ) internal pure returns (string memory result ) {
85+ /// @solidity memory-safe-assembly
86+ assembly {
87+ let o := add (mload (0x40 ), 0x4c ) // 32 for word, 44 for maximum possible length.
88+ let e := o
89+
90+ // Use the extended scratch space for the lookup. We'll restore 0x40 later.
91+ mstore (0x1f , "123456789ABCDEFGHJKLMNPQRSTUVWXY " )
92+ mstore (0x3f , "Zabcdefghijkmnopqrstuvwxyz " )
93+
94+ let w := not (0 ) // -1.
95+ let z := shl (5 , iszero (data)) // Number of leading zeroes in `data`.
96+ if iszero (z) {
97+ for { let v := data } v { v := div (v, 58 ) } {
98+ o := add (o, w)
99+ mstore8 (o, mload (mod (v, 58 )))
100+ }
101+ for {} iszero (byte (z, data)) { z := add (z, 1 ) } {} // Just loop, `z` is often tiny.
102+ }
103+ if z { mstore (sub (o, 0x20 ), mul (div (w, 0xff ), 49 )) } // '1111...1111' in ASCII.
104+ o := sub (o, z)
105+
106+ let n := sub (e, o) // Compute the final length.
107+ result := sub (o, 0x20 ) // Move back one word for the length.
108+ mstore (result, n) // Store the length.
109+ mstore (add (add (result, 0x20 ), n), 0 ) // Zeroize the slot after the bytes.
110+ mstore (0x40 , add (add (result, 0x40 ), n)) // Allocate memory.
111+ }
112+ }
113+
83114 /// @dev Decodes `encoded`, a Base58 string, into the original bytes.
84115 function decode (string memory encoded ) internal pure returns (bytes memory result ) {
85116 uint256 n = bytes (encoded).length ;
@@ -140,4 +171,19 @@ library Base58 {
140171 mstore (0x40 , add (add (result, 0x40 ), l)) // Allocate memory.
141172 }
142173 }
174+
175+ /// @dev Decodes `encoded`, a Base58 string, into the original word.
176+ function decodeWord (string memory encoded ) internal pure returns (bytes32 result ) {
177+ // Specializing and optimizing this for bytes32 is left as an exercise to the reader.
178+ bytes memory t = decode (encoded);
179+ /// @solidity memory-safe-assembly
180+ assembly {
181+ let n := mload (t)
182+ if iszero (lt (n, 0x21 )) {
183+ mstore (0x00 , 0xe8fad793 ) // `Base58DecodingError()`.
184+ revert (0x1c , 0x04 )
185+ }
186+ result := mload (add (t, n))
187+ }
188+ }
143189}
0 commit comments