-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove dependency on JDK 17 HexFormat
Add ByteArray, ByteUtils, and HexFormat classes to do it.
- Loading branch information
1 parent
b868fc3
commit 7294fe7
Showing
9 changed files
with
180 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
secp-api/src/main/java/org/bitcoinj/secp/api/ByteArray.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* Copyright 2023-2024 secp256k1-jdk Developers. | ||
* | ||
* 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 org.bitcoinj.secp.api; | ||
|
||
import org.bitcoinj.secp.api.internal.ByteUtils; | ||
import org.bitcoinj.secp.api.internal.HexFormat; | ||
|
||
import java.util.Arrays; | ||
|
||
/** | ||
* An effectively-immutable byte array. | ||
*/ | ||
public interface ByteArray extends Comparable<ByteArray> { | ||
HexFormat HEX_FORMAT = new HexFormat(); | ||
|
||
/** | ||
* @return the bytes as an array | ||
*/ | ||
byte[] bytes(); | ||
|
||
/** | ||
* @return the bytes as a hex-formatted string | ||
*/ | ||
default String formatHex() { | ||
return HEX_FORMAT.formatHex(bytes()); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
* <p>For {@link ByteArray} this is a byte-by-byte, unsigned comparison. | ||
* @param o {@inheritDoc} | ||
* @return {@inheritDoc} | ||
*/ | ||
@Override | ||
default int compareTo(ByteArray o) { | ||
return ByteUtils.arrayUnsignedComparator().compare(bytes(), o.bytes()); | ||
} | ||
|
||
/** | ||
* Utility method to format hex bytes as string | ||
* @param bytes bytes to format | ||
* @return hex-formatted String | ||
*/ | ||
static String toHexString(byte[] bytes) { | ||
return HEX_FORMAT.formatHex(bytes); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
secp-api/src/main/java/org/bitcoinj/secp/api/internal/ByteUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* Copyright 2023-2024 secp256k1-jdk Developers. | ||
* | ||
* 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 org.bitcoinj.secp.api.internal; | ||
|
||
import java.util.Comparator; | ||
|
||
/** | ||
* | ||
*/ | ||
public class ByteUtils { | ||
/** | ||
* Provides a byte array comparator. | ||
* @return A comparator for byte[] | ||
*/ | ||
public static Comparator<byte[]> arrayUnsignedComparator() { | ||
return ARRAY_UNSIGNED_COMPARATOR; | ||
} | ||
|
||
// In Java 9, this can be replaced with Arrays.compareUnsigned() | ||
private static final Comparator<byte[]> ARRAY_UNSIGNED_COMPARATOR = (a, b) -> { | ||
int minLength = Math.min(a.length, b.length); | ||
for (int i = 0; i < minLength; i++) { | ||
int result = compareUnsigned(a[i], b[i]); | ||
if (result != 0) { | ||
return result; | ||
} | ||
} | ||
return a.length - b.length; | ||
}; | ||
|
||
private static int compareUnsigned(byte a, byte b) { | ||
return Byte.toUnsignedInt(a) - Byte.toUnsignedInt(b); | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
secp-api/src/main/java/org/bitcoinj/secp/api/internal/HexFormat.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright 2023-2024 secp256k1-jdk Developers. | ||
* | ||
* 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 org.bitcoinj.secp.api.internal; | ||
|
||
/** | ||
* This class implements a subset of the functionality of the {@code HexFormat} class available in Java 17 and later. | ||
* Its behavior is the same as an instance of Java 17 {@code HexFormat} created with {@code HexFormat.of()}. | ||
* It is an internal class and may be removed in the future when and if we have a Java 17 baseline. This is a copy of | ||
* HexFormat.java in `bitcoinj-base/org.bitcoinj.base.internal`. | ||
* <p>Thanks to this <a href="https://www.baeldung.com/java-byte-arrays-hex-strings">Baeldung article</a>. | ||
*/ | ||
public class HexFormat { | ||
public String formatHex(byte[] bytes) { | ||
StringBuilder stringBuilder = new StringBuilder(bytes.length * 2); | ||
for (byte aByte : bytes) { | ||
stringBuilder.append(byteToHex(aByte)); | ||
} | ||
return stringBuilder.toString(); | ||
} | ||
|
||
public byte[] parseHex(String hexString) { | ||
if (hexString.length() % 2 == 1) { | ||
throw new IllegalArgumentException("Invalid hexadecimal String supplied."); | ||
} | ||
|
||
byte[] bytes = new byte[hexString.length() / 2]; | ||
for (int i = 0; i < hexString.length(); i += 2) { | ||
bytes[i / 2] = hexToByte(hexString.substring(i, i + 2)); | ||
} | ||
return bytes; | ||
} | ||
private String byteToHex(byte num) { | ||
char[] hexDigits = new char[2]; | ||
hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16); | ||
hexDigits[1] = Character.forDigit((num & 0xF), 16); | ||
return new String(hexDigits); | ||
} | ||
|
||
private byte hexToByte(String hexString) { | ||
int firstDigit = toDigit(hexString.charAt(0)); | ||
int secondDigit = toDigit(hexString.charAt(1)); | ||
return (byte) ((firstDigit << 4) + secondDigit); | ||
} | ||
|
||
private int toDigit(char hexChar) { | ||
int digit = Character.digit(hexChar, 16); | ||
if (digit == -1) { | ||
throw new IllegalArgumentException("Invalid Hexadecimal Character: "+ hexChar); | ||
} | ||
return digit; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters