123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- // SPDX-License-Identifier: MIT
- // OpenZeppelin Contracts (last updated v5.1.0-rc.1) (utils/Strings.sol)
- pragma solidity ^0.8.20;
- import {Math} from "./math/Math.sol";
- import {SignedMath} from "./math/SignedMath.sol";
- /**
- * @dev String operations.
- */
- library Strings {
- bytes16 private constant HEX_DIGITS = "0123456789abcdef";
- uint8 private constant ADDRESS_LENGTH = 20;
- /**
- * @dev The `value` string doesn't fit in the specified `length`.
- */
- error StringsInsufficientHexLength(uint256 value, uint256 length);
- /**
- * @dev Converts a `uint256` to its ASCII `string` decimal representation.
- */
- function toString(uint256 value) internal pure returns (string memory) {
- unchecked {
- uint256 length = Math.log10(value) + 1;
- string memory buffer = new string(length);
- uint256 ptr;
- assembly ("memory-safe") {
- ptr := add(buffer, add(32, length))
- }
- while (true) {
- ptr--;
- assembly ("memory-safe") {
- mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
- }
- value /= 10;
- if (value == 0) break;
- }
- return buffer;
- }
- }
- /**
- * @dev Converts a `int256` to its ASCII `string` decimal representation.
- */
- function toStringSigned(int256 value) internal pure returns (string memory) {
- return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
- }
- /**
- * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
- */
- function toHexString(uint256 value) internal pure returns (string memory) {
- unchecked {
- return toHexString(value, Math.log256(value) + 1);
- }
- }
- /**
- * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
- */
- function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
- uint256 localValue = value;
- bytes memory buffer = new bytes(2 * length + 2);
- buffer[0] = "0";
- buffer[1] = "x";
- for (uint256 i = 2 * length + 1; i > 1; --i) {
- buffer[i] = HEX_DIGITS[localValue & 0xf];
- localValue >>= 4;
- }
- if (localValue != 0) {
- revert StringsInsufficientHexLength(value, length);
- }
- return string(buffer);
- }
- /**
- * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal
- * representation.
- */
- function toHexString(address addr) internal pure returns (string memory) {
- return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
- }
- /**
- * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal
- * representation, according to EIP-55.
- */
- function toChecksumHexString(address addr) internal pure returns (string memory) {
- bytes memory buffer = bytes(toHexString(addr));
- // hash the hex part of buffer (skip length + 2 bytes, length 40)
- uint256 hashValue;
- assembly ("memory-safe") {
- hashValue := shr(96, keccak256(add(buffer, 0x22), 40))
- }
- for (uint256 i = 41; i > 1; --i) {
- // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f)
- if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) {
- // case shift by xoring with 0x20
- buffer[i] ^= 0x20;
- }
- hashValue >>= 4;
- }
- return string(buffer);
- }
- /**
- * @dev Returns true if the two strings are equal.
- */
- function equal(string memory a, string memory b) internal pure returns (bool) {
- return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
- }
- }
|