java 8 deserialize base64 encoded string - java

I'm taking part in a Capture the Flag contest. A question I'm stuck on relates to deserialization of a Java object. I'm interrogating a cookie string which is base64 encoded. When I decode that, I believe it is a Java serialized object which I want to deserialize in order to alter their values and re-encode in base64.
I know nothing about java, I've tried to deserialize the base64 decoded bytes, but I think this is the wrong type.
import java.util.Base64;
import java.util.UUID;
import java.io.UnsupportedEncodingException;
import java.io.ObjectInputStream;
public class decode {
public static void main(String args[]){
try {
// Encode using basic encoder
String base64encodedString = "mybase64encodedstring==";
System.out.println("Base64 encoded string :" + base64encodedString);
// Decode
byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);
ObjectInputStream in = new ObjectInputStream(base64decodedBytes);
System.out.println("Deserialised data: \n" + in.readObject().toString());
System.out.println("Original String: " + new String(base64decodedBytes, "utf-8"));
}catch(UnsupportedEncodingException e){
System.out.println("Error :" + e.getMessage());
}
}
}
The error I get is:
incompatible types: byte[] cannot be converted to InputStream
Any help appreciated!

Use ByteArrayInputStream instead of ObjectInputStream.
So, use this:
InputStream in = new ByteArrayInputStream(base64decodedBytes);
instead this:
ObjectInputStream in = new ObjectInputStream(base64decodedBytes);

#Hrabosch said use ByteArrayInputStream instead. Actually, use ByteArrayInputStream aswell
Also, if the data is a bunch of bytes written by an ObjectOuputStream, then it makes no sense to construct a string from those bytes
Like so
import java.util.Base64;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
public class Decode {
public static void main(String args[]){
try {
// Encode using basic encoder
// I assume you replace this with actual data...
String base64encodedString = "mybase64encodedstring==";
System.out.println("Base64 encoded string :" + base64encodedString);
// Decode
byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);
InputStream in = new ByteArrayInputStream(base64decodedBytes);
ObjectInputStream obin = new ObjectInputStream(in);
Object object = obin.readObject();
System.out.println("Deserialised data: \n" + object.toString());
// You could also try...
System.out.println("Object class is " + object.getClass().toString());
// Don't do this!! The original data was not a string!
//System.out.println("Original String: " + new String(base64decodedBytes, "utf-8"));
}catch(ClassNotFoundException | IOException e){
System.out.println("Error :" + e.getMessage());
}
}
}

Related

use Java to convert ANY file to hex and back again

I have some files i would like to convert to hex, alter, and then reverse again, but i have a problem trying to do jars, zips, and rars. It seems to only work on files containing normally readable text. I have looked all around but cant find anything that would allow jars or bats to do this correctly. Does anyone have an answer that does both? converts to hex then back again, not just to hex?
You can convert any file to hex. It's just a matter of obtaining a byte stream, and mapping every byte to two hexadecimal numbers.
Here's a utility class that lets you convert from a binary stream to a hex stream and back:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
public class Hex {
public static void binaryToHex(InputStream is, OutputStream os) {
Writer writer = new BufferedWriter(new OutputStreamWriter(os));
try {
int value;
while ((value = is.read()) != -1) {
writer.write(String.format("%02X", value));
}
writer.flush();
} catch (IOException e) {
System.err.println("An error occurred");
}
}
public static void hexToBinary(InputStream is, OutputStream os) {
Reader reader = new BufferedReader(new InputStreamReader(is));
try {
char buffer[] = new char[2];
while (reader.read(buffer) != -1) {
os.write((Character.digit(buffer[0], 16) << 4)
+ Character.digit(buffer[1], 16));
}
} catch (IOException e) {
System.err.println("An error occurred");
}
}
}
Partly inspired by this sample from Mykong and this answer.
Don't use a Reader to read String / char / char[], use an InputStream to read byte / byte[].

Replacement of sun.misc.BASE64Encoder in Oracle DB? [duplicate]

I need to encode some data in the Base64 encoding in Java. How do I do that? What is the name of the class that provides a Base64 encoder?
I tried to use the sun.misc.BASE64Encoder class, without success. I have the following line of Java 7 code:
wr.write(new sun.misc.BASE64Encoder().encode(buf));
I'm using Eclipse. Eclipse marks this line as an error. I imported the required libraries:
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
But again, both of them are shown as errors. I found a similar post here.
I used Apache Commons as the solution suggested by including:
import org.apache.commons.*;
and importing the JAR files downloaded from: http://commons.apache.org/codec/
But the problem still exists. Eclipse still shows the errors previously mentioned. What should I do?
You need to change the import of your class:
import org.apache.commons.codec.binary.Base64;
And then change your class to use the Base64 class.
Here's some example code:
byte[] encodedBytes = Base64.encodeBase64("Test".getBytes());
System.out.println("encodedBytes " + new String(encodedBytes));
byte[] decodedBytes = Base64.decodeBase64(encodedBytes);
System.out.println("decodedBytes " + new String(decodedBytes));
Then read why you shouldn't use sun.* packages.
Update (2016-12-16)
You can now use java.util.Base64 with Java 8. First, import it as you normally do:
import java.util.Base64;
Then use the Base64 static methods as follows:
byte[] encodedBytes = Base64.getEncoder().encode("Test".getBytes());
System.out.println("encodedBytes " + new String(encodedBytes));
byte[] decodedBytes = Base64.getDecoder().decode(encodedBytes);
System.out.println("decodedBytes " + new String(decodedBytes));
If you directly want to encode string and get the result as encoded string, you can use this:
String encodeBytes = Base64.getEncoder().encodeToString((userName + ":" + password).getBytes());
See Java documentation for Base64 for more.
Use Java 8's never-too-late-to-join-in-the-fun class: java.util.Base64
new String(Base64.getEncoder().encode(bytes));
In Java 8 it can be done as:
Base64.getEncoder().encodeToString(string.getBytes(StandardCharsets.UTF_8))
Here is a short, self-contained complete example:
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Temp {
public static void main(String... args) throws Exception {
final String s = "old crow medicine show";
final byte[] authBytes = s.getBytes(StandardCharsets.UTF_8);
final String encoded = Base64.getEncoder().encodeToString(authBytes);
System.out.println(s + " => " + encoded);
}
}
Output:
old crow medicine show => b2xkIGNyb3cgbWVkaWNpbmUgc2hvdw==
You can also convert using Base64 encoding. To do this, you can use the javax.xml.bind.DatatypeConverter#printBase64Binary method.
For example:
byte[] salt = new byte[] { 50, 111, 8, 53, 86, 35, -19, -47 };
System.out.println(DatatypeConverter.printBase64Binary(salt));
With Guava
pom.xml:
<dependency>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
<type>jar</type>
<version>14.0.1</version>
</dependency>
Sample code:
// encode
String s = "Hello Việt Nam";
String base64 = BaseEncoding.base64().encode(s.getBytes("UTF-8"));
// decode
System.out.println("Base64:" + base64); // SGVsbG8gVmnhu4d0IE5hbQ==
byte[] bytes = BaseEncoding.base64().decode(base64);
System.out.println("Decoded: " + new String(bytes, "UTF-8")); // Hello Việt Nam
Eclipse gives you an error/warning because you are trying to use internal classes that are specific to a JDK vendor and not part of the public API. Jakarta Commons provides its own implementation of base64 codecs, which of course reside in a different package. Delete those imports and let Eclipse import the proper Commons classs for you.
For Java 6-7, the best option is to borrow code from the Android repository. It has no dependencies.
https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/Base64.java
Java 8 does contain its own implementation of Base64. However, I found one slightly disturbing difference. To illustrate, I will provide a code example:
My codec wrapper:
public interface MyCodec
{
static String apacheDecode(String encodedStr)
{
return new String(Base64.decodeBase64(encodedStr), Charset.forName("UTF-8"));
}
static String apacheEncode(String decodedStr)
{
byte[] decodedByteArr = decodedStr.getBytes(Charset.forName("UTF-8"));
return Base64.encodeBase64String(decodedByteArr);
}
static String javaDecode(String encodedStr)
{
return new String(java.util.Base64.getDecoder().decode(encodedStr), Charset.forName("UTF-8"));
}
static String javaEncode(String decodedStr)
{
byte[] decodedByteArr = decodedStr.getBytes(Charset.forName("UTF-8"));
return java.util.Base64.getEncoder().encodeToString(decodedByteArr);
}
}
Test Class:
public class CodecDemo
{
public static void main(String[] args)
{
String decodedText = "Hello World!";
String encodedApacheText = MyCodec.apacheEncode(decodedText);
String encodedJavaText = MyCodec.javaEncode(decodedText);
System.out.println("Apache encoded text: " + MyCodec.apacheEncode(encodedApacheText));
System.out.println("Java encoded text: " + MyCodec.javaEncode(encodedJavaText));
System.out.println("Encoded results equal: " + encodedApacheText.equals(encodedJavaText));
System.out.println("Apache decode Java: " + MyCodec.apacheDecode(encodedJavaText));
System.out.println("Java decode Java: " + MyCodec.javaDecode(encodedJavaText));
System.out.println("Apache decode Apache: " + MyCodec.apacheDecode(encodedApacheText));
System.out.println("Java decode Apache: " + MyCodec.javaDecode(encodedApacheText));
}
}
OUTPUT:
Apache encoded text: U0dWc2JHOGdWMjl5YkdRaA0K
Java encoded text: U0dWc2JHOGdWMjl5YkdRaA==
Encoded results equal: false
Apache decode Java: Hello World!
Java decode Java: Hello World!
Apache decode Apache: Hello World!
Exception in thread "main" java.lang.IllegalArgumentException: Illegal base64 character d
at java.util.Base64$Decoder.decode0(Base64.java:714)
at java.util.Base64$Decoder.decode(Base64.java:526)
at java.util.Base64$Decoder.decode(Base64.java:549)
Notice that the Apache encoded text contain additional line breaks (white spaces) at the end. Therefore, in order for my codec to yield the same result regardless of Base64 implementation, I had to call trim() on the Apache encoded text. In my case, I simply added the aforementioned method call to the my codec's apacheDecode() as follows:
return Base64.encodeBase64String(decodedByteArr).trim();
Once this change was made, the results are what I expected to begin with:
Apache encoded text: U0dWc2JHOGdWMjl5YkdRaA==
Java encoded text: U0dWc2JHOGdWMjl5YkdRaA==
Encoded results equal: true
Apache decode Java: Hello World!
Java decode Java: Hello World!
Apache decode Apache: Hello World!
Java decode Apache: Hello World!
CONCLUSION: If you want to switch from Apache Base64 to Java, you must:
Decode encoded text with your Apache decoder.
Encode resulting (plain) text with Java.
If you switch without following these steps, most likely you will run into problems. That is how I made this discovery.
To convert this, you need an encoder & decoder which you will get from Base64Coder - an open-source Base64 encoder/decoder in Java. It is file Base64Coder.java you will need.
Now to access this class as per your requirement you will need the class below:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Base64 {
public static void main(String args[]) throws IOException {
/*
* if (args.length != 2) {
* System.out.println(
* "Command line parameters: inputFileName outputFileName");
* System.exit(9);
* } encodeFile(args[0], args[1]);
*/
File sourceImage = new File("back3.png");
File sourceImage64 = new File("back3.txt");
File destImage = new File("back4.png");
encodeFile(sourceImage, sourceImage64);
decodeFile(sourceImage64, destImage);
}
private static void encodeFile(File inputFile, File outputFile) throws IOException {
BufferedInputStream in = null;
BufferedWriter out = null;
try {
in = new BufferedInputStream(new FileInputStream(inputFile));
out = new BufferedWriter(new FileWriter(outputFile));
encodeStream(in, out);
out.flush();
}
finally {
if (in != null)
in.close();
if (out != null)
out.close();
}
}
private static void encodeStream(InputStream in, BufferedWriter out) throws IOException {
int lineLength = 72;
byte[] buf = new byte[lineLength / 4 * 3];
while (true) {
int len = in.read(buf);
if (len <= 0)
break;
out.write(Base64Coder.encode(buf, 0, len));
out.newLine();
}
}
static String encodeArray(byte[] in) throws IOException {
StringBuffer out = new StringBuffer();
out.append(Base64Coder.encode(in, 0, in.length));
return out.toString();
}
static byte[] decodeArray(String in) throws IOException {
byte[] buf = Base64Coder.decodeLines(in);
return buf;
}
private static void decodeFile(File inputFile, File outputFile) throws IOException {
BufferedReader in = null;
BufferedOutputStream out = null;
try {
in = new BufferedReader(new FileReader(inputFile));
out = new BufferedOutputStream(new FileOutputStream(outputFile));
decodeStream(in, out);
out.flush();
}
finally {
if (in != null)
in.close();
if (out != null)
out.close();
}
}
private static void decodeStream(BufferedReader in, OutputStream out) throws IOException {
while (true) {
String s = in.readLine();
if (s == null)
break;
byte[] buf = Base64Coder.decodeLines(s);
out.write(buf);
}
}
}
In Android you can convert your bitmap to Base64 for Uploading to a server or web service.
Bitmap bmImage = //Data
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageData = baos.toByteArray();
String encodedImage = Base64.encodeArray(imageData);
This “encodedImage” is text representation of your image. You can use this for either uploading purpose or for diplaying directly into an HTML page as below (reference):
<img alt="" src="data:image/png;base64,<?php echo $encodedImage; ?>" width="100px" />
<img alt="" src="data:image/png;base64,/9j/4AAQ...........1f/9k=" width="100px" />
Documentation: http://dwij.co.in/java-base64-image-encoder
On Android, use the static methods of the android.util.Base64 utility class. The referenced documentation says that the Base64 class was added in API level 8 (Android 2.2 (Froyo)).
import android.util.Base64;
byte[] encodedBytes = Base64.encode("Test".getBytes());
Log.d("tag", "encodedBytes " + new String(encodedBytes));
byte[] decodedBytes = Base64.decode(encodedBytes);
Log.d("tag", "decodedBytes " + new String(decodedBytes));
Apache Commons has a nice implementation of Base64. You can do this as simply as:
// Encrypt data on your side using BASE64
byte[] bytesEncoded = Base64.encodeBase64(str .getBytes());
System.out.println("ecncoded value is " + new String(bytesEncoded));
// Decrypt data on other side, by processing encoded data
byte[] valueDecoded= Base64.decodeBase64(bytesEncoded );
System.out.println("Decoded value is " + new String(valueDecoded));
You can find more details about base64 encoding at Base64 encoding using Java and JavaScript.
If you are using Spring Framework at least version 4.1, you can use the org.springframework.util.Base64Utils class:
byte[] raw = { 1, 2, 3 };
String encoded = Base64Utils.encodeToString(raw);
byte[] decoded = Base64Utils.decodeFromString(encoded);
It will delegate to Java 8's Base64, Apache Commons Codec, or JAXB DatatypeConverter, depending on what is available.
Simple example with Java 8:
import java.util.Base64;
String str = "your string";
String encodedStr = Base64.getEncoder().encodeToString(str.getBytes("utf-8"));
In Java 7 I coded this method
import javax.xml.bind.DatatypeConverter;
public static String toBase64(String data) {
return DatatypeConverter.printBase64Binary(data.getBytes());
}
If you are stuck to an earlier version of Java than 8 but already using AWS SDK for Java, you can use com.amazonaws.util.Base64.
I tried with the following code snippet. It worked well. :-)
com.sun.org.apache.xml.internal.security.utils.Base64.encode("The string to encode goes here");
public String convertImageToBase64(String filePath) {
byte[] fileContent = new byte[0];
String base64encoded = null;
try {
fileContent = FileUtils.readFileToByteArray(new File(filePath));
} catch (IOException e) {
log.error("Error reading file: {}", filePath);
}
try {
base64encoded = Base64.getEncoder().encodeToString(fileContent);
} catch (Exception e) {
log.error("Error encoding the image to base64", e);
}
return base64encoded;
}
GZIP + Base64
The length of the string in a Base64 format is greater then original: 133% on average. So it makes sense to first compress it with GZIP, and then encode to Base64. It gives a reduction of up to 77% for strings greater than 200 characters and more. Example:
public static void main(String[] args) throws IOException {
byte[] original = randomString(100).getBytes(StandardCharsets.UTF_8);
byte[] base64 = encodeToBase64(original);
byte[] gzipToBase64 = encodeToBase64(encodeToGZIP(original));
byte[] fromBase64 = decodeFromBase64(base64);
byte[] fromBase64Gzip = decodeFromGZIP(decodeFromBase64(gzipToBase64));
// test
System.out.println("Original: " + original.length + " bytes, 100%");
System.out.println("Base64: " + base64.length + " bytes, "
+ (base64.length * 100 / original.length) + "%");
System.out.println("GZIP+Base64: " + gzipToBase64.length + " bytes, "
+ (gzipToBase64.length * 100 / original.length) + "%");
//Original: 3700 bytes, 100%
//Base64: 4936 bytes, 133%
//GZIP+Base64: 2868 bytes, 77%
System.out.println(Arrays.equals(original, fromBase64)); // true
System.out.println(Arrays.equals(original, fromBase64Gzip)); // true
}
public static byte[] decodeFromBase64(byte[] arr) {
return Base64.getDecoder().decode(arr);
}
public static byte[] encodeToBase64(byte[] arr) {
return Base64.getEncoder().encode(arr);
}
public static byte[] decodeFromGZIP(byte[] arr) throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(arr);
GZIPInputStream gzip = new GZIPInputStream(bais);
return gzip.readAllBytes();
}
public static byte[] encodeToGZIP(byte[] arr) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(baos);
gzip.write(arr);
gzip.finish();
return baos.toByteArray();
}
public static String randomString(int count) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < count; i++) {
str.append(" ").append(UUID.randomUUID().toString());
}
return str.toString();
}
See also: How to get the JAR file for sun.misc.BASE64Encoder class?
add this library into your app level dependancies
implementation 'org.apache.commons:commons-collections4:4.4'

How to read url byte by byte?

Hi i am trying to read a url where i am getting a string i am printing that string on console but i want to read that url as a byte by byte which i am not getting how can i read
Here is my ReadTextFromURL
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
public class ReadTextFromURL {
public static void main(String[] args) {
try {
URL url = new URL("http://122.160.81.37:8080/mandim/MarketWise?m=agra");
ByteArrayOutputStream bais = new ByteArrayOutputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
int lin;
while ((lin = in.read()) != -1) {
System.out.println(lin);
}
in.close();
} catch (MalformedURLException e) {
System.out.println("Malformed URL: " + e.getMessage());
}catch (IOException e) {
System.out.println("I/O Error: " + e.getMessage());
}
}
}
desired output
धान~1325|चावल~2050|ज्वर~920|जौ~810|मकई~1280|गेहूँ~1420|जो~1050|बेजर~-|जय~800
getting output
2343
2366
2344
126
49
51
50
53
124
2330
2366
2357
2354
126
50
How can I get my desired output?
You can open the URL as InputStream and use the byte oriented method specifying an array of size equal to 1. Have a look to this page: http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read(byte[],%20int,%20int)
By the way, use the try-with-resource construct construct when working with streams:
byte oneSizeByteArray = new byte[1];
try (InputStream is = url.openStream()) {
is.read(oneSizeByteArray,0,1)
} catch (IOException ex) {
}
If you want to read bytes, don't use Readers. A Reader reads chars (not bytes). If you need to read bytes, use low-level input-output classes (InputStream/OutputStream).

Unable to print russian characters

I have a russian string which i have encoded to UTF-8
String str = "\u041E\u041A";
System.out.println("String str : " + str);
When i print the string in eclipse console i get ?? Can anyone suggest how to print the russian strings to console or what i am doing wrong here?
I have tried converting it to bytes using byte myArr[] = str.getBytes("UTF-8") and then new String(myArr, "UTF-8") still same problem :-(
Try this:
String myString = "some cyrillic text";
byte bytes[] = myString.getBytes("ISO-8859-1");
String value = new String(bytes, "UTF-8");
Or this:
String myString = "some cyrillic text";
byte bytes[] = myString.getBytes("UTF-8");
String value = new String(bytes, "UTF-8");
The main problem with russian its to set UTF-8 encoding correctly.
In eclipse Go to Run > Run Configuration > Common > Change the console encoding to UTF-8. You will be able to see the Russian Characters in console
My Eclipse prints it correctly
String str : ОК
try to change Run Configurations encoding to UTF-8 or CP1251
The display font of the console will most likely not cope with nonASCII characters.
You could try printing to a file rather then System.out
It's an old topic, but nevertheless maybe below would help someone.
If you're reading data using InputStream / InputStreamReader (for example from some API) that contains Cyrillic symbols and you get some gibberish like ������ ��� or ?????? ???, try to apply encoding Charset as second parameter of InputStreamReader constructor.
EXAMPLE:
Let's use Russian Central Bank API to get US dollars and euro price in Russian rubles. In below code we get data for the current day when we make a request. Data from API is in xml so we also need to parse it.
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
public class CBRFApi {
public static void main(String[] args) throws UnsupportedEncodingException {
String output = getAndReadData("http://www.cbr.ru/scripts/XML_daily.asp");
Document document = loadXMLFromString(output);
// getting root element
Node root = document.getDocumentElement();
NodeList currencies = root.getChildNodes();
// just for further reference
Node usDollar;
Node euro;
for (int i = 0; i < currencies.getLength(); i++) {
Node currency = currencies.item(i);
String key = currency.getAttributes().getNamedItem("ID").getNodeValue();
if (key.equals("R01235") || key.equals("R01239")) {
if (key.equals("R01235")) // US dollar ID
usDollar = currency;
else if (key.equals("R01239")) // Euro ID
euro = currency;
NodeList currencySpecs = currency.getChildNodes();
System.out.print(currencySpecs.item(1).getTextContent());
System.out.print(" " + currencySpecs.item(3).getTextContent());
System.out.print(" " + currencySpecs.item(4).getTextContent());
System.out.println();
}
}
}
public static String getAndReadData(String link) {
String output = "";
try {
URL url = new URL(link);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/xml");
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Linux; Android 4.2.2; en-us; SAMSUNG GT-I9505 Build/JDQ39) " +
"AppleWebKit/535.19 (KHTML, like Gecko) Version/1.0 Chrome/18.0.1025.308 Mobile Safari/535.19.");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
// below is the key line,
// without second parameter - Charset.forName("CP1251") -
// data in Cyrillic will be returned like ������ ���
InputStreamReader inputStreamReader = new InputStreamReader(conn.getInputStream(), Charset.forName("CP1251"));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
output += line;
}
conn.disconnect();
return output;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static Document loadXMLFromString(String xml)
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
InputSource inputSource = new InputSource(new StringReader(xml));
return builder.parse(inputSource);
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
return null;
}
}
}
So proper output is:
USD Доллар США 63,3791
EUR Евро 70,5980
And without indicating Charset.forName("CP1251"):
USD ������ ��� 63,3791
EUR ���� 70,5980
Of course actual encoding in your case may differ from CP1251, so if this one doesn't work, try other encoding.
This helped me in similar situation:
String myString = "some cyrillic text";
byte bytes[] = myString.getBytes("windows-1251");
String value = URLEncoder.encode(new String(bytes, "UTF-8"), "UTF-8");
I have found a solution -> right charset!
String path = "E:\\java\\test.txt"; File file = new File(path); Scanner scan = new Scanner(file, **"CP1251"**); System.out.println(scan.nextLine());
output was in Russian!
In XCode you can print values by LLDB function po [SomeClass returnAnObject]
For automatic work it can be added in some action in a breakpoint. Also you need add checkbox in "Automatic continue after eval actions"
I have same problem when I read "MyFile.txt" file with russian letters. May be helps to anyone. The solution is:
package j;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class J4 {
public static void Read_TXT_File(String fileName) throws
FileNotFoundException {
try{int i=0;
Scanner scanner = new Scanner(new File(fileName), "utf-8");
while (scanner.hasNext()) {
String line = scanner.nextLine();
//byte bytes[] = line.getBytes("UTF-8");
//line = new String(bytes, "UTF-8");
if (line.isEmpty()) {
System.out.println(i+": Empty line");
}
else {
System.out.println(i+": "+ line);
// here is your code for example String MyString = line
}
i++;
}
}catch(Exception ex){ex.printStackTrace();}
}
public static void main(String[] args) throws
FileNotFoundException {
Read_TXT_File("MyFile.txt");
}
}

Writing to and reading from file - Java - Not reading what I wrote into file

I'm executing an encryption algorithm and I need your help regarding writing to and reading from a .xtt file in Java. As part of the encryption, I basically need to write Base64 encoded bytes into a .txt file and read these exact bytes, decode them and use them to execute the decryption process.
I seem to be reading something different compared to what I'm writing into the .txt file. Basically when I check the bytearray I'm writing into the file it is reads as [B#56e5b723 but when I read it of my file it produces [B#35a8767.
Here's the outcome as printed in my Java console:
***Numbs converted to ByteArray is as follows: [B#56e5b723
Size of NumbsByteArray is: 10
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-x-x-x-x-x WriteByteArrayToFile(byte[] encoded) HAS STARTED -x-x-x-x-x
6,7,8,9,10 has been received as a byte array in WriteByteArrayToFile(byte[] encoded): [B#56e5b723
6,7,8,9,10 IS TO BE WRITTEN TO THE FILE: /Users/anmonari/Desktop/textfiletwo.txt
bs.write(encoded); HAS BEEN CALLED
-x-x-x-x-x WriteByteArrayToFile(byte[] encoded) HAS ENDED -x-x-x-x-x
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-x-x-x-x-x ReadByteArray() HAS STARTED -x-x-x-x-x
fileData read as bytes is: [B#35a8767
Size of fileData is: 10
fileDataString when converted to a string using String object is����������
fileDataString when converted to a string using fileDataStringTwo.toString()[B#35a8767
fileDataString.getBytes(); is: [B#2c6f7ce9
-x-x-x-x-x ReadByteArray() HAS ENDED -x-x-x-x-x***
Below is my code:
package com.writeandreadfromfile;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class WriteAndRead {
public static void main(String j[]) {
String Numbs = "6,7,8,9,10";
byte[] NumbsByteArray = Numbs.getBytes();
System.out.println("Numbs converted to ByteArray is as follows: " + NumbsByteArray);
System.out.println("Size of NumbsByteArray is: " + NumbsByteArray.length);
System.out.println("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
WriteByteArrayToFile(NumbsByteArray);
System.out.println("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
try {
ReadByteArrayFromFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Write ByteArray To File
public static void WriteByteArrayToFile(byte[] NumbsByteArray) {
System.out.println("\n-x-x-x-x-x WriteByteArrayToFile(byte[] encoded) HAS STARTED -x-x-x-x-x");
System.out.println("6,7,8,9,10 has been received as a byte array in WriteByteArrayToFile(byte[] encoded): " + NumbsByteArray);
String fileName = "/Users/anmonari/Desktop/textfiletwo.txt";
System.out.println("6,7,8,9,10 IS TO BE WRITTEN TO THE FILE: " + fileName);
BufferedOutputStream bs = null;
try {
FileOutputStream fs = new FileOutputStream(new File(fileName));
bs = new BufferedOutputStream(fs);
bs.write(NumbsByteArray);
System.out.println("bs.write(encoded); HAS BEEN CALLED");
bs.close();
bs = null;
} catch (Exception e) {
e.printStackTrace();
}
if (bs != null) try { bs.close(); } catch (Exception e) {}
System.out.println("-x-x-x-x-x WriteByteArrayToFile(byte[] encoded) HAS ENDED -x-x-x-x-x");
}
// Read ByteArray To File
public static void ReadByteArrayFromFile() throws IOException {
// Create FileInputStream and feed it the file name
System.out.println("-x-x-x-x-x ReadByteArray() HAS STARTED -x-x-x-x-x");
File file;
try {
file = new File("/Users/anmonari/Desktop/textfiletwo.txt");
// Create the object of DataInputStream
DataInputStream in = new DataInputStream((new FileInputStream(file)));
byte[] fileData = new byte[(int)file.length()];
System.out.println("fileData read as bytes is from file: " + fileData);
System.out.println("Size of fileData is: " + fileData.length);
//String fileDataString = in.readLine();
String fileDataString = new String(fileData);
System.out.println("fileDataString when converted to a string using String object is" + fileDataString);
String fileDataStringTwo = fileData.toString();
System.out.println("fileDataString when converted to a string using fileDataStringTwo.toString()" + fileDataStringTwo);
fileDataString.getBytes();
System.out.println("fileDataString.getBytes(); is: " + fileDataString.getBytes());
//Close the input stream
in.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("-x-x-x-x-x ReadByteArray() HAS ENDED -x-x-x-x-x");
}
}
Any assistance regarding how to read from a file the exact byte array you wrote onto a file is appreciated!
You're not printing the contents of the byte arrays. You're outputting their type and hashCode (the result of the toString() method on arrays).
To output the contents of a byte array, use
System.out.println(java.util.Arrays.toString(array));
In addition to what Sotirios pointed out (you're not reading from in), you're writing the byte array as text, i.e. "6,7,8,9,10", but then you're calling fileDataString.getBytes();. That gets the bytes of the string, which (assuming UTF-8) will be 0x36 0x2c 0x37 0x2c 0x38 0x2c 0x39 0x2c 0x31 0x30.
If your plan is that the file will be text, you need to parse the string back into a byte array. Maybe something like
String[] numbers = fileDataString.split();
byte[] bytes = new byte[numbers.length];
for (int i = 0; i < numbers.length; i++) {
bytes[i] = Byte.parseByte(numbers[i]);
}
On the other hand, if you just need to save and restore byte arrays, you'll have a simpler time with just an ObjectOutputStream and ObjectInputStream.
You can try bs(fs).flush() which buffered everything which were written out

Categories