Bitcoin/address validation: Difference between revisions
Content deleted Content added
m Add initial dart implementation of btc address validation |
|||
Line 417: | Line 417: | ||
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz": not Bitcoin version 0. |
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz": not Bitcoin version 0. |
||
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62izz": too long Bitcoin address.</pre> |
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62izz": too long Bitcoin address.</pre> |
||
=={{header|Dart}}== |
|||
This requires [https://pub.dev/packages/crypto Crypto package] to compile. |
|||
<lang dart> |
|||
import 'package:crypto/crypto.dart'; |
|||
class Bitcoin { |
|||
final String ALPHABET = |
|||
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; |
|||
List<int> bigIntToByteArray(BigInt data) { |
|||
String str; |
|||
bool neg = false; |
|||
if (data < BigInt.zero) { |
|||
str = (~data).toRadixString(16); |
|||
neg = true; |
|||
} else str = data.toRadixString(16); |
|||
int p = 0; |
|||
int len = str.length; |
|||
int blen = (len + 1) ~/ 2; |
|||
int boff = 0; |
|||
List bytes; |
|||
if (neg) { |
|||
if (len & 1 == 1) { |
|||
p = -1; |
|||
} |
|||
int byte0 = ~int.parse(str.substring(0, p + 2), radix: 16); |
|||
if (byte0 < -128) byte0 += 256; |
|||
if (byte0 >= 0) { |
|||
boff = 1; |
|||
bytes = new List<int>(blen + 1); |
|||
bytes[0] = -1; |
|||
bytes[1] = byte0; |
|||
} else { |
|||
bytes = new List<int>(blen); |
|||
bytes[0] = byte0; |
|||
} |
|||
for (int i = 1; i < blen; ++i) { |
|||
int byte = ~int.parse(str.substring(p + (i << 1), p + (i << 1) + 2), |
|||
radix: 16); |
|||
if (byte < -128) byte += 256; |
|||
bytes[i + boff] = byte; |
|||
} |
|||
} else { |
|||
if (len & 1 == 1) { |
|||
p = -1; |
|||
} |
|||
int byte0 = int.parse(str.substring(0, p + 2), radix: 16); |
|||
if (byte0 > 127) byte0 -= 256; |
|||
if (byte0 < 0) { |
|||
boff = 1; |
|||
bytes = new List<int>(blen + 1); |
|||
bytes[0] = 0; |
|||
bytes[1] = byte0; |
|||
} else { |
|||
bytes = new List<int>(blen); |
|||
bytes[0] = byte0; |
|||
} |
|||
for (int i = 1; i < blen; ++i) { |
|||
int byte = |
|||
int.parse(str.substring(p + (i << 1), p + (i << 1) + 2), radix: 16); |
|||
if (byte > 127) byte -= 256; |
|||
bytes[i + boff] = byte; |
|||
} |
|||
} |
|||
return bytes; |
|||
} |
|||
List<int> arrayCopy(bytes, srcOffset, result, destOffset, bytesLength) { |
|||
for (int i = srcOffset; i < bytesLength; i++) { |
|||
result[destOffset + i] = bytes[i]; |
|||
} |
|||
return result; |
|||
} |
|||
List<int> decodeBase58To25Bytes(String input) { |
|||
BigInt number = BigInt.zero; |
|||
for (String t in input.split('')) { |
|||
int p = ALPHABET.indexOf(t); |
|||
if (p == (-1)) |
|||
return null; |
|||
number = number * (BigInt.from(58)) + (BigInt.from(p)); |
|||
} |
|||
List<int> result = new List<int>(24); |
|||
List<int> numBytes = bigIntToByteArray(number); |
|||
return arrayCopy( |
|||
numBytes, 0, result, result.length - numBytes.length, numBytes.length); |
|||
} |
|||
validateAddress(String address) { |
|||
List<int> decoded = new List.from(decodeBase58To25Bytes(address)); |
|||
List<int> temp = new List<int>.from(decoded); |
|||
temp.insert(0, 0); |
|||
List<int> hash1 = sha256.convert(temp.sublist(0, 21)).bytes; |
|||
List<int> hash2 = sha256.convert(hash1).bytes; |
|||
if (hash2[0] != decoded[20] || |
|||
hash2[1] != decoded[21] || |
|||
hash2[2] != decoded[22] || |
|||
hash2[3] != decoded[23]) return false; |
|||
return true; |
|||
} |
|||
} |
|||
</lang> |
|||
{{out}} |
|||
<pre>"1BNGaR29FmfAqidXmD9HLwsGv9p5WVvvhq" true |
|||
"1BNGaR29FmfAqidXmD9HLws" false |
|||
</pre> |
|||
=={{header|Delphi}}== |
=={{header|Delphi}}== |