All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.DNAProject.crypto.Base58 Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2018 The DNA Authors
 * This file is part of The DNA library.
 *
 *  The DNA is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  The DNA is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with The DNA.  If not, see .
 *
 */

package com.github.DNAProject.crypto;

import com.github.DNAProject.common.ErrorCode;
import com.github.DNAProject.sdk.exception.SDKException;

import java.math.BigInteger;
import java.util.Arrays;

public class Base58 {
    /**
     *  base58
     */
    public static final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
    private static final BigInteger BASE = BigInteger.valueOf(ALPHABET.length());

    /**
     * decode base58
     * @param input
     * @return
     */
    public static byte[] decode(String input) {
        BigInteger bi = BigInteger.ZERO;
        for (int i = input.length() - 1; i >= 0; i--) {
            int index = ALPHABET.indexOf(input.charAt(i));
            if (index == -1) {
                throw new IllegalArgumentException();
            }
            bi = bi.add(BASE.pow(input.length() - 1 - i).multiply(BigInteger.valueOf(index)));
        }
        byte[] bytes = bi.toByteArray();
        boolean stripSignByte = bytes.length > 1 && bytes[0] == 0 && bytes[1] < 0;
        int leadingZeros = 0;
        for (; leadingZeros < input.length() && input.charAt(leadingZeros) == ALPHABET.charAt(0); leadingZeros++){};
        byte[] tmp = new byte[bytes.length - (stripSignByte ? 1 : 0) + leadingZeros];
        System.arraycopy(bytes, stripSignByte ? 1 : 0, tmp, leadingZeros, tmp.length - leadingZeros);
        return tmp;
    }

    /**
     * encode
     * @param input
     * @return
     */
    public static String encode(byte[] input) {
        BigInteger value = new BigInteger(1, input);
        StringBuilder sb = new StringBuilder();
        while (value.compareTo(BASE) >= 0) {
        	BigInteger[] r = value.divideAndRemainder(BASE);
            sb.insert(0, ALPHABET.charAt(r[1].intValue()));
            value = r[0];
        }
        sb.insert(0, ALPHABET.charAt(value.intValue()));
        for (byte b : input) {
            if (b == 0) {
                sb.insert(0, ALPHABET.charAt(0));
            } else {
                break;
            }
        }
        return sb.toString();
    }
    public static String checkSumEncode(byte[] in) {
        byte[] hash = Digest.sha256(Digest.sha256(in));
        byte[] checksum = Arrays.copyOfRange(hash, 0, 4);
        byte[] input = new byte[in.length+4];
        System.arraycopy(in, 0, input, 0, in.length);
        System.arraycopy(checksum, 0, input, in.length, 4);
        return  encode(input);
    }

    public static byte[] decodeChecked(String input) throws Exception {

        byte[] decoded  = decode(input);
        if (decoded.length < 4) {
            throw new Exception(ErrorCode.InputTooShort);
        }
        byte[] data = Arrays.copyOfRange(decoded, 0, decoded.length - 4);
        byte[] checksum = Arrays.copyOfRange(decoded, decoded.length - 4, decoded.length);
        byte[] actualChecksum = Arrays.copyOfRange(Digest.sha256(Digest.sha256(data)), 0, 4);
        if (!Arrays.equals(checksum, actualChecksum)) {
            throw new SDKException(ErrorCode.ChecksumNotValidate);
        }
        return decoded;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy