So I have some FRX binary files from which I am attempting to get string captions using Java's binary reading methods.
I was capable of doing so, and specifying the region in which to read bytes in C# using the following program :
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
public class GetFromFRX
{
public static void Main()
{
StringBuilder buffer = new StringBuilder();
using (BinaryReader b = new BinaryReader(File.Open("frmResidency.frx", FileMode.Open)))
{
try
{
b.BaseStream.Seek(641, SeekOrigin.Begin);
int length = b.ReadInt32();
for (int i = 0; i < length; i++)
{
buffer.Append(b.ReadChar());
}
}
catch (Exception e)
{
Console.WriteLine( "Error obtaining resource\n" + e.Message);
}
}
Console.WriteLine(buffer);
}
}
Question Update :
Attempting to do the same in Java, I have built the following program. Now I have implemented Guava in order to use LittleEndian equivalents, however now my length prints 24, and as a result I only get the first 24 bytes in my output file. Is ReadInt not appropriate for this situation, and function in a different manner than ReadInt32?
import java.io.*;
import com.google.common.io.*;
public class RealJavaByteReader {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("frmResidency.frx");
LittleEndianDataInputStream din = new LittleEndianDataInputStream(in);
out = new FileOutputStream("output.txt");
int length = din.readInt();
System.out.println(length);
int c;
for (c = 0; c < length; c++) {
// TODO: first read byte and check for EOF
out.write(din.read());
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
Elizion,
This might be because you might be reading an int stored using little endian. As such, Java uses Big endian and .NET little endian.
Use a function as below to convert a little endian int to a big endian int in java.
/**
* Byte swap a single int value.
*
* #param value Value to byte swap.
* #return Byte swapped representation.
*/
public static int swap (int value)
{
int b1 = (value >> 0) & 0xff;
int b2 = (value >> 8) & 0xff;
int b3 = (value >> 16) & 0xff;
int b4 = (value >> 24) & 0xff;
return b1 << 24 | b2 << 16 | b3 << 8 | b4 << 0;
}
Please try to see the below post.
Converting Little Endian to Big Endian
I realized what my mistake was at this point. Now that LittleEndianDataInputStream has been implemented, I can correctly use SkipBytes to set my initial byte position, and will return the string caption as required. Of course I will initially only produce the first 24 bytes, as whatever is in the first 4 bytes of the binary file must hold a length of 24 for some given property in the FRX file. I must set the offset with skipBytes in order to produce anything meaningful, because the lengths of properties in FRX files are stored in groups of 4 bytes and are followed by those bytes containing that property .
For instance, if I set din.skipBytes(308);, then the 308th to 312th bytes in the FRX file hold the byte-length of the string in the Caption property I require (for instance 140), which is output by readInt. Thus the next 140 bytes will contain my string required, and my for loop will iterate properly.
Related
I'm working on an encryption algorithm and I need to generate some information in Java (a binary file) to read in C++.
I'm not sure if the problem is how I create the binary file or how I read it, though I can perfectly read the information in Java.
So I made a simple test. In Java I save the number 9 to a binary file, and then I try to read it in C++, but it does not read a number.
Can someone please tell me how I can do this?
The Java code:
int x = 9;
try{
ObjectOutputStream salida=new ObjectOutputStream(new
FileOutputStream("test.bin"));
salida.writeInt(x);
salida.close();
System.out.println("saved");
} catch(Exception e){
System.out.println(e);
}
The C++ code:
streampos size;
char * memblock;
ifstream file ("test.bin", ios::in|ios::binary|ios::ate);
if (file.is_open())
{
size = file.tellg();
cout<< size << endl;
memblock = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();
int i;
for (i = 0; i < sizeof(memblock); i++)
{
cout << memblock[i] <<endl;
}
delete[] memblock;
}
else cout << "Unable to open file";
This is the output:
�
�
w
Your problem is that you are using ObjectOutputStream to write the data. This encodes the object graph in a Java-specific form intended to be read with ObjectInputStream. To make the data stream compatible with C++ you would need to do one of two things:
Implement in C++ code that understands the output format produced by ObjectOutputStream -- i.e. re-implement in C++ what Java does in ObjectInputStream. This is NOT recommended.
Write your data out from Java using a standard FileOutputStream, in a serialized format that you define, that then can be read by your C++ code. How you specify and implement this is up to you but can be very simple, depending on the complexity of your data.
Yor write to file int (4 bytes?), in your file in hex must bu such data as 09 00 00 00.
In your cpp code you read it to char array (you read bytes!), file.tellg(); return 4, and you read to char * memblock array {9, 0, 0, 0}. And after it you print it as chars cout << memblock[i] <<endl;.
So you can print your out array as
for (i = 0; i < size / sizeof(int) / ; i++) {
cout << ((int*)memblock)[i] <<endl;
}
or read it in int array
int* memblock;
...
memblock = new int[size / sizeof(int)];
...
file.read (memblock, (size / sizeof(int)) * sizeof(int));
Java code:
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class Main
{
public static void main( String[] args )
{
int x = 9;
try
{
FileOutputStream fout = new FileOutputStream( "prueba.bin" );
DataOutputStream salida = new DataOutputStream( fout );
salida.writeInt( x );
salida.close();
System.out.println( "guardado" );
}
catch( Exception e )
{
System.out.println( e );
}
}
}
C++ Builder code:
unsigned char buffer[4];
ifstream file( "prueba.bin", ios::in | ios::binary );
if( file.is_open() )
{
file.read( (char*)&buffer, sizeof( buffer ) );
int num = buffer[ 0 ] | buffer[1] | buffer[ 2 ] | buffer[ 3 ];
// another way to convert endianness:
// int num = buffer[ 0 ] | ( buffer[1] << 8 ) | ( buffer[ 2 ] << 16 ) | ( buffer[ 3 ] << 24 );
}
I have a binary file that I need to read and save as characters or a string of 0's and 1's in the same order that they are in the binary file. I am currently able to read in the binary file, but am unable to obtain the 0's and 1's. Here is the code I am currently using:
public void read()
{
try
{
byte[] buffer = new byte[(int)infile.length()];
FileInputStream inputStream = new FileInputStream(infile);
int total = 0;
int nRead = 0;
while((nRead = inputStream.read(buffer)) != -1)
{
System.out.println(new String(buffer));
total += nRead;
}
inputStream.close();
System.out.println(total);
}
catch(FileNotFoundException ex)
{
System.out.println("File not found.");
}
catch(IOException ex)
{
System.out.println(ex);
}
}
and the output from running this with the binary file:
�, �¨Ã �¨ÊÃ
�!Cˇ¯åaÃ!Dˇ¸åÇÃ�"( ≠EÃ!J�H���û�������
����������������������������������������������������������������������������������������
156
Thanks for any help you can give.
Check out String to binary output in Java. Basically you need to take your String, convert it to a byte array, and print out each byte as a binary string.
Instead of converting the bytes directly into characters and then printing them, convert each byte into a binary string and print them out. In other words, replace
System.out.println(new String(buffer));
with
for (int i = 0; i<nRead; i++) {
String bin=Integer.toBinaryString(0xFF & buffer[i] | 0x100).substring(1);
System.out.println(bin);
}
Notice though that the bits of each byte are printed in big-endian order. There is no way to know if bits are actually stored in this order on disk.
with JBBP such operation will be very easy
public static final void main(final String ... args) throws Exception {
try (InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream("somefile.txt")) {
class Bits { #Bin(type = BinType.BIT_ARRAY) byte [] bits; }
for(final byte b : JBBPParser.prepare("bit [_] bits;",JBBPBitOrder.MSB0).parse(inStream).mapTo(Bits.class).bits)
System.out.print(b != 0 ? "1" : "0");
}
}
But it will not be working with huge files because parsed data will be cached in memory during operatio
Even though this response is in C, you can use the JNI to access it natively from a Java program.
Since they are in a binary format, you will not be able to read it. I would do it like this.
fstream fs;
int value; //Since you are reading bytes, change accordingly.
fs.open( fileName, is.in | is.binary );
fs.read((char *) &value, sizeof(int));
while(!fs.eof())
{
//Print or do something with value
fs.read((char *) &value, sizeof(long));
}
Is there any way to convert Java String to a byte[] (not the boxed Byte[])?
In trying this:
System.out.println(response.split("\r\n\r\n")[1]);
System.out.println("******");
System.out.println(response.split("\r\n\r\n")[1].getBytes().toString());
and I'm getting separate outputs. Unable to display 1st output as it is a gzip string.
<A Gzip String>
******
[B#38ee9f13
The second is an address. Is there anything I'm doing wrong? I need the result in a byte[] to feed it to gzip decompressor, which is as follows.
String decompressGZIP(byte[] gzip) throws IOException {
java.util.zip.Inflater inf = new java.util.zip.Inflater();
java.io.ByteArrayInputStream bytein = new java.io.ByteArrayInputStream(gzip);
java.util.zip.GZIPInputStream gzin = new java.util.zip.GZIPInputStream(bytein);
java.io.ByteArrayOutputStream byteout = new java.io.ByteArrayOutputStream();
int res = 0;
byte buf[] = new byte[1024];
while (res >= 0) {
res = gzin.read(buf, 0, buf.length);
if (res > 0) {
byteout.write(buf, 0, res);
}
}
byte uncompressed[] = byteout.toByteArray();
return (uncompressed.toString());
}
The object your method decompressGZIP() needs is a byte[].
So the basic, technical answer to the question you have asked is:
byte[] b = string.getBytes();
byte[] b = string.getBytes(Charset.forName("UTF-8"));
byte[] b = string.getBytes(StandardCharsets.UTF_8); // Java 7+ only
However the problem you appear to be wrestling with is that this doesn't display very well. Calling toString() will just give you the default Object.toString() which is the class name + memory address. In your result [B#38ee9f13, the [B means byte[] and 38ee9f13 is the memory address, separated by an #.
For display purposes you can use:
Arrays.toString(bytes);
But this will just display as a sequence of comma-separated integers, which may or may not be what you want.
To get a readable String back from a byte[], use:
String string = new String(byte[] bytes, Charset charset);
The reason the Charset version is favoured, is that all String objects in Java are stored internally as UTF-16. When converting to a byte[] you will get a different breakdown of bytes for the given glyphs of that String, depending upon the chosen charset.
String example = "Convert Java String";
byte[] bytes = example.getBytes();
Simply:
String abc="abcdefghight";
byte[] b = abc.getBytes();
Try using String.getBytes(). It returns a byte[] representing string data.
Example:
String data = "sample data";
byte[] byteData = data.getBytes();
You can use String.getBytes() which returns the byte[] array.
You might wanna try return new String(byteout.toByteArray(Charset.forName("UTF-8")))
I know I'm a little late tothe party but thisworks pretty neat (our professor gave it to us)
public static byte[] asBytes (String s) {
String tmp;
byte[] b = new byte[s.length() / 2];
int i;
for (i = 0; i < s.length() / 2; i++) {
tmp = s.substring(i * 2, i * 2 + 2);
b[i] = (byte)(Integer.parseInt(tmp, 16) & 0xff);
}
return b; //return bytes
}
i had to conwert a int to decimal 3 byte 129 to 1 2 9
Byte data
int i1 = 129
int i3 = (i1 / 100);
i1 = i1 - i3*100;
int i2 = (i1 / 10);
i1 = i1 - i2*10;
data [1]= (byte) i1
data [2]= (byte) i2
data [3]= (byte) i3
It is not necessary to change java as a String parameter. You have to change the c code to receive a String without a pointer and in its code:
Bool DmgrGetVersion (String szVersion);
Char NewszVersion [200];
Strcpy (NewszVersion, szVersion.t_str ());
.t_str () applies to builder c ++ 2010
I just started studying computer science and our teacher gave us this small, but tricky programming assignment. I need to decode a .bmp image http://postimg.org/image/vgtcka251/ our teacher have handed us
and after 4 hours of research and trying i'm no closer to decoding it. He gave us his encoding method:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class HideMsgInPicture {
final static long HEADSIZE=120;
public static void main(String[] args) throws IOException {
encode();
decode();
}
private static void encode() throws IOException {
FileInputStream in = null;
FileInputStream msg = null;
FileOutputStream out = null;
try {
in = new FileInputStream("car.bmp");
msg = new FileInputStream("msg.txt");
out = new FileOutputStream("carX.bmp");
int c,mb;
byte clearBit1 = (byte) 0xFE; //254; // 11111110
for (int i=1;i<=HEADSIZE;i++) out.write(in.read()); //copy header
while ((mb = msg.read()) != -1) { // for all byte in message
for (int bit=7; bit>=0; bit--) // 1 bit a time from messsage
{ c = in.read() & clearBit1; // get picturebyte,clear last bit
c = (c | ((mb >> bit) & 1));// put msg-bit in end of pic-byte
out.write(c); // add pic-byte in new file
}
}
for (int bit=7; bit>=0; bit--) // add 8 zeroes as stop-byte of msg
{ c = in.read() & clearBit1; // get picturebyte,clear last bit
out.write(c); // add pic-byte in new file
}
while ((c = in.read()) != -1) out.write(c);// copy rest of file
}
finally {
if (in != null) in.close();
if (msg != null) msg.close();
if (out != null) out.close();
}
}
}
Would anyone be able to send me in the right direction?
How much do you know about steganography? The simplest algorithm (which is what your assignment is implementing) is the least significant bit (LSB). In short, you convert your message to binary (i.e. character 'a' = 01100001) and write the individual bits in the rightmost bits of the pixel values. For example, take 8 pixels (each represented by a byte) and in the first byte hide a 0, in the second 1, in the third 1, in the fourth 0, etc. To extract your message, obtain the binary string from the LSB in your pixels and convert it back to text.
Your teacher gave you the hiding algorithm, so basically you have to write an algorithm which reverses the process. You don't need to look further than that, you just have to understand what this code does. Just the inline comments should be enough.
I have a socket server which keeps listening to incoming requests. The data received will be in the form of binary array of bytes.
Data format is something like this.
2321902321221200AA
Whereas 1 byte is data begin
4 bits is version
4 bits is data return type
5 bytes are product code
2 bytes data length
The question is, how to parse the data and segregate the parameters.
Thanks in advance!!
Try java.io.DataInputStream:
DataInputStream dis = new DataInputStream(in);
byte b = dis.readByte();
int version = (b >> 4) & 0xF;
int returnType = b & 0xF;
byte[] productCode = new byte[5];
dis.readFully(productCode);
int len = dis.readShort() & 0xFFFF;
if use the java binary block parser then code will look like
class Parsed {
#Bin byte begin;
#Bin(type = BinType.BIT) int version;
#Bin(type = BinType.BIT) int returnType;
#Bin byte [] productCode;
#Bin(type = BinType.USHORT) int dataLength;
}
final Parsed parsed = JBBPParser.prepare("byte begin; bit:4 version; bit:4 returnType; byte [5] productCode; ushort dataLength;")
.parse(new byte[]{0x23,0x21,(byte)0x90,0x23,0x21,0x22,0x12,0x00,(byte)0xAA})
.mapTo(Parsed.class);
assertEquals(0x23, parsed.begin);
assertEquals(0x01, parsed.version);
assertEquals(0x02, parsed.returnType);
assertArrayEquals(new byte[]{(byte)0x90,0x23,0x21,0x22,0x12}, parsed.productCode);
assertEquals(0x00AA,parsed.dataLength);
try {
char [] cbuf = new char[16];
char databegin = cbuf[0];
char [] version = Arrays.copyOfRange(cbuf, 1, 6)
char [] product_typep = Arrays.copyOfRange(cbuf, 7, 12)
char []data_lendth = Arrays.copyOfRange(cbuf, 13, 15)
} catch(Error e){
System.out.println(e);
}
byte [] data = receiveData ();
int dataBegin = data [0]; // Once field is 1-byte, it is simple!
int version = data [1] & 0x0F; // Use shift (>>>) and binary "and" (&)
int returnCode = // to extract value of fields that are
(data [1] >>> 4) & 0x0F; // smaller than one byte
byte [] productCode = // Copy fixed-size portions of data
new byte [] { // into separate arrays using hardcode
data [2], data [3], // (as here), or System.arrayCopy
data [4], data [5], // in case field occupies quite
data [6]}; // a many bytes.
int dataLength = // Use shift (<<) binary or (|) to
(data [7] & 0xFF) | // Combine several bytes into one integer
((data [8] & 0xFF) << 8); // We assume little-endian encoding here
I would got for some king of package reader:
class Record {
.....
Record static fromBytes(byte[] bytes) {
// here use ByteBuffer or DataInputStream to extract filds
......
}
}
Record readNextRecord(InputStream in) {
int len = in.read() && 0xFF;
byte[] data = new byte[len];
in.read(data);
return Record.fromBytes(data)
}
{
InputStream in = ....;
Record r readNextRecord(in);
process (r);
}
Of course you need to add error handling. In general, for something which should run reliable, I will suggest to use NIO framework like Grizzly or Netty.
You might get the data via the ByteArrayOutputStream
And then parse the bytes by applying masks (mainly AND, OR).
Take a look at This question
Hope this helps