You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.9 KiB
88 lines
2.9 KiB
/*
|
|
* Copyright (c) 2017 m2049r er al.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.wownero.wownerujo.util;
|
|
|
|
// based on https://rosettacode.org/wiki/Bitcoin/address_validation#Java
|
|
|
|
import com.wownero.wownerujo.model.NetworkType;
|
|
import com.wownero.wownerujo.model.WalletManager;
|
|
|
|
import java.math.BigInteger;
|
|
import java.security.MessageDigest;
|
|
import java.security.NoSuchAlgorithmException;
|
|
import java.util.Arrays;
|
|
|
|
public class BitcoinAddressValidator {
|
|
|
|
private static final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
|
|
public static boolean validate(String addrress) {
|
|
return validate(addrress,
|
|
WalletManager.getInstance().getNetworkType() != NetworkType.NetworkType_Mainnet);
|
|
}
|
|
|
|
public static boolean validate(String addrress, boolean testnet) {
|
|
if (addrress.length() < 26 || addrress.length() > 35)
|
|
return false;
|
|
byte[] decoded = decodeBase58To25Bytes(addrress);
|
|
if (decoded == null)
|
|
return false;
|
|
|
|
int v = decoded[0] & 0xFF;
|
|
if (!testnet) {
|
|
if ((v != 0x00) && (v != 0x05)) return false;
|
|
} else {
|
|
if ((v != 0x6f) && (v != 0xc4)) return false;
|
|
}
|
|
|
|
byte[] hash1 = sha256(Arrays.copyOfRange(decoded, 0, 21));
|
|
byte[] hash2 = sha256(hash1);
|
|
|
|
return Arrays.equals(Arrays.copyOfRange(hash2, 0, 4), Arrays.copyOfRange(decoded, 21, 25));
|
|
}
|
|
|
|
private static byte[] decodeBase58To25Bytes(String input) {
|
|
BigInteger num = BigInteger.ZERO;
|
|
for (char t : input.toCharArray()) {
|
|
int p = ALPHABET.indexOf(t);
|
|
if (p == -1)
|
|
return null;
|
|
num = num.multiply(BigInteger.valueOf(58)).add(BigInteger.valueOf(p));
|
|
}
|
|
|
|
byte[] result = new byte[25];
|
|
byte[] numBytes = num.toByteArray();
|
|
if (num.bitLength() > 200) return null;
|
|
|
|
if (num.bitLength() == 200) {
|
|
System.arraycopy(numBytes, 1, result, 0, 25);
|
|
} else {
|
|
System.arraycopy(numBytes, 0, result, result.length - numBytes.length, numBytes.length);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static byte[] sha256(byte[] data) {
|
|
try {
|
|
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
|
md.update(data);
|
|
return md.digest();
|
|
} catch (NoSuchAlgorithmException e) {
|
|
throw new IllegalStateException(e);
|
|
}
|
|
}
|
|
} |