Hex to Decimal Conversion Error - android

I have a byte array -
byte[] byteArr = new byte[] { (byte)0x00 , (byte)0xF0 , (byte)0x03 };
I am just getting each one,
Integer byte1 = Integer.valueOf(byteArr[0]);
Integer byte2 = Integer.valueOf(byteArr[1]);
Integer byte3 = Integer.valueOf(byteArr[2]);
String pgnString = byte1.toString() + byte2.toString() + byte3.toString();
And my output is: 0-163
But I can see the correct output should be: 61443
Link--- http://www.binaryhexconverter.com/hex-to-decimal-converter

Thats because bytes are signed. (byte)0xF0 is actually the same as (byte)-16.
To convert as unsigned quantity you can mask the lower 8 bits:
int byte1 = byteArr[0] & 0xff;
int byte2 = byteArr[1] & 0xff;
int byte3 = byteArr[2] & 0xff;
String pgnString = String.valueOf(byte1 * 0x10000 + byte2 * 0x100 + byte3);

If you don't want to go through them one at a time, you can use ByteBuffer to convert to another base.
byte[] byteArr = new byte[] { (byte)0x00 , (byte)0x00 , (byte)0xF0 , (byte)0x03 };
int value = ByteBuffer.wrap(byteArr).getInt();
// value = 61443
Note: the byte[] must have a length of 4 (or call getInt() for each 4 byte part).

Related

Android spinner selected position with byte convertion logic

I have a piece of code obtain from a source which I need to understand regarding byte conversion and use from android spinner -
Edit: ---------------------------------------
So I was playing around with this binary operations and I don't know how these statements decide the output-
A. How the "and" plays role here?
B. Why do we need to convet it to int using toInt()? The output was same even without using it.
var biteData = ByteArray(2)
biteData[0] = (1 and 0xFF)
biteData[1] = (0 and 0xFF)
testByteToInt(biteData)
testByteToInt1(biteData)
testByteToInt2(biteData)
testByteToInt3(biteData)
fun testByteToInt(bytes:ByteArray){
val item_one:Byte = (bytes[0] + 0xFF and 0x01).toByte()
var one_item = item_one.toInt()
print(one_item)
}
// output: 0
fun testByteToInt1(bytes:ByteArray){
val item_one:Byte = (bytes[0] + 0x01 and 0xFF).toByte()
var one_item = item_one.toInt()
print(one_item)
}
// output: 2
fun testByteToInt2(bytes:ByteArray){
val item_one:Byte = ((bytes[0] + 0xFF) and 0x01).toByte()
var one_item = item_one.toInt()
print(one_item)
}
// output: 0
fun testByteToInt3(bytes:ByteArray){
val item_one:Byte = ((bytes[0] + 0x01) and 0xFF).toByte()
var one_item = item_one.toInt()
print(one_item)
}
// output: 2
class MyClass{
public byte[] getSpinnerVal(View view){
byte[] bytes = new byte[2];
Spinner spinner = null;
spinner = (Spinner) view.findViewById(R.id.spinner_item_one);
byte[0] = (byte) (spinner.getSelectedItemPosition() & 0xFF)
spinner = (Spinner) view.findViewById(R.id.spinner_item_two);
byte[1] = (byte) (spinner.getSelectedItemPosition() & 0xFF)
}
void setSpinnerVal(byte val_one,byte val_two,View view){
Spinner spinner = null;
spinner = (Spinner) view.findViewById(R.id.spinner_item_one);
spinner.setSelection((byte) ((val_one - 0x01) & 0xFF));
spinner = (Spinner) view.findViewById(R.id.spinner_item_two);
spinner.setSelection((byte) ((val_two - 0x01) & 0xFF));
}
}
void onCreate(){
MyClass mclass = new MyClass()
byte[] bytes = mclass.getSpinnerVal(spinner_view);
byte item_one = (byte) ((bytes[0] + 0x01) & 0xFF);
byte item_two = (byte) ((bytes[1] + 0x01) & 0xFF);
mclass.setSpinnerVal(some_byte_val_one, some_byte_val_two, spinner_view);
}
What I am confused about is this line where selected value gets increment by one
byte item_one = (byte) ((bytes[0] + 0x01) & 0xFF);
All it does is simple byte addition, A byte is 8 bits, so the upper bound with all one's would be 256(1111 1111) which is represented as 0xFF in hex, same goes for 1 in hex 0x01
byte item_two = (byte) ((bytes[1] + 0x01) & 0xFF);
//say byte[1] = 1, whose binary representation is 0000 0001
//0x01 = 0000 0001
//Now if you do (bytes[1] + 0x01)
// 0000 0001 //byte[1] value, which is position 1
// +0000 0001 // incremental value of 1
// 0000 0010 // which equals to 2
// and by doing [& 0xFF] is to limit the upper bound.

How to retrieve font name from TTF file for Android

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.

What the value mean convert from string to Hex for BLE?

I am developing BLE in Android.
And I try to send string value to BLE device
It seem the string need to convert to byte before send to BLE device.
I found some code like the following , the code seems can convert the string value to byte.
private byte[] parseHex(String hexString) {
hexString = hexString.replaceAll("\\s", "").toUpperCase();
String filtered = new String();
for(int i = 0; i != hexString.length(); ++i) {
if (hexVal(hexString.charAt(i)) != -1)
filtered += hexString.charAt(i);
}
if (filtered.length() % 2 != 0) {
char last = filtered.charAt(filtered.length() - 1);
filtered = filtered.substring(0, filtered.length() - 1) + '0' + last;
}
return hexStringToByteArray(filtered);
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
private int hexVal(char ch) {
return Character.digit(ch, 16);
}
I call the above function before send the string to the BLE device like the following code.
byte[] value = parseHex(text);
mCharacteristic.setValue(value);
mBluetoothGatt.writeCharacteristic(mCharacteristic);
The BLE device will show the value which I have send to it. But the value is strange and I did not under stand what it mean.
The value what I send and the value show from BLE device are like the following.
Send BLE Show
1 1
2 2
9 9
10 16
11 17
20 32
30 48
40 64
70 112
90 144
99 153
100 16
I did not understand what the value mean show on BLE device...
Does someone help me ?
You are sending the hex values, which is a base 16 system, but your BLE Show values are in decimal.
Therefore sending 10 in hex is 1*16+0*1=16 in decimal. Similarly, 99 is 9*16+9*1=153 in decimal

getBytes doesn't get the right bytes amount

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

UTRAN Cell Identity returned by getCid()

In UMTS I get a large number returned by getCid() (larger than the allowed value). Is this the UTRAN Cell Identity (UC-ID)?
UC-Id = RNC-Id + C-Id
Does someone knows that? How to get the C-Id from the UC-Id?
Thanks and Best,
Benny
The RNC id is the first 2 bytes of the 4 byte Cell Id (3GPP 25.401, section 6.1.5), if the network type is UMTS/HSxPA/HSPA+." I have access to an operator network and I checked in the system and it's true and correct.
Based on that please see my code how you can easily get RNCID + CID:Convert CID to ByteArray:
public static byte[] convertByteArray__p(int p_int){
byte[] l_byte_array = new byte[4];
int MASK_c = 0xFF;
for (short i=0; i<=3; i++){
l_byte_array[i] = (byte) ((p_int >> (8*i)) & MASK_c);
}
return l_byte_array;
}
Get the RNCID and CID:
public int getRNCID_or_CID__p(byte[] p_bytes, short p_which){
int MASK_c = 0xFF;
int l_result = 0;
if (p_which == Constants.CID_C) {
l_result = p_bytes[0] & MASK_c ;
l_result = l_result + ((p_bytes[1] & MASK_c ) << 8);
} else if (p_which == Constants.RNCID_C){
l_result = p_bytes[2] & MASK_c ;
l_result = l_result + ((p_bytes[3] & MASK_c ) << 8);
} else {
g_FileHandler.putLog__p('E', "getRNCID_or_CID__p invalid parameter");
}
return l_result;
}
Than you can easily call like this:
byte[] l_byte_array = new byte[4];
l_byte_array = convertByteArray__p(l_cid);
int l_RNC_ID = getRNCID_or_CID__p(l_byte_array,Constants.RNCID_C);
int l_real_CID = getRNCID_or_CID__p(l_byte_array,Constants.CID_C);
Constants RNCID_C(1) and CID_C(2) are only contants just for me to seperate which parameter will be passed through.
If CID is > 65536, it's not actually the cell-ID, but a linear combination of the real cell-ID and RNC-ID:
UTRAN_CELL_ID = RNCID x 65536 + CellID
To extract the cellID, use the modulo operation:
CellID = UTRAN_CELL_ID % 65536
To extract the RNCID, get the integer part:
RNCID = UTRAN_CELL_ID / 65536
try
(cell id % 65536)
it worked for me.
This is more simple than this. Cell ID is in the low register of the value getCid() returns, the RNC is the high register of this value (http://developer.android.com/reference/android/telephony/gsm/GsmCellLocation.html#getCid()).
So:
getCid() == RNC << 16 | CID
CID = getCid() & 0xffff
RNC = (getCid() >> 16) & 0xffff

Categories

Resources