java base58编码_base58 编码、解码
时间: 2024-01-15 19:03:10 浏览: 159
BASE 58 编解码源码
5星 · 资源好评率100%
Base58编码是一种用于数字和字母的编码方式,它主要用于比特币地址、IPFS哈希等。
Java中实现Base58编码的方法如下:
```java
import java.math.BigInteger;
import java.util.Arrays;
public class Base58 {
private static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
private static final int BASE_58 = ALPHABET.length;
public static String encode(byte[] input) {
if (input.length == 0) {
return "";
}
// Count leading zeros.
int zeros = 0;
while (zeros < input.length && input[zeros] == 0) {
++zeros;
}
// Convert base-256 digits to base-58 digits (plus conversion to ASCII characters)
byte[] temp = Arrays.copyOf(input, input.length); // since we modify it in-place
char[] encoded = new char[temp.length * 2]; // upper bound
int outputStart = encoded.length;
for (int inputStart = zeros; inputStart < temp.length; ) {
encoded[--outputStart] = ALPHABET[divmod(temp, inputStart, 256, BASE_58)];
if (temp[inputStart] == 0) {
++inputStart; // optimization - skip leading zeros
}
}
// Preserve exactly as many leading encoded zeros in output as there were leading zeros in input.
while (outputStart < encoded.length && encoded[outputStart] == ALPHABET[0]) {
++outputStart;
}
while (--zeros >= 0) {
encoded[--outputStart] = ALPHABET[0];
}
// Return encoded string (including encoded leading zeros).
return new String(encoded, outputStart, encoded.length - outputStart);
}
public static byte[] decode(String input) {
if (input.length() == 0) {
return new byte[0];
}
// Convert the base58-encoded ASCII chars to a base58 byte sequence (base58 digits).
byte[] input58 = new byte[input.length()];
for (int i = 0; i < input.length(); ++i) {
char c = input.charAt(i);
int digit58 = -1;
if (c >= '1' && c <= '9') {
digit58 = c - '1';
} else if (c >= 'A' && c <= 'H') {
digit58 = c - 'A' + 9;
} else if (c >= 'J' && c <= 'N') {
digit58 = c - 'J' + 17;
} else if (c >= 'P' && c <= 'Z') {
digit58 = c - 'P' + 22;
} else if (c >= 'a' && c <= 'k') {
digit58 = c - 'a' + 33;
} else if (c >= 'm' && c <= 'z') {
digit58 = c - 'm' + 44;
} else if (c == 'l' || c == 'i') {
digit58 = 34;
} else if (c == 'o' || c == '0') {
digit58 = 0;
}
if (digit58 == -1) {
throw new IllegalArgumentException("Illegal character " + c + " at position " + i);
}
input58[i] = (byte) digit58;
}
// Count leading zeros.
int zeros = 0;
while (zeros < input58.length && input58[zeros] == 0) {
++zeros;
}
// Convert base-58 digits to base-256 digits.
byte[] temp = new byte[input.length()];
int outputStart = temp.length;
for (int inputStart = zeros; inputStart < input58.length; ) {
temp[--outputStart] = divmod(input58, inputStart, BASE_58, 256);
if (input58[inputStart] == 0) {
++inputStart; // optimization - skip leading zeros
}
}
// Ignore extra leading zeros that were added during the calculation.
while (outputStart < temp.length && temp[outputStart] == 0) {
++outputStart;
}
// Return decoded data (including original number of leading zeros).
return Arrays.copyOfRange(temp, outputStart - zeros, temp.length);
}
private static byte divmod(byte[] number, int firstDigit, int base, int divisor) {
// this is just long division which accounts for the base of the input digits
int remainder = 0;
for (int i = firstDigit; i < number.length; i++) {
int digit = (int) number[i] & 0xFF;
int temp = remainder * base + digit;
number[i] = (byte) (temp / divisor);
remainder = temp % divisor;
}
return (byte) remainder;
}
}
```
使用方法:
```java
String input = "Hello, world!";
byte[] data = input.getBytes();
String encoded = Base58.encode(data);
byte[] decoded = Base58.decode(encoded);
String output = new String(decoded);
System.out.println("Input: " + input);
System.out.println("Encoded: " + encoded);
System.out.println("Decoded: " + output);
```
输出结果如下:
```
Input: Hello, world!
Encoded: 2NEpo7TZRX1LZEdD3V7LzF5awNk6JZLTbbU
Decoded: Hello, world!
```
Base58编码在比特币等加密货币中有广泛应用。
阅读全文