My question is, I guess, quite simple :
How to convert a Byte to alpha-numeric char array (String) in java ?
I tried this but it gives me back an error on netbeans :
byte[] b = "test".getBytes("ASCII");
String test = new String(b,"ASCII");
UPDATE :
I am actually using this code :
byte[] b = "test".getBytes("ASCII");
MessageDigest md = MessageDigest.getInstance("SHA-256");
String bla = new String(md.digest(b), "ASCII");
But once I try to use for other stuff which requires String with ASCII, I receive the following errors like "This is not ASCII".
I don't really understand, actually.
When I try to print it I got something weird like "2Q�h/�k�����"
Thank you in advance for your help.
You're close :
public static void main(String[] args) throws java.io.UnsupportedEncodingException { //you should throw or catch this exception
byte[] b = "test".getBytes("ASCII"); // And you must declare a byte array
String test = new String(b,"ASCII");
System.out.println(test); // Will output "test"
}
After your edits I think you want to generate a SHA-256 hash of a given String.
try {
byte[] b = "test".getBytes("ASCII");
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = md.digest(b);
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < hashBytes.length; i++) {
hexString.append(Integer.toHexString(0xFF & hashBytes[i]));
}
System.out.println(hexString);
} catch (Exception e) {
e.printStackTrace();
}
Related
This question already has answers here:
How to convert Java String into byte[]?
(9 answers)
Closed 4 years ago.
I have the following code to zip and unzip the String:
public static void main(String[] args) {
// TODO code application logic here
String Source = "hello world";
byte[] a = ZIP(Source);
System.out.format("answer:");
System.out.format(a.toString());
System.out.format("\n");
byte[] Source2 = a.toString().getBytes();
System.out.println("\nsource 2:" + Source2.toString() + "\n");
String b = unZIP(Source2);
System.out.println("\nunzip answer:");
System.out.format(b);
System.out.format("\n");
}
public static byte[] ZIP(String source) {
ByteArrayOutputStream bos= new ByteArrayOutputStream(source.length()* 4);
try {
GZIPOutputStream outZip= new GZIPOutputStream(bos);
outZip.write(source.getBytes());
outZip.flush();
outZip.close();
} catch (Exception Ex) {
}
return bos.toByteArray();
}
public static String unZIP(byte[] Source) {
ByteArrayInputStream bins= new ByteArrayInputStream(Source);
byte[] buf= new byte[2048];
StringBuffer rString= new StringBuffer("");
int len;
try {
GZIPInputStream zipit= new GZIPInputStream(bins);
while ((len = zipit.read(buf)) > 0) {
rString.append(new String(buf).substring(0, len));
}
return rString.toString();
} catch (Exception Ex) {
return "";
}
}
When "Hello World" have been zipped, it's will become [B#7bdecdec in byte[] and convert into String and display on the screen. However, if I'm trying to convert the string back into byte[] with the following code:
byte[] Source2 = a.toString().getBytes();
the value of variable a will become to [B#60a1807c instead of [B#7bdecdec . Does anyone know how can I convert the String (a value of byte but been convert into String) back in byte[] in JAVA?
Why doing byte[] Source2 = a.toString().getBytes(); ?
It seems like a double conversion; you convert a byte[] to string the to byte[].
The real conversion of a byte[] to string is new String(byte[]) hoping that you're in the same charset.
Source2 should be an exact copy of a hence you should just do byte[] Source2 = a;
Your unzip is wrong because you are converting back a string which might be in some other encoding (let's say UTF-8):
public static String unZIP(byte[] source) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream(source.length*2);
try (ByteArrayInputStream in = new ByteArrayInputStream(source);
GZIPInputStream zis = new GZIPInputStream(in)) {
byte[] buffer = new buffer[4096];
for (int n = 0; (n = zis.read(buffer) != 0; ) {
bos.write(buffer, 0, n);
}
}
return new String(bos.toByteArray(), StandardCharsets.UTF_8);
}
This one, not tested, will:
Store byte from the gzip stream into a ByteArrayOutputStream
Close the gzip/ByteArrayInputStream using try with resources
Convert the whole into a String using UTF-8 (you should always use encoding and unless rare case, UTF-8 is the way to go).
You must not use StringBuffer for two reasons:
The most important one: this will not behave well with multi bytes string such as UTF-8 or UTF-16.
And second, StringBuffer is synchronized: you should use StringBuilder whenever possible and whenever it should be used (eg: not here!). StringBuffer should be reserved for case where your share the StringBuffer with several threads, otherwise it is useless.
With those change, you will also need to change the ZIP as per David Conrad comment and because the unZIP use UTF-8:
public static byte[] ZIP(String source) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream(source.length()* 4);
try (GZIPOutputStream zip = new GZIPOutputStream(bos)) {
zip.write(source.getBytes(StandardCharsets.UTF_8));
}
return bos.toByteArray();
}
As for the main, printing a byte[] will result in the default toString.
I'm coding in Android Studio and I'm trying to create base64 encoded and sha512 hashed String.
The functions are:
private String getBase64(String data){
try{
byte[] enc = data.getBytes("UTF-8");
return Base64.encodeToString(enc, Base64.DEFAULT);
}catch (Exception e){
e.printStackTrace();
return null;
}
}
private String getSHA(String data){
try {
MessageDigest mda = MessageDigest.getInstance("SHA-512");
byte[] digesta = mda.digest(data.getBytes("UTF-8"));
return convertByteToHex(digesta);
}catch(Exception e){
e.printStackTrace();
return null;
}
}
public String convertByteToHex(byte data[]) {
StringBuilder hexData = new StringBuilder();
for (byte aData : data)
hexData.append(String.format("%02x", aData));
return hexData.toString();
}
Then calling them:
// line below prints VGVzdDox as it should
Log.d("GO", "Working Base64: " + getBase64("Test:1"));
// line below prints: 3553AF9EDC389314B0F7354B51FEA7EB089C039EA77A0FD7BD61798A8DD14B1292B353B9E00789B2698B072AF5B05417DDDAA1870ADF9E1DE9C1F96D9465DF56
// as it should
Log.d("GO", "Working SHA: " + getSHA("VGVzdDox"));
String b = getBase64("Test:1");
// line below prints VGVzdDox again, as it should
Log.d("Base64", b);
String s = getSHA(b);
// Now this line prints a7d1bdc5d6497d787b35ce52774365150a2e21084958ffc14570367f3764b938fc1191d06006f1908084518c9697cbff3f2830a1ac003ef8ace36a0667dce92d
// Not sure why?
Log.d("SHA", s);
So that last output is wrong. However the getBase64 is right and the getSHA also when hard coding the base64 encoded String. And I have no idea why.
This is just the main activity, no other code is executed.
it seems like your String
b
have a new line at the end, i tested it with an online sha 512 generator with the String:
"VGVzdDox" and
"VGVzdDox
"
output of the first one is:
3553AF9EDC389314B0F7354B51FEA7EB089C039EA77A0FD7BD61798A8DD14B1292B353B9E00789B2698B072AF5B05417DDDAA1870ADF9E1DE9C1F96D9465DF56
the out put for the second is:
A7D1BDC5D6497D787B35CE52774365150A2E21084958FFC14570367F3764B938FC1191D06006F1908084518C9697CBFF3F2830A1AC003EF8ACE36A0667DCE92D
so get rid of the line seperator maybe with the method Stirng.trim(), but i didn't tested it
Found it, had to change:
return Base64.encodeToString(enc, Base64.DEFAULT);
to
return Base64.encodeToString(enc, Base64.NO_WRAP);
I have a text file which contains the "Captured Network Packets' Headers" as hexadecimal values like this...
FC-C8-97-62-88-5F-74-DE-2B-C8-C7-E5-08-00-45-00-00-28-4E-C4-40-00-80-06-BD-65-C0-A8-01-03-AD-C2-7F-38-C9-96-01-BB-F8-01-7F-5F-B6-8A-15-22-50-10-40-42-72-8C-00-00.
I need to convert them to decimal values... I did little as here..
InputStream input = new FileInputStream("data.txt");
OutputStream output = new FileOutputStream ("converteddata.txt");
int data = input.read();
while (data != -1)
{
char ch = (char) data;
output.write(ch);
data=input.read();
}
input.close();
output.close();
Now, my problem is... how to get each hexadecimal string which would have '2' characters..? (such as "AD" or 5F etc. in order to convert them in to decimal values).
I know that C++ has a function "fgetc()" No..? I need similar solution. Anybody can suggest a good way..? (Sorry, I'm a beginner for Java but know c++ much better)
Thanks in advance.
Try Long.parseLong("<hex string>", 16); to convert a hexadecimal string to a long value.
Try this:
String strHex = "FC-C8-97-62-88-5F-74-DE-2B-C8-C7-E5-08-00-45-00-00-28-4E-C4-40-00-80-06-BD-65-C0-A8-01-03-AD-C2-7F-38-C9-96-01-BB-F8-01-7F-5F-B6-8A-15-22-50-10-40-42-72-8C-00-00";
String[] hexParts = strHex.split("-");
for (String myStr : hexParts) {
// System.out.println(toHex(myStr));
System.out.println(toDecimal(myStr));
}
// getting For Decimal values from Hex string
public int toDecimal(String str){
return Integer.parseInt(str.trim(), 16 );
}
// getting For Hex values
public String toHex(String arg) {
return String.format("%x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
}
Here is a sample code. Please optimize for real time uses.
public static void main(String[] args) throws IOException {
OutputStream output = new FileOutputStream ("converteddata.txt");
BufferedReader br = new BufferedReader(new FileReader(new File("data.txt")));
String r = null;
while((r=br.readLine())!=null) {
String [] str = r.split("-");
for (String string : str) {
Long l = Long.parseLong(string.trim(), 16);
output.write(String.valueOf(l).getBytes());
output.write("\n".getBytes());
}
}
br.close();
output.close();
}
I am using following code to encrypt my email id in Java and sending it as a parameter in url (Using URLEncoder.encode(encrypteInput("email"))):
public static String encrypteInput(String input) {
String output = null;
input = input + ((int) Math.random()) % 1000;
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
output = new String(md5.digest(input.getBytes()));
} catch (Exception e) {
output = "";
}
return output;
}
but, when I am getting the same parameter from servlet, it is not giving me the same output as encrypteInput("email").
Whenever you have a byte array that you want to store in a string, you should be Hex- or Base64-encoding the byte array (hex-encoding is probably better in this particular case).
Apache commons-codec has a Hex class you can use for this:
byte[] bytes = ...
char[] encoded = Hex.encodeHex(bytes);
String encodedString = new String(encoded);
I'm new to java and really need some help. I created a command line tool in order to get an MD5 hash of a file. This worked so I then tailored my code to put it in GUI form. The two programs give different hashes of the same file which is confusing. I have looked into UTF-8 but as far as I can tell that would only work for strings and not a file instance. Can anyone tell me why they are providing different hash values and point me in the right direction?
First method (command line)...
public static void main(String args[]) throws IOException, NoSuchAlgorithmException {
System.out.println("Please enter file path: \n");
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
String dir = stdin.readLine();
File file = new File(dir);
FileInputStream iStream = null;
try {iStream = new FileInputStream(file);}
catch (FileNotFoundException e) {
String MD5Output = "There has been an error: " + e.toString();
}
byte[] dataBytes = new byte[1024];
MessageDigest md = MessageDigest.getInstance("MD5");
int numRead = iStream.read(dataBytes);
md.update(dataBytes, 0, numRead);
iStream.close();
dataBytes = md.digest();
md.update(dataBytes);
System.out.println("MD5: " + new BigInteger(1, md.digest()).toString(16));
}
Second method (built for gui)...
public void doMD5() throws IOException, NoSuchAlgorithmException {
File file = new File(jTxtMD51.getText());
FileInputStream iStream = null;
try {iStream = new FileInputStream(file);}
catch (FileNotFoundException e) {
String MD5Output = "There has been an error: " + e.toString();
}
byte[] dataBytes = new byte[1024];
MessageDigest md = MessageDigest.getInstance("MD5");
int numRead = iStream.read(dataBytes);
md.update(dataBytes, 0, numRead);
iStream.close();
byte[] MD5checksum = md.digest();
md.update(dataBytes);
BigInteger bigInt = new BigInteger(1, md.digest());
String MD5Hash = bigInt.toString(16);
jTextOutput.append("MD5 is : " + MD5Hash);
}
you only make one read call from the stream. you need to loop when reading an InputStream (assuming you want to read the whole thing, which you generally want). additionally, you seem to make 2 calls to digest.update() using the same bytes.
also, typically when a hash value is printed, since it is a binary value, it is printed using base64 encoding.
In addition to #jtahlborn's comment, you don't need the md.update(databytes); call in both methods, and your second method should have this at the end:
BigInteger bigInt = new BigInteger(1, MD5checksum);
You first method doesn't do this second call to digest(), whose values changes when you make the call to update()