| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- import 'dart:convert' show utf8;
- import 'dart:typed_data';
- import 'package:convert/convert.dart' show hex;
- import "package:pointycastle/digests/keccak.dart";
- bool isHexPrefixed(String str) {
- ArgumentError.checkNotNull(str);
- return str.startsWith('0x');
- }
- /// Is the string a hex string.
- bool isHexString(String value, {int length = 0}) {
- ArgumentError.checkNotNull(value);
- // if (!RegExp('^0x[0-9A-Fa-f]*\$').hasMatch(value)) return false;
- if (!RegExp(r'\b(?:0[xX])?[0-9a-fA-F]+\b').hasMatch(value)) return false;
- if (length > 0 && value.length != 2 + 2 * length) return false;
- return true;
- }
- String stripHexPrefix(String hexString) {
- ArgumentError.checkNotNull(hexString);
- if (hexString.startsWith("0x") || hexString.startsWith("0X")) {
- return hexString.substring(2);
- }
- return hexString;
- }
- String addHexPrefix(String hexString) {
- ArgumentError.checkNotNull(hexString);
- if (!hexString.startsWith("0x") && !hexString.startsWith("0X")) {
- return '0x$hexString';
- }
- return hexString;
- }
- /// Pads a [String] to have an even length
- String padToEven(String value) {
- ArgumentError.checkNotNull(value);
- var a = '$value';
- if (a.length % 2 == 1) a = '0${a}';
- return a;
- }
- /// Converts a [int] into a hex [String]
- String intToHex(i) {
- ArgumentError.checkNotNull(i);
- return '0x${i.toRadixString(16)}';
- }
- /// Converts an [int] or [BigInt] to a [Uint8List]
- Uint8List intToBuffer(i) {
- return Uint8List.fromList(i == null || i == 0 || i == BigInt.zero ? [] : hex.decode(padToEven(intToHex(i).substring(2))));
- }
- Uint8List stringToBuffer(String i) {
- return Uint8List.fromList(i.isEmpty ? [] : hex.decode(padToEven(stripHexPrefix(i))));
- }
- /// Get the binary size of a string
- int getBinarySize(String str) {
- ArgumentError.checkNotNull(str);
- return utf8.encode(str).length;
- }
- /// Returns TRUE if the first specified array contains all elements from the second one. FALSE otherwise.
- bool arrayContainsArray(List superset, List subset, {bool some = false}) {
- ArgumentError.checkNotNull(superset);
- ArgumentError.checkNotNull(subset);
- if (some) return Set.from(superset).intersection(Set.from(subset)).length > 0;
- return Set.from(superset).containsAll(subset);
- }
- /// Should be called to get utf8 from it's hex representation
- String toUtf8(String hexString) {
- ArgumentError.checkNotNull(hexString);
- List<int> bufferValue = hex.decode(padToEven(stripHexPrefix(hexString).replaceAll(RegExp('^0+|0+\$'), '')));
- return utf8.decode(bufferValue);
- }
- /// Should be called to get ascii from it's hex representation
- String toAscii(String hexString) {
- ArgumentError.checkNotNull(hexString);
- var start = hexString.startsWith(RegExp('^0x')) ? 2 : 0;
- return String.fromCharCodes(hex.decode(hexString.substring(start)));
- }
- /// Should be called to get hex representation (prefixed by 0x) of utf8 string
- String fromUtf8(String stringValue) {
- ArgumentError.checkNotNull(stringValue);
- var stringBuffer = utf8.encode(stringValue);
- return "0x${padToEven(hex.encode(stringBuffer)).replaceAll(RegExp('^0+|0+\$'), '')}";
- }
- /// Should be called to get hex representation (prefixed by 0x) of ascii string
- String fromAscii(String stringValue) {
- ArgumentError.checkNotNull(stringValue);
- var hexString = '';
- for (var i = 0; i < stringValue.length; i++) {
- var code = stringValue.codeUnitAt(i);
- var n = hex.encode([code]);
- hexString += n.length < 2 ? '0${n}' : n;
- }
- return '0x$hexString';
- }
- Uint8List hexToBytes(String hexStr) {
- final bytes = hex.decode(stripHexPrefix(hexStr));
- if (bytes is Uint8List) return bytes;
- return Uint8List.fromList(bytes);
- }
- String bytesToHex(List<int> bytes,
- {bool include0x = false,
- int? forcePadLength,
- bool padToEvenLength = false}) {
- var encoded = hex.encode(bytes);
- if (forcePadLength != null) {
- assert(forcePadLength >= encoded.length);
- final padding = forcePadLength - encoded.length;
- encoded = ('0' * padding) + encoded;
- }
- if (padToEvenLength && encoded.length % 2 != 0) encoded = '0$encoded';
- return (include0x ? '0x' : '') + encoded;
- }
- // ------------ by myself -----------
- String hex2ascii(String hexString) {
- try {
- if (isHexString(hexString)) {
- hexString = stripHexPrefix(hexString);
- List<String> splitted = [];
- for (int i = 0; i < hexString.length; i = i + 2) {
- splitted.add(hexString.substring(i, i + 2));
- }
- String ascii = List.generate(splitted.length,
- (i) => String.fromCharCode(int.parse(splitted[i], radix: 16))).join();
- return ascii;
- } else {
- return '';
- }
- } catch (error) {
- return '';
- }
- }
- String ascii2hex(String asciiString) {
- try {
- if (asciiString.isNotEmpty) {
- String hexStr = '';
- for (int i = 0; i < asciiString.length; ++i) {
- hexStr = hexStr + asciiString.codeUnitAt(i).toRadixString(16);
- }
- return hexStr;
- } else {
- return '';
- }
- } catch (error) {
- return '';
- }
- }
- String hex2dec(String hexString) {
- try {
- if (isHexString(hexString)) {
- BigInt? bgInt = BigInt.tryParse(stripHexPrefix(hexString), radix:16);
- if (bgInt != null) {
- return bgInt.toRadixString(10);
- }
- }
- // else
- return '';
- } catch (error) {
- return '';
- }
- }
- String dec2hex(String decString) {
- try {
- if (decString.isNotEmpty) {
- BigInt? bgInt = BigInt.tryParse(decString, radix:10);
- if (bgInt != null) {
- return addHexPrefix(bgInt.toRadixString(16));
- }
- }
- // else
- return '';
- } catch (error) {
- return '';
- }
- }
- /// ----- to Hash -----
- /// 注意:Hash256 和 Keccak256 其实不一样,
- /// 但由于最早接触 Ethereum 相关代码,其中 Hash 使用的是 Keccak256,
- /// 造成App其他地方的 Hash 也都沿用了 Keccak256。
- /// 历史原因,不做修改。[2023-12-15 James.Zhang]
- String toHash(String anyString) {
- return toKeccak256(anyString);
- }
- String toKeccak256(String anyString, [int bitLength = 256]) {
- var keccak = KeccakDigest(bitLength);
- keccak.update(
- Uint8List.fromList(anyString.codeUnits),
- 0,
- anyString.codeUnits.length,
- );
- var out = Uint8List(bitLength ~/ 8);
- keccak.doFinal(out, 0);
- return _uint8ListToHex(out);
- }
- /// Character `0`.
- const int _zero = 0x30;
- /// Character `a`.
- const int _a = 0x61;
- String _uint8ListToHex(List<int> bytes) {
- final buffer = Uint8List(bytes.length * 2);
- int bufferIndex = 0;
- for (var i = 0; i < bytes.length; i++) {
- var byte = bytes[i];
- // The bitwise arithmetic here is equivalent to `byte ~/ 16` and `byte % 16`
- // for valid byte values, but is easier for dart2js to optimize given that
- // it can't prove that [byte] will always be positive.
- buffer[bufferIndex++] = _codeUnitForDigit((byte & 0xF0) >> 4);
- buffer[bufferIndex++] = _codeUnitForDigit(byte & 0x0F);
- }
- return String.fromCharCodes(buffer);
- }
- /// Returns the ASCII/Unicode code unit corresponding to the hexadecimal digit
- /// [digit].
- int _codeUnitForDigit(int digit) =>
- digit < 10 ? digit + _zero : digit + _a - 10;
|