Unique Bytes from a String - java

I want to get bytes from a string value( for Encryption/Decryption purposes ),
I have used getBytes() method for that purpose, but every time i call getBytes() method,
it returns a new bytes of array each time.
I want a unique bytes of array for a particular string.
How ? Also i want to store that information (string or byte) in a file, and i want to get back this information in form of bytes.

getBytes() will not return new byte[] every time but contents are same.
Please check the below sample
byte[] b1 = "abc".getBytes();
byte[] b2 = "abc".getBytes();
if(b1 == b2)
{
System.out.println("Equal Not possible");//Not this
}
if(Arrays.equals(b1, b2))
{
System.out.println("Equal possible");//Gets printed
}
As contents of Array are equal here it should not make any difference in any possible kind of encryption/description algorithm in whole Java world !

If String gave you the same byte array every time, it would violate the contract of the method. Here is why:
String a = "test";
byte[] abytes1 = a.getBytes();
abytes1[0] = 0; // we are modifying the byte array.
// There is no way to prevent this!
// some other caller later on does this:
byte[] abytes2 = a.getBytes();
If abytes2 was the same array as abytes1, it would have a 0 as its first entry and would not match the value of the string. String.getBytes() must create a new array every time in case a caller decides to modify the array.

Related

How to convert a Base64 String to a byte array in java (signed char)?

I need to convert a Base64 String (UTF-8) to an array of bytes in java. The logic I've used was not able to accomplish that properly. I guess this code does not take into consideration the indication for signed or unsigned char. I runs with no erros, but the results are not the expected ones. How Can I get the byte array considering possible negative values?
Base64 decoder = new Base64();
byte[] decodedBytes = (byte[]) decoder.decode(getInfo().getBytes());
for (int i = 0; i < decodedBytes.length; i++) {
System.out.println(decodedBytes[i]);
}
private static String getInfo() {
return "+//q/93/4v/0//7/AAD0/+f/6v/7/wIA9P/g/9v/7P/x//H/5//b/+D/9v/+
//v/8f/g/+z/BQD+/+r/4P/i/+z/9v/5/+L/0f/q/wIABQD5/+z/5f/5/wcA
+f/l/+D/4v/v//v/7//d/93/9P8FAAIA+f/g/+f//v8FAPn/4v/b/+z/+//7
/+//5//x/wIABQD7/+r/1v/q//b/+f/s/+f/4v/s//n/9P/i/9j/7P/+/wAA
9P/q/+f/+f8FAPv/5//d/+X/9v8AAO//4P/b/+//9v/+//b/5f/v//v/AAD0
/+L/3f/q//H/+//s/93/5f/2/wAA+f/x/+X/7P/7//T/4P/R/93/6v/5//T/
4v/Y/+///v8CAPb/8f/n//T//v/0/93/4P/s/+//AAD2/+L/5f/x//v/+f/2
/+L/6v/+/wUA8f/l/93/6v/0//v/7P/b/+L/+f8AAPv/7P/b/+//AAD+/+r/
2//d/+z/+//2/+X/1v/q//v/+//0/+X/3f/x/wAA+f/l/93/6v/x//n/7//l
/+L/7/8CAPn/8f/g/+r//v8AAPT/4P/b/+L/7P/0/+f/1v/l//b/+f/0//H/
4P/n//7//v/q/9v/2//n//b/8f/d/9v/7P/5//v/9v/s/+D/9P8AAPn/5f/d
/+D/5//2//H/4P/i//H/AAD7//T/5//v//v//v/v/9v/0f/i/+z/9v/l/9P/
3f/0//7/+//v/+L/7P8HAAUA7P/d/9v/4v/2/+//4P/Y/+z/AAAAAPn/7P/g
/+//AgD5/+f/3f/l//H//v/0/+D/3f/s/wAAAAD2/+L/5//7//v/8f/b/9j/
5f/x//n/7P/b/+r/+/8FAPv/7//d//H//v/7/+z/2//d/+r/+//7/+f/3f/s
/wIABQAAAPH/6v/x/wUAAADq/+L/7//s//v/8f/l/+L/7/8AAP7/9v/l/+z/
AAAKAPv/6v/l/+//+f8AAPH/2//i//b/BQAFAPv/7P/x/xsAFAD5/+r/7P/5
/wUA+//v/93/7P/7/wUA+f/v/+X/8f/7//b/5f/b/93/5f/2//H/4v/b//H/
AAD7/+//4v/q//b/+//v/+X/2//i/+//9P/n/93/6v/2//n/9v/x/93/6v/5
//T/4v/W/9v/6v/5//H/5//d/+r//v8AAPT/6v/b/+r/+f/x/+X/3f/l/+z/
+f/x/9v/3f/s/wAA+f/x/+D/5f/v//b/8f/i/+f/5f/2/wAA+f/x//7/DAAU
ABQAEQAHABsAOQBDADkANABNAGYAjgCnAKIArAC+AOgA+gD6APoA+gAVAScB
HwEaAQsBBAEBAQYB5gDFAKwAnQCTAH0AXABBADQAMgAgAAoA6v/i/+r/6v/s
/9P/uv+//9H/zv+//7D/nP+p/8T/xP+z/6n/q/+1/8L/xP+w/6n/uv/M/8z/
x/+9/7r/0f/g/9b/xP+//8f/1v/v/+f/0//R/93/8f/v/+D/zv/W/+f/7//d
/87/zP/Y/+f/9P/l/8z/2P/s//n/9P/d/8z/4v/2/+//4v/W/9P/3f/v/+r/
3f/O/+D/9P/0/+X/2//T/+f/+f/v/93/0f/b/+f/9P/s/9H/0//l//v/+//s
/9v/5//s//T/6v/R/87/2//q//T/4v/W/+D/8f/7/+z/5f/T/+L/8f/x/+L/
zv/O/9j/6v/n/93/1v/g//T/+//s/+L/1v/l//b/7//b/87/2P/l/+//5//M
/87/2//0//v/7//Y/9v/6v/5/+r/2P/R/93/5f/q/9j/xP/O/+r/9v/x/+//
3f/i//v/9P/i/9H/zv/i//T/5//Y/8z/2P/x//v/7P/l/93/8f/+//T/4P/W
/93/4P/q/+z/0//W/+f/+f/0/+z/3f/l//T/AADv/9v/3f/n//H/+//q/9b/
4P/5/wUAAAD0/+D/7P8AAAAA7P/g/+L/8f/+//v/8f/l//T/AgAFAPn/8f/s
/wIAFAAKAPT/5//v//v/DwAKAO//7P/+/xQAFAAFAPb//v8MABsAEQD7/+//
/v8KABEABQD+/wcAFgAjACUAGwAKAA8AIwAgABEABQAAAA8AHgAZAAcA/v8P
ACMAJQAZAAoAAgAWACAAFAAHAAAADAAUACMAGwAHAAUADwAlACMAHgAFAAwA
HgAoABsABwD+/wUADAAWAAoA9v8AAAwAGQARAAoA+f/7/w8AEQAFAPH/8f/+
/woABQD2/+z/AAARAA8AAAD5/+z//v8HAAAA8f/n/+z/7/8AAAUA5//i//T/
AgAAAPv/7//0/wAACgD7/+z/4P/n/+r/9v/q/93/6v/5/wIA/v/5/93/6v/7
/wAA8f/i/9v/5f/x//b/6v/d/+z/+/8CAPb/5f/W/+r/+f/0/93/2//l/+X/
7//2/+z/9v/q//v/AAAHAO//6v/5/wAAAADl/+X/7P/l/+//7P/g/+z/8f/5
//7//v/v/+X/9v/x//T/8f/s/93/9P/5/+z/2//v//b/7//+//n/6v/v//7/
8f/l/+r/4v/i//H/+f/d/+r/7P8AAPv/BQD7//H/+/8CAPb/7P/x/+r/7//7
//H/5f/x//v/9P/7/wAA7//s/wAA+f/s/+z/6v/s//b//v/x/93/6v/0/+z/
/v8AAPH/7//5//H/7//0/+f/7P/5//n/5//q/+//8f/2/wAAAAD0//b/9v/s
/+//9P/q/+//+f/7/+X/9P/7/wIAAAAFAO//5//2/+z/8f/l/+//7P/0//n/
7//i//H/+f/s//b/+f/n/+z/AgD5//H/8f/n/+f/9P/7/+r/7P/x//T/+f/+
/+//7P/2/wAA9P/q//H/6v/x//b/7//q//H/+//0//n/9v/n/+X/+f/2/+//
5//n/93/7//0//H/4P/s//T/7//5//H/7P/0//7/8f/l/+r/6v/l//v/+//s
/+f/6v/2//T/9v/s/+f/9P/5//T/6v/s/+z/5//0/+//5//x//T/6v/7//7/
7P/n//T/9v/v/+z/5//g/+r/7P/n/93/7P/0/+///v/0/+D/5f/s/+L/4v/s
/+X/5//7//n/5//l/+r/+f/2/wIA8f/q//H/9v/0/+r/5//q/+r/8f/5/+z/
+//v/wAA/v8FAO//4v8KAAUA7P/v/+z/+f/+/wAA8f/x//T/AAACAAAA9v/s
//7/CgAAAN3/7//7//7/";
}
I say the results are not the expected because I have to make a graphic with the array values and compare it to another existing one and currently the drawings are different.
Updating... What if I wanted to get 16 bits at a time instead of only 8?

Using ReadFully in java

I am using Readfully in java to read a file. The below code illustrates it.
import java.io.*;
public class RandomAccessFileDemo {
public static void main(String[] args) {
try {
// create a string and a byte array
// create a new RandomAccessFile with filename test
RandomAccessFile raf = new RandomAccessFile("/home/mayank/Desktop/Image/Any.txt", "rw");
// set the file pointer at 0 position
raf.seek(0);
int Length = (int)raf.length();
// create an array equal to the length of raf
byte[] arr = new byte[Length];
// read the file
raf.readFully(arr,0,Length);
// create a new string based on arr
String s2 = new String(arr);
// print it
System.out.println("" + s2);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
The contents of Any.txt is Hello World!!
The above code prints Hello World!!
but when I change
raf.readFully(arr,0,Length);
to
raf.readFully(arr,3,Length-3);
Instead of getting the output lo World!!, I get no error.
Can any one explain me how to use readfully.
Or how to get the output lo World!!?
readFully will start reading from the current position in the file by default. To skip the first three characters, use:
raf.skipBytes(3);
before using readFully. Also there's no reason to use an offset, so use:
raf.readFully(arr,0,Length - 3);
and things will be peachy.
IMPORTANT NOTE: This assumes that the first 3 characters are only one byte a piece, which isn't necessarily the case with some character sets. But since this is likely a beginning homework assignment or tutorial, this is likely the answer you're looking for.
Per the javadoc, the off and len parameters of readFully(byte[] b, int off, int len) affect where in your byte array the raf data is placed, not how much of the raf data is read. In all cases the remainder of the file is read fully.
If b is null, a NullPointerException is thrown. If off is negative, or
len is negative, or off+len is greater than the length of the array b,
then an IndexOutOfBoundsException is thrown. If len is zero, then no
bytes are read. Otherwise, the first byte read is stored into element
b[off], the next one into b[off+1], and so on. The number of bytes
read is, at most, equal to len.
try this instead:
raf.skipBytes(3);
raf.readFully(arr,3,Length-3);

Java: Remove first UTF string from byte array

I'm trying to remove a written string from a byte array and maintain the original separate objects:
byte[] data... // this is populated with the following:
// 00094E6966747943686174001C00074D657373616765000B4372616674656446757279000474657374
// to string using converter : " ChannelMessageUsernametest"
// notice that tab/whitespace, ignore quotes
// The byte array was compiled by writing the following (writeUTF from a writer):
// Channel
// Message
// Username
// test
Now I'm trying to strip Channel from the byte array:
ByteArrayDataInput input = ByteStreams.newDataInput(message);
String channel = input.readUTF(); // Channel, don't want this
String message = input.readUTF(); // Message
// works good, but I don't want Channel,
// and I can't remove it from the data before it arrives,
// I have to work with what I have
Here is my problem:
byte[] newData = Arrays.copyOfRange(data, channel.length() + 2, data.length)
// I use Arrays.copyOfRange to strip the whitespace (I assume it's not needed)
// As well, since it's inclusive of length size, I have to add 1 more,
// resulting in channel.length() + 1
// ...
ByteArrayDataInput newInput = ByteStreams.newDataInput(message);
String channel = newInput.readUTF(); // MessageUsernametext
See how I lose the separation of the objects, how can I keep the original "sections" of objects in the original byte[] data inside byte[] newData.
It's safe to assume that String channel (before and after stripping) is a string
It's NOT safe to assume that every object is a string, assume everything is random, because it is
As long as you can guarantee that channel is always in a reasonable character range (for example alphanumeric), changing the channel.length() + 2 to channel.length() + 4 should be sufficient.
Java Strings have 16-bit elements, so it is safe to convert a byte array into a String, although not as memory efficient:
private byte[] removeElements(byte[] data, int fromIndex, int len) {
String str1 = new String(data).substring(0,fromIndex);
String str2 = new String(data).substring(fromIndex+len,data.length);
return (str1+str2).getBytes();
}
In the same manner, you can also search for a String inside the byte array:
private int findStringInByteArray(byte[] mainByte, String str, int fromIndex) {
String main = new String(mainByte);
return main.indexOf(str,fromIndex);
}
Now you can call these methods together:
byte[] newData = removeElements(
data,
findStringInByteArray(data,channel,0),
channel.length() );

Getting Exception in Converting ByteArray to String with Fixed length

I want to convert bytes in to String.
I have one android application and I am using flatfile for data storage.
Suppose I have lots of record in my flatfile.
Here in flat file database, my record size is fixed and its 10 characters and here I am storing lots of String records sequence.
But when I read one record from the flat file, then it is fixed number of bytes for each record. Because I wrote 10 bytes for every record.
If my string is S="abc123";
then it is stored in flat file like abc123 ASCII values for each character and rest would be 0.
Means byte array should be [97 ,98 ,99 ,49 ,50 ,51,0,0,0,0].
So when I want to get my actual string from the byte array, at that time I am using below code and it is working fine.
But when I give my inputString = "1234567890" then it creates problem.
public class MainActivity extends Activity {
public static short messageNumb = 0;
public static short appID = 16;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// record with size 10 and its in bytes.
byte[] recordBytes = new byte[10];
// fill record by 0's
Arrays.fill(recordBytes, (byte) 0);
// input string
String inputString = "abc123";
int length = 0;
int SECTOR_LENGTH = 10;
// convert in bytes
byte[] inputBytes = inputString.getBytes();
// set how many bytes we have to write.
length = SECTOR_LENGTH < inputBytes.length ? SECTOR_LENGTH
: inputBytes.length;
// copy bytes in record size.
System.arraycopy(inputBytes, 0, recordBytes, 0, length);
// Here i write this record in the file.
// Now time to read record from the file.
// Suppose i read one record from the file successfully.
// convert this read bytes to string which we wrote.
Log.d("TAG", "String is = " + getStringFromBytes(recordBytes));
}
public String getStringFromBytes(byte[] inputBytes) {
String s;
s = new String(inputBytes);
return s = s.substring(0, s.indexOf(0));
}
}
But I am getting problem when my string has complete 10 characters. At that time I have two 0's in my byte array so in this line
s = s.substring(0, s.indexOf(0));
I am getting the below exception:
java.lang.StringIndexOutOfBoundsException: length=10; regionStart=0; regionLength=-1
at java.lang.String.startEndAndLength(String.java:593)
at java.lang.String.substring(String.java:1474)
So what can I do when my string length is 10.
I have two solutions- I can check my inputBytes.length == 10 then make it not to do subString condition otherwise check contains 0 in byte array.
But i don't want to use this solution because I used this thing at lots of places in my application. So, is there any other way to achieve this thing?
Please suggest me some good solution which works in every condition. I think at last 2nd solution would be great. (check contains 0's in byte array and then apply sub string function).
public String getStringFromBytes(byte[] inputBytes) {
String s;
s = new String(inputBytes);
int zeroIndex = s.indexOf(0);
return zeroIndex < 0 ? s : s.substring(0, zeroIndex);
}
i think this line cause the error
s = s.substring(0, s.indexOf(0));
s.indexOf(0)
returns -1 , perhaps you should specifiy the ASCII code
for zero which is 48
so this will work s = s.substring(0, s.indexOf(48));
check documentation for indexOf(int)
public int indexOf (int c) Since: API Level 1 Searches in this string
for the first index of the specified character. The search for the
character starts at the beginning and moves towards the end of this
string.
Parameters c the character to find. Returns the index in this string
of the specified character, -1 if the character isn't found.

Compare individual bytes with array of bytes

I need to verify that a code generated in one class is same as code verified in another class. But the twist is in other class the logic used is different. Its like this.
Class A:
String = "0A2D" (suppose)
i used the substring method, take out 0A , 2D and convert them into Decimal values & store them as bytes.
the end result will look something like this
int a1 = (byte) Integer.parseInt(s,16); here s= 0A
int a2 = (byte) Integer.parseInt(s,16); here s= 2D
so a1 would be 10 ( 1byte memory) , a2 would be 45 (1byte memory)
Class B:
In this class i'm supposed to use the method getBytes(). But when i use that I see some strange o/p saying [B#...... Firstly I need information about what is happening there actually. How is it getting encoded. Secondly the o/p here should be an array of bytes matching with o/p of Class A. i.e
byte[] b = {a1a2} ( memory 2bytes)
b = {1045}
So at the end A would be having 2 values with 1byte each. But B would have an array which would have the same two values but the memory size would be 2bytes.
I hope I'm clear in my ques & didnt confuse.
your kind help would be appreciated. thanks in advance.
What line of code gives the output "[B#......"? (I assume the dots mean you truncated the output.) This particular output appears as if you are trying to print the array reference rather than the elements of the array. You should either use a for loop to print the individual elements or use Array.toString() to get a String representation of the array.
Your language is slightly unclear but I think the following will do what you want:
byte[] b = new byte[] { a1, a2 };
Array initializers are a very useful feature of the language.
probably you are just printing it wrong when printing arrays use Arrays.toString(arr)
I assume when you say byte[] b = {a1a2} you mean byte[] b = {a1,a2}
If you want to print out the contents of a byte[] you need to convert it into a String first.
Here's a useful method to convert a byte array into a readable string:
public static String toHexString(byte[] data)
{
if (data == null) return "";
char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] hexChars = new char[data.length * 2];
int v;
for ( int j = 0; j < data.length; j++)
{
v = data[j] & 0xFF;
hexChars[j*2] = hexArray[v/16];
hexChars[j*2 + 1] = hexArray[v%16];
}
return new String(hexChars);
}
From there you should be able to work out the rest.

Categories