The address format is well explained in the relevant TRON documentation.
In Java code (based on wallet-cli):
public String tronHex(String base58) {
byte[] decoded = decode58(base58);
String hexString = decoded == null ? "" : org.spongycastle.util.encoders.Hex.toHexString(decoded);
return hexString;
}
private byte[] decode58(String input) {
byte[] decodeCheck = Base58.decode(input);
if (decodeCheck.length <= 4) {
return null;
}
byte[] decodeData = new byte[decodeCheck.length - 4];
System.arraycopy(decodeCheck, 0, decodeData, 0, decodeData.length);
byte[] hash0 = Sha256Hash.hash(decodeData);
byte[] hash1 = Sha256Hash.hash(hash0);
if (hash1[0] == decodeCheck[decodeData.length] &&
hash1[1] == decodeCheck[decodeData.length + 1] &&
hash1[2] == decodeCheck[decodeData.length + 2] &&
hash1[3] == decodeCheck[decodeData.length + 3]) {
return decodeData;
}
return null;
}
And the other way around:
public String hexStringTobBase58(String hexString) {
hexString = adjustHex(hexString);
byte[] decodedHex = hexString == null? new byte[0] : org.spongycastle.util.encoders.Hex.decode(hexString);
String base58 = encode58(decodedHex);
return base58;
}
private String adjustHex(String hexString) {
if (hexString.startsWith("0x")) {
hexString = "41" + hexString.substring(2);
}
if (hexString.length() % 2 == 1) {
hexString = "0" + hexString;
}
return hexString;
}
private String encode58(byte[] input) {
byte[] hash0 = Sha256Hash.hash(input);
byte[] hash1 = Sha256Hash.hash(hash0);
byte[] inputCheck = new byte[input.length + 4];
System.arraycopy(input, 0, inputCheck, 0, input.length);
System.arraycopy(hash1, 0, inputCheck, input.length, 4);
return Base58.encode(inputCheck);
}
Find class Base58
here, class Sha256Hash
here and the required dependency to Spongy Castle here.