I am trying to decode an APK file. I need to get what m21862a function returns.
Simply I need HASH value. Hash is requested to https://api.SOMESITE.net/external/auth. How it is generated?
Here is my part code:
a = HttpTools.m22199a("https://api.somesite.net/external/hello", false);
String str = BuildConfig.FLAVOR;
str = BuildConfig.FLAVOR;
str = BuildConfig.FLAVOR;
try {
str = ((String) new JSONObject(a).get("token")) + ZaycevApp.f15130a.m21564W();
Logger.m22256a("ZAuth", "token - " + str);
str = m21862a(str);
a = new JSONObject(HttpTools.m22199a(String.format("https://api.SOMESITE.net/external/auth?code=%s&hash=%s", new Object[]{a, str}), false)).getString("token");
if (!ae.m21746b((CharSequence) a)) {
ZaycevApp.f15130a.m21595f(a);
}
}
I need to know what is m21862a function. Is there PHP replacement for m21862a? Here is m21862a function:
private String m21862a(String str) {
try {
MessageDigest instance = MessageDigest.getInstance("MD5");
instance.update(str.getBytes());
byte[] digest = instance.digest();
StringBuffer stringBuffer = new StringBuffer();
for (byte b : digest) {
String toHexString = Integer.toHexString(b & RadialCountdown.PROGRESS_ALPHA);
while (toHexString.length() < 2) {
toHexString = "0" + toHexString;
}
stringBuffer.append(toHexString);
}
return stringBuffer.toString();
} catch (Exception e) {
Logger.m22252a((Object) this, e);
return BuildConfig.FLAVOR;
}
}
The function computes the MD5 digest of the input, takes each byte of the computed MD5, "ANDize" with RadialCountdown.PROGRESS_ALPHA, translates to hex (pad with 0 to have 2 char) and appends that to the ouput.
There is probably a way to do the same thing in php (using md5()?).
I need to convert byte[] to char[] in Java.
The Unicode encoding used is UTF-16.
To be concise, I need a Java equivalent of c#'s
UnicodeEncoding.Unicode.GetChars(byte[] bytes);
Also, I need to convert only a part of byte[] to char[]
public virtual char[] GetChars(byte[] bytes, int index, int count);
You can try this:
byte[] b = ...
char[] c = new String(b, "UTF-16").toCharArray();
From String(byte[] bytes, String charsetName):
Constructs a new String by decoding the specified array of bytes using the specified charset.
C# API:
public virtual char[] GetChars(byte[] bytes);
Java:
byte[] byte = ...
char[] char = new String(byte, "UTF-16").toCharArray();
Java methods to return char[] :
public static char[] getCharsFromBytes(byte[] bytes, String type) {
try {
String byteConvert = new String(bytes, "UTF-16");
return byteConvert.toCharArray();
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(DataTypeUtil.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
C# API:
public virtual char[] GetChars(byte[] bytes, int index, int count);
Java:
Iterate through required bytes in the byte array
public static char[] getCharsFromBytes(byte[] bytes, int index, int count) {
char[] charArr = getCharsFromBytes(bytes);
char[] result = new char[count];
for (int i = 0; i < count; i++) {
result[i] = charArr[i + startIndex];
}
return result;
}
public static char[] GetChars(byte[] bytes, int index, int count) {
try {
return new String(java.util.Arrays.copyOfRange(bytes,index,index+count), "UTF-16").toCharArray();
} catch (java.io.UnsupportedEncodingException e) {
assert false: "Your JRE is broken (UTF-16 not supported)";
return null;
}
}
I'm trying in Java to decode URL containing % encoded characters
I've tried using java.net.URI class to do the job, but it's not always working correctly.
String test = "https://fr.wikipedia.org/wiki/Fondation_Alliance_fran%C3%A7aise";
URI uri = new URI(test);
System.out.println(uri.getPath());
For the test String "https://fr.wikipedia.org/wiki/Fondation_Alliance_fran%C3%A7aise", the result is correct "/wiki/Fondation_Alliance_française" (%C3%A7 is correctly replaced by ç).
But for some other test strings, like "http://sv.wikipedia.org/wiki/Anv%E4ndare:Lsjbot/Statistik#Drosophilidae", it gives an incorrect result "/wiki/Anv�ndare:Lsjbot/Statistik" (%E4 is replaced by � instead of ä).
I did some testing with getRawPath() and URLDecoder class.
System.out.println(URLDecoder.decode(uri.getRawPath(), "UTF8"));
System.out.println(URLDecoder.decode(uri.getRawPath(), "ISO-8859-1"));
System.out.println(URLDecoder.decode(uri.getRawPath(), "WINDOWS-1252"));
Depending on the test String, I get correct results with different encodings:
For %C3%A7, I get a correct result with "UTF-8" encoding as expected, and incorrect results with "ISO-8859-1" or "WINDOWS-1252" encoding
For %E4, it's the opposite.
For both test URL, I get the correct page if I put them in Chrome address bar.
How can I correctly decode the URL in all situations ?
Thanks for any help
==== Answer ====
Thanks to the suggestions in McDowell answer below, it now seems to work. Here's what I now have as code:
private static void appendBytes(ByteArrayOutputStream buf, String data) throws UnsupportedEncodingException {
byte[] b = data.getBytes("UTF8");
buf.write(b, 0, b.length);
}
private static byte[] parseEncodedString(String segment) throws UnsupportedEncodingException {
ByteArrayOutputStream buf = new ByteArrayOutputStream(segment.length());
int last = 0;
int index = 0;
while (index < segment.length()) {
if (segment.charAt(index) == '%') {
appendBytes(buf, segment.substring(last, index));
if ((index < segment.length() + 2) &&
("ABCDEFabcdef0123456789".indexOf(segment.charAt(index + 1)) >= 0) &&
("ABCDEFabcdef0123456789".indexOf(segment.charAt(index + 2)) >= 0)) {
buf.write((byte) Integer.parseInt(segment.substring(index + 1, index + 3), 16));
index += 3;
} else if ((index < segment.length() + 1) &&
(segment.charAt(index + 1) == '%')) {
buf.write((byte) '%');
index += 2;
} else {
buf.write((byte) '%');
index++;
}
last = index;
} else {
index++;
}
}
appendBytes(buf, segment.substring(last));
return buf.toByteArray();
}
private static String parseEncodedString(String segment, Charset... encodings) {
if ((segment == null) || (segment.indexOf('%') < 0)) {
return segment;
}
try {
byte[] data = parseEncodedString(segment);
for (Charset encoding : encodings) {
try {
if (encoding != null) {
return encoding.newDecoder().
onMalformedInput(CodingErrorAction.REPORT).
decode(ByteBuffer.wrap(data)).toString();
}
} catch (CharacterCodingException e) {
// Incorrect encoding, try next one
}
}
} catch (UnsupportedEncodingException e) {
// Nothing to do
}
return segment;
}
Anv%E4ndare
As PopoFibo says this is not a valid UTF-8 encoded sequence.
You can do some tolerant best-guess decoding:
public static String parse(String segment, Charset... encodings) {
byte[] data = parse(segment);
for (Charset encoding : encodings) {
try {
return encoding.newDecoder()
.onMalformedInput(CodingErrorAction.REPORT)
.decode(ByteBuffer.wrap(data))
.toString();
} catch (CharacterCodingException notThisCharset_ignore) {}
}
return segment;
}
private static byte[] parse(String segment) {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
Matcher matcher = Pattern.compile("%([A-Fa-f0-9][A-Fa-f0-9])")
.matcher(segment);
int last = 0;
while (matcher.find()) {
appendAscii(buf, segment.substring(last, matcher.start()));
byte hex = (byte) Integer.parseInt(matcher.group(1), 16);
buf.write(hex);
last = matcher.end();
}
appendAscii(buf, segment.substring(last));
return buf.toByteArray();
}
private static void appendAscii(ByteArrayOutputStream buf, String data) {
byte[] b = data.getBytes(StandardCharsets.US_ASCII);
buf.write(b, 0, b.length);
}
This code will successfully decode the given strings:
for (String test : Arrays.asList("Fondation_Alliance_fran%C3%A7aise",
"Anv%E4ndare")) {
String result = parse(test, StandardCharsets.UTF_8,
StandardCharsets.ISO_8859_1);
System.out.println(result);
}
Note that this isn't some foolproof system that allows you to ignore correct URL encoding. It works here because v%E4n - the byte sequence 76 E4 6E - is not a valid sequence as per the UTF-8 scheme and the decoder can detect this.
If you reverse the order of the encodings the first string can happily (but incorrectly) be decoded as ISO-8859-1.
Note: HTTP doesn't care about percent-encoding and you can write a web server that accepts http://foo/%%%%% as a valid form. The URI spec mandates UTF-8 but this was done retroactively. It is really up to the server to describe what form its URIs should be and if you have to handle arbitrary URIs you need to be aware of this legacy.
I've written a bit more about URLs and Java here.
I'm trying to make an simple encryption program that converts a string into the ASCII value equivalent and then decrypts it into the string again or char.
import java.io.*;
import javax.swing.*;
public class SimpleEncryption {
public static void main (String [] args) throws Exception
{
BufferedReader inKb = new BufferedReader (new InputStreamReader (System.in));
for(int i=0; i<10; i++)
{
String ans = JOptionPane.showInputDialog ("Hello User, would you like to encrypt or decrypt?");
ans = ans.toUpperCase();
int a = 0;
if (ans.contains("EN")||ans.contains("ENCRYPT"))
{
String pass = "";
pass = JOptionPane.showInputDialog ("Please type your phrase into input:");
for (int j=0; j<pass.length(); j++)
{
char c = pass.charAt(j);
a = (int) c;
System.out.print(a);
}
break;
}
if (ans.contains("DE")||ans.contains("DECRYPT"))
{
String pass = "";
pass = JOptionPane.showInputDialog ("Please type the encrypted code into input:");
for (int k=0; k<pass.length(); k++)
{
char c = pass.charAt(k);
a = (int)(c);
i = (char) a;
System.out.print(a);
}
break;
}
System.out.println("Sorry I don't understand, please retry.");
}
}
}
If what you're trying to have is in fact an encoding (before encryption ?) in ASCII of any java String (UTF-16 based), you might encode it in base64 : this encoding scheme was created just for that.
It's really easy to do this encoding/decoding in java (as in other languages).
What you seem to want is to get the byte array representing some kind of character encoding (not encryption) of the input string. Then you seem to want to show the octal value of the encoded characters. If you just need US ASCII then you would get all (printable) characters up to 177 octal. If you want special characters you need to choose a more specific character set (IBM OEM or Western-Latin are common ones). UTF-8 could also be used, but it may encode a single character into multiple bytes.
public static String toOctalString(final byte[] encoding) {
final StringBuilder sb = new StringBuilder(encoding.length * 4);
for (int i = 0; i < encoding.length; i++) {
if (i != 0) {
sb.append("|");
}
sb.append(Integer.toOctalString(encoding[i] & 0xFF));
}
return sb.toString();
}
public static byte[] fromOctalString(final String octalString) {
final ByteArrayOutputStream baos = new ByteArrayOutputStream(octalString.length() / 4 + 1);
final Matcher m = Pattern.compile("[0-7]{1,3}").matcher(octalString);
while (m.find()) {
baos.write(Integer.parseInt(m.group(), 8));
}
return baos.toByteArray();
}
public static void main(String[] args) {
final String userInput = "owlstæd";
// use the common Latin-1 encoding, standardized in ISO 8859 as character set 1
// you can replace with ASCII, but the ASCII characters will encode fine for both
final byte[] userInputEncoded = userInput.getBytes(Charset.forName("ISO8859-1"));
final String octalString = toOctalString(userInputEncoded);
System.out.println(octalString);
final byte[] userInputEncoded2 = fromOctalString(octalString);
final String userInput2 = new String(userInputEncoded2, Charset.forName("ISO8859-1"));
System.out.println(userInput2);
}
I am trying to convert a string like "testing123" into hexadecimal form in java. I am currently using BlueJ.
And to convert it back, is it the same thing except backward?
Here's a short way to convert it to hex:
public String toHex(String arg) {
return String.format("%040x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
}
To ensure that the hex is always 40 characters long, the BigInteger has to be positive:
public String toHex(String arg) {
return String.format("%x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
}
import org.apache.commons.codec.binary.Hex;
...
String hexString = Hex.encodeHexString(myString.getBytes(/* charset */));
http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Hex.html
Use DatatypeConverter.printHexBinary():
public static String toHexadecimal(String text) throws UnsupportedEncodingException
{
byte[] myBytes = text.getBytes("UTF-8");
return DatatypeConverter.printHexBinary(myBytes);
}
Example usage:
System.out.println(toHexadecimal("Hello StackOverflow"));
Prints:
48656C6C6F20537461636B4F766572666C6F77
Note: This causes a little extra trouble with Java 9 and newer since the API is not included by default. For reference e.g. see this GitHub issue.
The numbers that you encode into hexadecimal must represent some encoding of the characters, such as UTF-8. So first convert the String to a byte[] representing the string in that encoding, then convert each byte to hexadecimal.
public static String hexadecimal(String input, String charsetName) throws UnsupportedEncodingException {
if (input == null) throw new NullPointerException();
return asHex(input.getBytes(charsetName));
}
private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
public static String asHex(byte[] buf)
{
char[] chars = new char[2 * buf.length];
for (int i = 0; i < buf.length; ++i)
{
chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
}
return new String(chars);
}
Here an other solution
public static String toHexString(byte[] ba) {
StringBuilder str = new StringBuilder();
for(int i = 0; i < ba.length; i++)
str.append(String.format("%x", ba[i]));
return str.toString();
}
public static String fromHexString(String hex) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < hex.length(); i+=2) {
str.append((char) Integer.parseInt(hex.substring(i, i + 2), 16));
}
return str.toString();
}
All answers based on String.getBytes() involve encoding your string according to a Charset. You don't necessarily get the hex value of the 2-byte characters that make up your string. If what you actually want is the equivalent of a hex viewer, then you need to access the chars directly. Here's the function that I use in my code for debugging Unicode issues:
static String stringToHex(String string) {
StringBuilder buf = new StringBuilder(200);
for (char ch: string.toCharArray()) {
if (buf.length() > 0)
buf.append(' ');
buf.append(String.format("%04x", (int) ch));
}
return buf.toString();
}
Then, stringToHex("testing123") will give you:
0074 0065 0073 0074 0069 006e 0067 0031 0032 0033
byte[] bytes = string.getBytes(CHARSET); // you didn't say what charset you wanted
BigInteger bigInt = new BigInteger(bytes);
String hexString = bigInt.toString(16); // 16 is the radix
You could return hexString at this point, with the caveat that leading null-chars will be stripped, and the result will have an odd length if the first byte is less than 16. If you need to handle those cases, you can add some extra code to pad with 0s:
StringBuilder sb = new StringBuilder();
while ((sb.length() + hexString.length()) < (2 * bytes.length)) {
sb.append("0");
}
sb.append(hexString);
return sb.toString();
To get the Integer value of hex
//hex like: 0xfff7931e to int
int hexInt = Long.decode(hexString).intValue();
I would suggest something like this, where str is your input string:
StringBuffer hex = new StringBuffer();
char[] raw = tokens[0].toCharArray();
for (int i=0;i<raw.length;i++) {
if (raw[i]<=0x000F) { hex.append("000"); }
else if(raw[i]<=0x00FF) { hex.append("00" ); }
else if(raw[i]<=0x0FFF) { hex.append("0" ); }
hex.append(Integer.toHexString(raw[i]).toUpperCase());
}
Java 17 introduces a utility class for hexadecimal formatting: java.util.HexFormat
Convert to hex:
public String toHex(String value) {
return HexFormat.of().formatHex(value.getBytes());
}
Convert from hex:
public String fromHex(String value) {
return new String(HexFormat.of().parseHex(value));
}
More about HexFormat here
Documentation: here
Convert a letter in hex code and hex code in letter.
String letter = "a";
String code;
int decimal;
code = Integer.toHexString(letter.charAt(0));
decimal = Integer.parseInt(code, 16);
System.out.println("Hex code to " + letter + " = " + code);
System.out.println("Char to " + code + " = " + (char) decimal);
To go the other way (hex to string), you can use
public String hexToString(String hex) {
return new String(new BigInteger(hex, 16).toByteArray());
}
One line HEX encoding/decoding without external libs (Java 8 and above):
Encoding :
String hexString = inputString.chars().mapToObj(c ->
Integer.toHexString(c)).collect(Collectors.joining());
Decoding :
String decodedString = Stream.iterate(0, i -> i+2)
.limit(hexString.length()/2 + Math.min(hexString.length()%2,1))
.map(i -> "" + (char)Integer.parseInt("" + hexString.charAt(i) + hexString.charAt(i+1),16))
.collect(Collectors.joining());
First convert it into bytes using getBytes() function and then convert it into hex usign this :
private static String hex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i=0; i<bytes.length; i++) {
sb.append(String.format("%02X ",bytes[i]));
}
return sb.toString();
}
Using Multiple Peoples help from multiple Threads..
I know this has been answered, but i would like to give a full encode & decode method for any others in my same situation..
Here's my Encoding & Decoding methods..
// Global Charset Encoding
public static Charset encodingType = StandardCharsets.UTF_8;
// Text To Hex
public static String textToHex(String text)
{
byte[] buf = null;
buf = text.getBytes(encodingType);
char[] HEX_CHARS = "0123456789abcdef".toCharArray();
char[] chars = new char[2 * buf.length];
for (int i = 0; i < buf.length; ++i)
{
chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
}
return new String(chars);
}
// Hex To Text
public static String hexToText(String hex)
{
int l = hex.length();
byte[] data = new byte[l / 2];
for (int i = 0; i < l; i += 2)
{
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i + 1), 16));
}
String st = new String(data, encodingType);
return st;
}
Much better:
public static String fromHexString(String hex, String sourceEncoding ) throws IOException{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] buffer = new byte[512];
int _start=0;
for (int i = 0; i < hex.length(); i+=2) {
buffer[_start++] = (byte)Integer.parseInt(hex.substring(i, i + 2), 16);
if (_start >=buffer.length || i+2>=hex.length()) {
bout.write(buffer);
Arrays.fill(buffer, 0, buffer.length, (byte)0);
_start = 0;
}
}
return new String(bout.toByteArray(), sourceEncoding);
}
import java.io.*;
import java.util.*;
public class Exer5{
public String ConvertToHexadecimal(int num){
int r;
String bin="\0";
do{
r=num%16;
num=num/16;
if(r==10)
bin="A"+bin;
else if(r==11)
bin="B"+bin;
else if(r==12)
bin="C"+bin;
else if(r==13)
bin="D"+bin;
else if(r==14)
bin="E"+bin;
else if(r==15)
bin="F"+bin;
else
bin=r+bin;
}while(num!=0);
return bin;
}
public int ConvertFromHexadecimalToDecimal(String num){
int a;
int ctr=0;
double prod=0;
for(int i=num.length(); i>0; i--){
if(num.charAt(i-1)=='a'||num.charAt(i-1)=='A')
a=10;
else if(num.charAt(i-1)=='b'||num.charAt(i-1)=='B')
a=11;
else if(num.charAt(i-1)=='c'||num.charAt(i-1)=='C')
a=12;
else if(num.charAt(i-1)=='d'||num.charAt(i-1)=='D')
a=13;
else if(num.charAt(i-1)=='e'||num.charAt(i-1)=='E')
a=14;
else if(num.charAt(i-1)=='f'||num.charAt(i-1)=='F')
a=15;
else
a=Character.getNumericValue(num.charAt(i-1));
prod=prod+(a*Math.pow(16, ctr));
ctr++;
}
return (int)prod;
}
public static void main(String[] args){
Exer5 dh=new Exer5();
Scanner s=new Scanner(System.in);
int num;
String numS;
int choice;
System.out.println("Enter your desired choice:");
System.out.println("1 - DECIMAL TO HEXADECIMAL ");
System.out.println("2 - HEXADECIMAL TO DECIMAL ");
System.out.println("0 - EXIT ");
do{
System.out.print("\nEnter Choice: ");
choice=s.nextInt();
if(choice==1){
System.out.println("Enter decimal number: ");
num=s.nextInt();
System.out.println(dh.ConvertToHexadecimal(num));
}
else if(choice==2){
System.out.println("Enter hexadecimal number: ");
numS=s.next();
System.out.println(dh.ConvertFromHexadecimalToDecimal(numS));
}
}while(choice!=0);
}
}
new BigInteger(1, myString.getBytes(/*YOUR_CHARSET?*/)).toString(16)
Here are some benchmarks comparing different approaches and libraries. Guava beats Apache Commons Codec at decoding. Commons Codec beats Guava at encoding. And JHex beats them both for decoding and encoding.
JHex example
String hexString = "596f752772652077656c636f6d652e";
byte[] decoded = JHex.decodeChecked(hexString);
System.out.println(new String(decoded));
String reEncoded = JHex.encode(decoded);
Everything is in a single class file for JHex. Feel free to copy paste if you don't want yet another library in your dependency tree. Also note, it is only available as Java 9 jar until I can figure out how to publish multiple release targets with Gradle and the Bintray plugin.
Convert String to Hexadecimal:
public String hexToString(String hex) {
return Integer.toHexString(Integer.parseInt(hex));
}
definitely this is the easy way.
check this solution for String to hex and hex to String vise-versa
public class TestHexConversion {
public static void main(String[] args) {
try{
String clearText = "testString For;0181;with.love";
System.out.println("Clear Text = " + clearText);
char[] chars = clearText.toCharArray();
StringBuffer hex = new StringBuffer();
for (int i = 0; i < chars.length; i++) {
hex.append(Integer.toHexString((int) chars[i]));
}
String hexText = hex.toString();
System.out.println("Hex Text = " + hexText);
String decodedText = HexToString(hexText);
System.out.println("Decoded Text = "+decodedText);
} catch (Exception e){
e.printStackTrace();
}
}
public static String HexToString(String hex){
StringBuilder finalString = new StringBuilder();
StringBuilder tempString = new StringBuilder();
for( int i=0; i<hex.length()-1; i+=2 ){
String output = hex.substring(i, (i + 2));
int decimal = Integer.parseInt(output, 16);
finalString.append((char)decimal);
tempString.append(decimal);
}
return finalString.toString();
}
Output as follows :
Clear Text = testString For;0181;with.love
Hex Text = 74657374537472696e6720466f723b303138313b776974682e6c6f7665
Decoded Text = testString For;0181;with.love
A short and convenient way to convert a String to its Hexadecimal notation is:
public static void main(String... args){
String str = "Hello! This is test string.";
char ch[] = str.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ch.length; i++) {
sb.append(Integer.toHexString((int) ch[i]));
}
System.out.println(sb.toString());
}