Need some help ensuring my ByteUtil class is accurate - java

I am not very familiar with exactly all of the implications of bytes or even close to charsets, simply because i have not used them often. However i am working on a project in which i need to convert every Java primitive type (and Strings) to AND from bytes. I want them all with the charset UTF-8, but i'm not sure if i am converting them properly.
Anyways, although i am pretty sure that all number to/from byte conversions are correct, but then again, i need to be 100% sure. If someone has really good experience with bytes with numbers and charsets, could you look over the class below, and point out any issues?
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
public class ByteUtil
{
//TO BYTES FROM PRIMITIVES & STRINGS
public static byte[] getBytes(short i)
{
return ByteBuffer.allocate(2).putInt(i).array();
}
public static byte[] getBytes(int i)
{
return ByteBuffer.allocate(4).putInt(i).array();
}
public static byte[] getBytes(long i)
{
return ByteBuffer.allocate(8).putLong(i).array();
}
public static byte getBytes(boolean i)
{
return (byte) (i ? 1 : 0);
}
public static byte[] getBytes(char i)
{
return getBytes(String.valueOf(i).trim());
}
public static byte[] getBytes(String i)
{
return i.getBytes(StandardCharsets.UTF_8);
}
public static byte[] getBytes(float i)
{
return getBytes(Float.floatToIntBits(i));
}
public static byte[] getBytes(double i)
{
return getBytes(Double.doubleToLongBits(i));
}
//TO PRIMITIVES & STRINGS FROM BYTES
public static short getShort(byte[] b)
{
ByteBuffer wrapped = ByteBuffer.wrap(b);
return wrapped.getShort();
}
public static int getInt(byte[] b)
{
ByteBuffer wrapped = ByteBuffer.wrap(b);
return wrapped.getInt();
}
public static long getLong(byte[] b)
{
ByteBuffer wrapped = ByteBuffer.wrap(b);
return wrapped.getLong();
}
public static boolean getBoolean(byte b)
{
return(b == 1 ? true : false);
}
public static char getChar(byte[] b)
{
return getString(b).trim().toCharArray()[0];
}
public static String getString(byte[] b)
{
return new String(b, StandardCharsets.UTF_8);
}
public static float getFloat(byte[] b)
{
return Float.intBitsToFloat(getInt(b));
}
public static double getDouble(byte[] b)
{
return Double.longBitsToDouble(getLong(b));
}
}
Additionally, all the data put in and returned is read by my source internally, for example the boolean conversion may or may not be the correct way to do something like such, but in the boolean case, it wont matter since i know what i am checking for.

You don't even need to do this. You can use a DataOutputStream to write your primitive types and Strings to a ByteArrayOutputStream. You can then use toByteArray() to get a byte[] that you put into a ByteArrayInputStream. You can wrap that InputStream in a DataInputStream to get back your primitives.
If you're doing a school assignment where you need to implement this yourself (which sounds like a dumb assignment), you can look up the implementations of ByteArrayOutputStream and ByteArrayInputStream on GrepCode. Copy/pasting is a bad idea, but it might give you some hints about considerations to take into account.

Related

How to map binary data in java class object?

Input data :hexadecimal 64 byte
String binaryData="01000076183003104000800180f5010100010100000063000000630000006300000063000000000000000000820000000200b8010307010700640005e1cbe180";
Question is to read this binary data and set in class object
Here is the model
public class Transaction_PLUSale {
public byte opcode;
public byte[] code=new byte[7];
public byte flag1;
public byte flag2;
public byte flag3;
public byte flag4;
public byte flag5;
public short deptnum;
public byte multi_sell_unit;
public byte return_type;
public byte tax_pointer;
public int qty;
public int price;
public int amount;
public int no_tax_price;
public int no_tax_amount;
public int return_surcharge_percent;
public byte product_code;
public byte flags;
public TransactionTail tail;
}
I am currently doing this way to set values in each fields.
String hexArray[]= binaryData.split("(?<=\\G..)");
public static void readPLUSalesData(String hexArray[]) {
Transaction_PLUSale pluSale=new Transaction_PLUSale();
pluSale.setOpcode(Byte.valueOf(hexArray[0]));
byte arr[]=new byte[7];
for(int i=1;i<=7;i++) {
arr[i-1]=Byte.valueOf(hexArray[i]);
}
pluSale.setCode(arr);
pluSale.setFlag1(Byte.valueOf(hexArray[8]));
pluSale.setFlag2(Byte.valueOf(hexArray[9]));
pluSale.setFlag3(Byte.valueOf(hexArray[10]));
pluSale.setFlag4(Byte.valueOf(hexArray[11]));
pluSale.setFlag5(Byte.valueOf(hexArray[12]));
pluSale.setDeptnum((short)Integer.parseInt((hexArray[14]+hexArray[13]),16));
pluSale.setMulti_sell_unit(Byte.valueOf(hexArray[15]));
pluSale.setReturn_type(Byte.valueOf(hexArray[16]));;
pluSale.setTax_pointer(Byte.valueOf(hexArray[17]));
pluSale.setQty(Integer.parseInt((hexArray[21]+hexArray[20]+hexArray[19]+hexArray[18]),16));
pluSale.setPrice(Integer.parseInt((hexArray[25]+hexArray[24]+hexArray[23]+hexArray[22]),16));
pluSale.setAmount(Integer.parseInt((hexArray[29]+hexArray[28]+hexArray[27]+hexArray[26]),16));
pluSale.setNo_tax_price(Integer.parseInt((hexArray[33]+hexArray[32]+hexArray[31]+hexArray[30]),16));
pluSale.setNo_tax_amount(Integer.parseInt((hexArray[37]+hexArray[36]+hexArray[35]+hexArray[34]),16));
pluSale.setReturn_surcharge_percent(Integer.parseInt((hexArray[41]+hexArray[40]+hexArray[39]+hexArray[38]),16));
pluSale.setProduct_code(Byte.valueOf(hexArray[42]));
pluSale.setFlags(Byte.valueOf(hexArray[43]));
}
It is working fine. But I want it to be generic. So instead of giving byte by byte value. I want to direct map it to class fields.
In .net we are doing the marshalling for same feature that I need.
Here is the example
foreach (KeyValuePair<string, byte[]> s in t)
{
//byte array consist of bytes of the above hexadecimal string.
Ticket ticket = new Ticket();
int count = Marshal.SizeOf(typeof(Transaction_Coupon));
MemoryStream ms = new MemoryStream(s.Value);
byte[] readBuffer = new byte[count];
BinaryReader br = new BinaryReader(ms);
readBuffer = br.ReadBytes(count);
GCHandle handle = GCHandle.Alloc(readBuffer, GCHandleType.Pinned);
//here we are mapping byte data to each field
Transaction_PLUSale t_plusale = (Transaction_PLUSale)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Transaction_PLUSale));
}
To convert binary data, a byte[] to a class with fields, there is no memory template to shift the data in. A good solution is using a ByteBuffer, either on a byte array or InputStream.
public static void readPLUSalesData(String[] hexArray) {
byte[] bytes = new byte[hexArray.length];
for (int i = 0; i < bytes.length; ++i) {
bytes[i] = Byte.parseByte(hexArray[i], 16);
}
ByteBuffer buf = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN;
Transaction_PLUSale pluSale=new Transaction_PLUSale();
pluSale.setOpcode(buf.get());
byte[] arr[] = new byte[7];
buf.get(arr);
pluSale.setCode(arr);
pluSale.setFlag1(buf.get());
pluSale.setFlag2(buf.get());
pluSale.setFlag3(buf.get());
pluSale.setFlag4(buf.get());
pluSale.setFlag5(buf.get());
pluSale.setDeptnum(buf.getShort());
pluSale.setMulti_sell_unit(buf.get());
pluSale.setReturn_type(buf.get());
pluSale.setTax_pointer(buf.get());
pluSale.setQty(buf.getInt());
pluSale.setPrice(buf.getInt());
pluSale.setAmount(buf.getInt());
pluSale.setNo_tax_price(buf.getInt());
pluSale.setNo_tax_amount(buf.getInt());
pluSale.setReturn_surcharge_percent(buf.getInt());
pluSale.setProduct_code(buf.get());
pluSale.setFlags(buf.get());
}
There exist other solutions, like using reflection, which is inefficient.
I used little endian byte order here, default in java is big endian.
There is the ObjectOutputStream, Serializable, persistence using serialisation.
It stores class data too, so is not the language agnostic format you desire.
While developing with a ByteBuffer is makes sense to check the read position.
If you are interested in XML persistence, JAXB with annotations offers a nice reflection based way, without need of handling every field.
A remark: Type[] variable is the preferred notation; Type var[] was initially added to java to be compatible with C/C++.

How to use over-ride the super class methods?

This was the question asked:
Develop a class Decrypt that derives from FileInputStream and overrides the read() method of FileInputStream such that overriding read method returns a decrypted integer. Use this class to decrypt the file information that is contained out.txt.
I wrote a code for encryption, it worked but for decryption it doesn't. For decryption, i have to XOR the value with 128.
The problem is that after running the program, it doesn't write anything on the output file.
Here's the link for the sample input:
https://www.dropbox.com/s/jb361cxmjc9yd8n/in.txt
This is how the sample output looks like:
How high he holds his haughty head.
The code is below:
//Decrypt class
import java.io.*;
public class Decrypt extends FileInputStream {
public Decrypt(String name) throws FileNotFoundException {
super(name);
}
public int read() throws IOException {
int value = super.read();
int xor = value^128; // exclusive OR to decrypt
return xor;
}
}
//main
import java.io.*;
public class LA4ex3b {
public static void main(String[] args) throws IOException {
Decrypt de=null;
FileOutputStream output=null;
try
{
de = new Decrypt("C:/Users/user/workspace/LA4ex3a/in.txt");
output = new FileOutputStream("C:/Users/user/workspace/LA4ex3a /out.txt");
int a;
while ((a = de.read()) != -1)
{
output.write(a);
}
}
finally
{
if (de!=null)
de.close();
if (output!=null)
output.close();
}
}
}
int value = super.read();
int xor = value^128; // exclusive OR to decrypt
return xor;
In the above you do not check for the special value of -1 returned from super.read(), which you must push through transparently. Without that you'll never receive -1 in your while loop and the program will not terminate normally. The code as below should fix that issue:
int value = super.read();
return value == -1? value : value^128;
Well, I think you should ask in your Overriden method, wether super.read() is -1, too. Because if super.read() is -1, and you xor it with 128, it will not be -1 any longer, so Decrypt.read() wont be -1.
Edit: Ok, I wasn't fast enough!
Two quick corrections:
The output filename should not have a space in it
You listed no restrictions on data in your input file, so I suggest you use the "read data into a byte array" method (just in case a "-1" byte value is legitimate data in the input. Your particular text input is probably ok, but think of problems like these and solve the most inclusive problem you can still simply.
byte[] dataBuffer = new byte[1000];
int bytesRead;
bytesRead = de.read(dataBuffer);
while (bytesRead != -1 ) [
// decrypt each byte
// write the decrypted bytes
bytesRead = de.read(dataBuffer);
}
class Overload
{
public int Add(int a, int b)
{
Console.WriteLine("Int method with Two params executed");
return a + b;
}
public int Add(int a, int b, int c)
{
Console.WriteLine("Int method with three params executed");
return a + b + c;
}
public double Add(double a, double b)
{
Console.WriteLine("double method with Two params executed");
return a + b;
}
}
//class Derived : Overload //over riding//
//{
// public int Add(int a, int b)
// {
// return a + b;
// }
//}
}

actual code in static method or instance method

I'm writing a small library.
public class MyClass {
public static String doSomethingWithString(final String s) {
new MyClass().doSomething(s);
}
public String doSomething(final String s) {
return null;
}
}
Or I can do like this.
public class MyClass {
public static String doSomethingWithString(final String s) {
return null;
}
public String doSomething(final String s) {
return doSomethingWithString(s);
}
}
Which style is preferable? Are they same?
UPDATE
Thank you for comments and answers.
Here are two classes.
public class IdEncoder {
private static String block(final long decoded) {
final StringBuilder builder = new StringBuilder(Long.toString(decoded));
builder.append(Integer.toString(
ThreadLocalRandom.current().nextInt(9) + 1)); // 1-9
builder.append(Integer.toString(
ThreadLocalRandom.current().nextInt(9) + 1)); // 1-9
builder.reverse();
return Long.toString(
Long.parseLong(builder.toString()), Character.MAX_RADIX);
}
public static String encodeLong(final long decoded) {
return block(decoded >>> 0x20) + "-" + block(decoded & 0xFFFFFFFFL);
}
public String encode(final long decoded) {
return encodeLong(decoded);
}
}
And another style.
public class IdDecoder {
public static long decodeLong(final String encoded) {
return new IdDecoder().decode(encoded);
}
public long decode(final String encoded) {
final int index = encoded.indexOf('-');
if (index == -1) {
throw new IllegalArgumentException("wrong encoded: " + encoded);
}
return (block(encoded.substring(0, index)) << 32)
| (block(encoded.substring(index + 1)));
}
private long block(final String encoded) {
final StringBuilder builder = new StringBuilder(
Long.toString(Long.parseLong(encoded, Character.MAX_RADIX)));
builder.reverse();
builder.deleteCharAt(builder.length() - 1);
builder.deleteCharAt(builder.length() - 1);
return Long.parseLong(builder.toString());
}
}
If you are just picking between these 2 options, take the second one.
The reason is the first requires you to allocate a new dummy object on the heap just to call a method. If there is truly no other difference, don't waste the time and space and just call the static method from the class.
The second is more akin to a static Utility function, which are a fine coding practice.
When writing a library, ease of use dramatically trumps general best practices. Your method should be static if it doesn't make sense for a user to instantiate something in order to access it. However often it is actually much cleaner and more powerful for a method to be part of an object, because it allows the user (as well as the library writer) to override it in child classes.
In a sense, you aren't actually asking a programming question, but a UX question. Ask yourself how your users would best benefit from accessing your code, and implement it that way. As a good benchmark, look at the Guava API; it consists of many static utility classes, but just as many classes and interfaces designed to be easily extended. Do what you think is best.

Java how common is extending/wrapping built-in classes

I'm new to the Java language and I've tried to write my first relatively complex program. After I wrote a few classes I've realized that I barely use built-in classes (like BigInteger, MessageDigest, ByteBuffer) directly because they don't totally fit my needs. Instead I write my own class and inside the class I use the built-in class as an attribute.
Example:
public class SHA1 {
public static final int SHA_DIGEST_LENGTH = 20;
private MessageDigest md;
public SHA1() {
try {
md = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
public void update(byte[] data) {
md.update(data);
}
public void update(BigNumber bn) {
md.update(bn.asByteArray());
}
public void update(String data) {
md.update(data.getBytes());
}
public byte[] digest() {
return md.digest();
}
}
With the following simple class I don't have to use try catch when using SHA1, I can put my custom BigNumber class as parameter and I can also put String as parameter to update function.
The following BigNumber class contains all of the functions what I need and exactly how I need them.
public class BigNumber {
private BigInteger m_bn;
public BigNumber() {
m_bn = new BigInteger("0");
}
public BigNumber(BigInteger bn) {
m_bn = bn;
}
public BigNumber(String hex) {
setHexStr(hex);
}
//reversed no minsize
public byte[] asByteArray() {
return asByteArray(0, true);
}
//reversed with minsize
public byte[] asByteArray(int minSize) {
return asByteArray(minSize, true);
}
public byte[] asByteArray(int minSize, boolean rev) {
byte[] mag = m_bn.toByteArray();
//delete sign bit
//there is always a sign bit! so if bitNum % 8 is zero then
//the sign bit created a new byte (0th)
if(getNumBits() % 8 == 0) {
byte[] tmp = new byte[mag.length-1];
System.arraycopy(mag, 1, tmp, 0, mag.length-1);
mag = tmp;
}
//extend the byte array if needed
int byteSize = (minSize >= getNumBytes()) ? minSize : getNumBytes();
byte[] tmp = new byte[byteSize];
//if tmp's length smaller then byteSize then we keep 0x00-s from left
System.arraycopy(mag, 0, tmp, byteSize-mag.length, mag.length);
if(rev) ByteManip.reverse(tmp);
return tmp;
}
public String asHexStr() {
return ByteManip.byteArrayToHexStr(asByteArray(0, false));
}
public void setHexStr(String hex) {
m_bn = new BigInteger(hex, 16);
}
public void setBinary(byte[] data) {
//reverse = true
ByteManip.reverse(data);
//set as hex (binary set has some bug with the sign bit...)
m_bn = new BigInteger(ByteManip.byteArrayToHexStr(data), 16);
}
public void setRand(int byteSize) {
byte[] tmp = new byte[byteSize];
new Random().nextBytes(tmp);
//reversing byte order, but it doesn't really matter since it is a random
//number
setBinary(tmp);
}
public int getNumBytes() {
return (m_bn.bitLength() % 8 == 0) ? (m_bn.bitLength() / 8) : (m_bn.bitLength() / 8 + 1);
}
public int getNumBits() {
return m_bn.bitLength();
}
public boolean isZero() {
return m_bn.equals(BigInteger.ZERO);
}
//operations
public BigNumber modExp(BigNumber exp, BigNumber mod) {
return new BigNumber(m_bn.modPow(exp.m_bn, mod.m_bn));
}
public BigNumber mod(BigNumber m) {
return new BigNumber(m_bn.mod(m.m_bn));
}
public BigNumber add(BigNumber bn) {
return new BigNumber(m_bn.add(bn.m_bn));
}
public BigNumber subtract(BigNumber bn) {
return new BigNumber(m_bn.subtract(bn.m_bn));
}
public BigNumber multiply(BigNumber bn) {
return new BigNumber(m_bn.multiply(bn.m_bn));
}
}
My question is that how common in Java language to use these kind of classes instead of the built-in classes? Does it make my code unreadable for other programmers (compared to implementing everything with built-in classes)?
I've read that new C++ programmers desperately trying to write codes they used to write in C therefore the benefits of C++ remains hidden for them.
I'm afraid I do something like that in Java: trying to implement everything on my own instead of using the build-in classes directly.
Is this happening (for example in the BigNumber class)?
Thank you for your opinions!
I normally write a utility class which will support me to handle logics. Such as
public class CommonUtil{
public byte[] asByteArray(int minSize)
{
return "something".getBytes();
}
// add more utility methods
}
Wrapping a class makes sense when you add some value by doing so. If you are adding small functionality it can be worth using a Utility class instead of wrapping an existing one.
I think that if you do not have a very good reason for implementing the same functionality again you should not probably do it. Here are several reasons:
Built-in classes are used by a lot of people around the world and therefore there are less bugs than in your code
Users that are experienced in Java will be better in using standard classes than your classes and they will need less time to understand your code and write something new in your project
Built-in classes have good documentations and therefore it is much easier to use them
You are wasting your time by implementing something that was implemented and tested by Java professionals. It is better to concentrate on your own project
If you are writing a long-term project you will need to support all your classes. Oracle is already supporting built-in classes. Let them do their job!
The last but not the least. Are you sure that you know more about the problem than an author of a built-in class? Only if the answer is yes, consider writing your own implementation. Even implementation of daily used classes, such as collections or time-related classes can be tricky.
You're not gaining anything by making a class that does this stuff for you. If you're going to be doing certain operations a lot, then you might want to create a new class with static methods that do these important things for you.
Let's assume that you want a sorted array at all times. You could make a new class, let's call it SortedArray. You could sort it whenever you add something in, but why would you do that when you can just add in everything and then call the (utility) method Arrays.sort?
For common operations, take a look at Java's Arrays class - if you are doing something often, that's something you make a method for, like searching and sorting. In your case, you might make a utility method that turns the BigInteger into a byte array for you. You shouldn't be just making your own, 'better' version that does what you want it. When other people look at your code, when you use standard objects it's much better, instead of having custom objects that don't really do anything.
As #Shark commented, there's no point in creating your own solutions, because:
They take time to create
They become not as flexible
However, you can extend classes (it's recommended) or use 3rd party frameworks that might suit you better.

Store and retrieve a float[] to/from Cassandra using Hector

I have the following Cassandra schema:
ColumnFamily: FloatArrays {
SCKey: SuperColumn Key (Integer) {
Key: FloatArray (float[]) {
field (String): value (String)
}
}
}
In order to insert data that adheres to this schema I created the following template in Hector:
template = new ThriftSuperCfTemplate<Integer, FloatArray, String>(
keyspace, "FloatArrays", IntegerSerializer.get(),
FloatArraySerializer.get(), StringSerializer.get());
To (de-)serialize the FloatArray I created (and unit tested) a custom Serializer:
public class FloatArraySerializer extends AbstractSerializer<FloatArray> {
private static final FloatArraySerializer instance =
new FloatArraySerializer();
public static FloatArraySerializer get() {
return instance;
}
#Override
public FloatArray fromByteBuffer(ByteBuffer buffer) {
buffer.rewind();
FloatBuffer floatBuf = buffer.asFloatBuffer();
float[] floats = new float[floatBuf.limit()];
if (floatBuf.hasArray()) {
floats = floatBuf.array();
} else {
floatBuf.get(floats, 0, floatBuf.limit());
}
return new FloatArray(floats);
}
#Override
public ByteBuffer toByteBuffer(FloatArray theArray) {
float[] floats = theArray.getFloats();
ByteBuffer byteBuf = ByteBuffer.allocate(4 * descriptor.length);
FloatBuffer floatBuf = byteBuf.asFloatBuffer();
floatBuf.put(floats);
byteBuf.rewind();
return byteBuf;
}
}
Now comes the tricky bit. Storing and then retrieving an array of floats does not return the same result. In fact, the number of elements in the array isn't even the same. The code I use to retrieve the result is shown below:
SuperCfResult<Integer, FloatArray, String> result =
template.querySuperColumns(hash);
for (FloatArray floatArray: result.getSuperColumns()) {
// Do something with the FloatArrays
}
Do I make a conceptual mistake here since I'm quite new to Cassandra/Hector? Right now I don't even have a clue on where it goes wrong. The Serializer seems to be ok. Can you please provide me with some pointers to continue my search? Many thanks!
I think you're on the right track. When I work with ByteBuffers I find I sometimes need the statement:
import org.apache.thrift.TBaseHelper;
...
ByteBuffer aCorrectedByteBuffer = TBaseHelper.rightSize(theByteBufferIWasGiven);
The byte buffer sometimes has its value stored as an offset into its buffer but the Serializers seem to assume that the byte buffer's value starts at offset 0. The TBaseHelper corrects the offsets as best I can tell so the assumptions in the Serializer implementation are made valid.
The difference in lengths of the array in and array out are the result of starting at the wrong offset. The first byte or two of the serialized value contain the length of the array.
Thanks to Chris I solved the problem. The Serializer now looks like this:
public class FloatArraySerializer extends AbstractSerializer<FloatArray> {
private static final FloatArraySerializer instance =
new FloatArraySerializer();
public static FloatArraySerializer get() {
return instance;
}
#Override
public FloatArray fromByteBuffer(ByteBuffer buffer) {
ByteBuffer rightBuffer = TBaseHelper.rightSize(buffer); // This does the trick
FloatBuffer floatBuf = rightBuffer.asFloatBuffer();
float[] floats = new float[floatBuf.limit()];
if (floatBuf.hasArray()) {
floats = floatBuf.array();
} else {
floatBuf.get(floats, 0, floatBuf.limit());
}
return new FloatArray(floats);
}
#Override
public ByteBuffer toByteBuffer(FloatArray theArray) {
float[] floats = theArray.getDescriptor();
ByteBuffer byteBuf = ByteBuffer.allocate(4 * descriptor.length);
FloatBuffer floatBuf = byteBuf.asFloatBuffer();
floatBuf.put(floats);
byteBuf.rewind();
return byteBuf;
}
}

Categories