I need to create a string of hex values. Now, i've got something like this.
String address = "5a f2 ff 1f";
But when getting this address into bytes:
byte[] bytes= address.getBytes();
It gets me each letter and space as a byte, instead of getting each 2 chars as a byte ang leaving the spaces. So...
How can i declare this?
private String CalcChecksum (String message) {
/**Get string's bytes*/
message = message.replaceAll("\\s","");
byte[] bytes = toByteArray(message);
byte b_checksum = 0;
for (int byte_index = 0; byte_index < byte_calc.length; byte_index++) {
b_checksum += byte_calc[byte_index];
}
int d_checksum = b_checksum; //Convert byte to int(2 byte)
int c2_checksum = 256 - d_checksum;
String hexString = Integer.toHexString(c2_checksum);
return hexString;
}
String address = "5a f2 ff 1f";
byte[] bytes = DatatypeConverter.parseHexBinary(address.replaceAll("\\s","")).getBytes();
As stated you're using hex, which you cannot use .getBytes() in the way you are trying to!
You need to specify that your string contains hex values. And in the solution below you need to remove all whitespaces from the string before converting it:
import javax.xml.bind.DatatypeConverter;
class HexStringToByteArray {
public static void main(String[] args) {
String address = "5A F2 FF 1F";
address = address.replaceAll("\\s","");
System.out.println(address);
byte[] bytes = toByteArray(address);
for( byte b: bytes ) {
System.out.println(b);
}
String string_again = toHexString(bytes);
System.out.println(string_again);
}
public static String toHexString(byte[] array) {
return DatatypeConverter.printHexBinary(array);
}
public static byte[] toByteArray(String s) {
return DatatypeConverter.parseHexBinary(s);
}
}
This will print (note that bytes as signed):
5AF2FF1F // Original address
90 // 5A
-14 // F2
-1 // FF
31 // 1F
5AF2FF1F // address retrieved from byte array
Related
In anroid emoji convert to unicode time alwasy get output U+5c but we give emoji string "\uD83D\uDE21" this method it's working
String a = emojiconEditText.getText().toString().trim();
String text = new String(
StringEscapeUtils.escapeJava(a).getBytes(),
StandardCharsets.UTF_8
);
int codepoint = text.codePointAt(0);
String yourUnicode = "U+"+Integer.toHexString(codepoint);
You can encode/decode emojis to the following unicode UTF-8, UTF-16 and U+<hex> using the below:
try {
//I am assuming you are getting unicode from an inputbox
String emoji = emojiconEditText.getText().toString().trim();
//I am also assuming you are getting emoji in hexadecimal form `U+<hexdigits>`
String unicodeHexEmoji = "U+";
StringBuilder sb = new StringBuilder();
//Firstly you want to encode emojis to unicode types by converting to byte array
byte[] utf8Bytes = emoji.getBytes("UTF-8"); // "\\uf0\\u9f\\u98\\u80"
byte[] utf16Bytes = emoji.getBytes("UTF-16"); // "\\ud83d\\ude00"
//convert emoji to hex
for (byte b : utf16Bytes ) {
sb.append(String.format("%02x", b));
}
//we are converting our current emoji to hex just for the purpose of this example
unicodeHexEmoji += sb; //yields "U+feffd83dde21";
byte[] utfHexBytes = getByteFromHex(unicodeHexEmoji.replace("U+","")); // "\\ud83d\\ude00"
//NB: we removed "U+" because its only a prefix denoting that the string is a <hex>
//Decoding our unicodes back to emoji string
String emojiUTF_8 = new String(utf8Bytes,"UTF-8");
String emojiUTF_16 = new String(utf16Bytes,"UTF-16");
String emojiUTF_hex = new String(utfHexBytes,"UTF-16");
Log.d("Tag", "emojiUTF_8 : "+ emojiUTF_8);
Log.d("Tag", "emojiUTF_16 : "+ emojiUTF_16)
Log.d("Tag", "emojiUTF_hex : "+ emojiUTF_hex)
//output
//emojiUTF-8 : 😀
//emojiUTF-16 : 😀
//emojiUTF-hex : 😡
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
...
public byte[] getByteFromHex(String hexString){
//To convert hex string to byte array, you need to first get the length
//of the given string and include it while creating a new byte array.
byte[] val = new byte[hexString.length() / 2];
for (int i = 0; i < val.length; i++) {
int index = i * 2;
int j = Integer.parseInt(hexString.substring(index, index + 2), 16);
val[i] = (byte) j;
}
return val;
}
I am trying to "chunk" up the bytes of an image. This will allow me to upload a large image in bytes array. I have the image currently stored as one large byte[]. I would like to split the byte array into byte[]'s with a each exactly of 5 MB.
public static byte[][] divideArray(byte[] source, int chunksize) {
byte[][] ret = new byte[(int) Math.ceil(source.length / (double) chunksize)][chunksize];
int start = 0;
int parts = 0;
for (int i = 0; i < ret.length; i++) {
if (start + chunksize > source.length) {
System.arraycopy(source, start, ret[i], 0, source.length - start);
} else {
System.arraycopy(source, start, ret[i], 0, chunksize);
}
start += chunksize;
parts++;
}
Log.d("Parts", parts + "");
return ret;
}
Call It by
divideArray(common.fullyReadFileToBytes(wallpaperDirectory), 5 * 1024 * 1024)
You can use copyOfRange for that:
T[] copyOfRange (T[] original,
int from,
int to);
In your case, something like this:
Byte[] copyOfRange (original,
0,
5000000);
make sure you calculate the offset:
class test {
// this is just for dummy data
public static byte[] getTestBytes() {
byte[] largeByteArray = new byte[50_000_000];
for(int i = 0; i < 50_000_000; i ++) {
largeByteArray[i] = 0;
}
return largeByteArray;
}
// this method splits your byte array into small portions
// and returns a list with those portions
public static List<byte[]> byteToPortions(byte[] largeByteArray) {
// create a list to keep the portions
List<byte[]> byteArrayPortions = new ArrayList<>();
// 5mb is about 5.000.000 bytes
int sizePerPortion = 5_000_000;
int offset = 0;
// split the array
while(offset < largeByteArray.length) {
// into 5 mb portions
byte[] portion = Arrays.copyOfRange(largeByteArray, offset, offset + sizePerPortion);
// update the offset to increment the copied area
offset += sizePerPortion;
// add the byte array portions to the list
byteArrayPortions.add(portion);
}
// return portions
return byteArrayPortions;
}
// create your byte array, and split it to portions
public static void main(String[] args) {
byte[] largeByteArray = getTestBytes();
List<byte[]> portions = byteToPortions(largeByteArray);
// work with your portions
}
}
Something cool: the value to does not have to be an index inside the array, it checks that for you without erroring and copies a subset that is valid to the intended array.
These answers work fine but has optimization issues. They allocate extra space of the whole chunk size irrespective of the only actual bytes of memory the array needs to allocate for copying the data.
Here is the solution for this problem.
private fun divideDataIntoChunks(source: ByteArray, chunkSize: Int): kotlin.collections.ArrayList<ByteArray> {
val result: ArrayList<ByteArray> = ArrayList()
if (chunkSize <= 0) {
result.add(source)
} else {
for (chunk in source.indices step chunkSize) {
result.add(source.copyOfRange(chunk, min(chunk+chunkSize,source.size)))
}
}
return result
}
I work with my custom USB Device. I get from it bytes array. I want to display this array as hex string so I convert it firstly into Long like this :
byte[] receivedTag = connector.receive(512);
String tag = null;
if (receivedTag != null) {
long tagValue = ByteBuffer.wrap(receivedTag).getLong();
Next I want to convert it into hex String :
tag = Long.toHexString(tagValue);
however I've got problem here. Received Tag has something about 400 bytes (I've checked it on debug) , but when I convert it , tag is only 16 chars long(8 bytes, there are correct). Why is that ?
public static String bytesToHex(byte[] in) {
final StringBuilder builder = new StringBuilder();
for(byte b : in) {
builder.append(String.format("%02x", b));
}
return builder.toString();
}
// consider using this
There are example for Java (but using java.awt sth) and C#; it seems that getting a name from TTF file should be no pain. But unfortunately it is not. Please help.
Please using class:
class TTFAnalyzer
{
// This function parses the TTF file and returns the font name specified in the file
public String getTtfFontName( String fontFilename )
{
try
{
// Parses the TTF file format.
// See http://developer.apple.com/fonts/ttrefman/rm06/Chap6.html
m_file = new RandomAccessFile( fontFilename, "r" );
// Read the version first
int version = readDword();
// The version must be either 'true' (0x74727565) or 0x00010000
if ( version != 0x74727565 && version != 0x00010000 )
return null;
// The TTF file consist of several sections called "tables", and we need to know how many of them are there.
int numTables = readWord();
// Skip the rest in the header
readWord(); // skip searchRange
readWord(); // skip entrySelector
readWord(); // skip rangeShift
// Now we can read the tables
for ( int i = 0; i < numTables; i++ )
{
// Read the table entry
int tag = readDword();
readDword(); // skip checksum
int offset = readDword();
int length = readDword();
// Now here' the trick. 'name' field actually contains the textual string name.
// So the 'name' string in characters equals to 0x6E616D65
if ( tag == 0x6E616D65 )
{
// Here's the name section. Read it completely into the allocated buffer
byte[] table = new byte[ length ];
m_file.seek( offset );
read( table );
// This is also a table. See http://developer.apple.com/fonts/ttrefman/rm06/Chap6name.html
// According to Table 36, the total number of table records is stored in the second word, at the offset 2.
// Getting the count and string offset - remembering it's big endian.
int count = getWord( table, 2 );
int string_offset = getWord( table, 4 );
// Record starts from offset 6
for ( int record = 0; record < count; record++ )
{
// Table 37 tells us that each record is 6 words -> 12 bytes, and that the nameID is 4th word so its offset is 6.
// We also need to account for the first 6 bytes of the header above (Table 36), so...
int nameid_offset = record * 12 + 6;
int platformID = getWord( table, nameid_offset );
int nameid_value = getWord( table, nameid_offset + 6 );
// Table 42 lists the valid name Identifiers. We're interested in 4 but not in Unicode encoding (for simplicity).
// The encoding is stored as PlatformID and we're interested in Mac encoding
if ( nameid_value == 4 && platformID == 1 )
{
// We need the string offset and length, which are the word 6 and 5 respectively
int name_length = getWord( table, nameid_offset + 8 );
int name_offset = getWord( table, nameid_offset + 10 );
// The real name string offset is calculated by adding the string_offset
name_offset = name_offset + string_offset;
// Make sure it is inside the array
if ( name_offset >= 0 && name_offset + name_length < table.length )
return new String( table, name_offset, name_length );
}
}
}
}
return null;
}
catch (FileNotFoundException e)
{
// Permissions?
return null;
}
catch (IOException e)
{
// Most likely a corrupted font file
return null;
}
}
// Font file; must be seekable
private RandomAccessFile m_file = null;
// Helper I/O functions
private int readByte() throws IOException
{
return m_file.read() & 0xFF;
}
private int readWord() throws IOException
{
int b1 = readByte();
int b2 = readByte();
return b1 << 8 | b2;
}
private int readDword() throws IOException
{
int b1 = readByte();
int b2 = readByte();
int b3 = readByte();
int b4 = readByte();
return b1 << 24 | b2 << 16 | b3 << 8 | b4;
}
private void read( byte [] array ) throws IOException
{
if ( m_file.read( array ) != array.length )
throw new IOException();
}
// Helper
private int getWord( byte [] array, int offset )
{
int b1 = array[ offset ] & 0xFF;
int b2 = array[ offset + 1 ] & 0xFF;
return b1 << 8 | b2;
}
}
codes from http://www.ulduzsoft.com/2012/01/enumerating-the-fonts-on-android-platform/
note that it does not work for all ttf files.
I used this code for converts hex to binary but works only with 8 bits.How can i expand to 16bits?For example i want to convert FFFF to 1111111111111111 ....also i need to fill the zero 0...
void HexToBinary1(String Hex) {
int i = Integer.parseInt(Hex, 16);//16 bits
String Bin = Integer.toBinaryString(i);//Converts int to binary
String Bin2="";
if(Bin.length()==8){Bin2=Bin;}
if(Bin.length()==7){Bin2="0"+Bin;}
if(Bin.length()==6){Bin2="00"+Bin;}
if(Bin.length()==5){Bin2="000"+Bin;}
if(Bin.length()==4){Bin2="0000"+Bin;}
if(Bin.length()==3){Bin2="00000"+Bin;}
if(Bin.length()==2){Bin2="000000"+Bin;}
if(Bin.length()==1){Bin2="0000000"+Bin;}
text1.setText(Bin2);//Shows binary
}
use
String HexToBinary(String Hex) {
String bin = new BigInteger(Hex, 16).toString(2);
int inb = Integer.parseInt(bin);
bin = String.format(Locale.getDefault(),"%08d", inb);
return bin;
}
It will return binary string as 8 digit format.
you need to tell Java that the int is in hex, like this:
String HexToBinary(String Hex) {
int i = Integer.parseInt(Hex, 16);
String Bin = Integer.toBinaryString(i);
return Bin;
}
Try this
public static String getBits(double value)
{
//get bit-string of double
String printString = (Long.toBinaryString(Double.doubleToRawLongBits(value)));
//add leading zeros if bitstring is shorter than 64 bits
while (printString.length() < 64)
printString = "0" + printString;
//format string by adding byte padding
StringBuilder bitwise = new StringBuilder();
for(int i = 0; i<8; i++)
bitwise.append(printString.substring(i*8, (i+1)*8)+" ");
return bitwise.toString();
}
Feel free to further adapt for ints and add in the feature of parsing a HEX string.