currently I am playing around with SNMP (snmp4j and SimpleSnmpClient) to get some information from a network device.
This works as long as the result is a "normal" value like an integer.
If the value is an OctetString like
44:00:4f:00:30:00:4a:00:47:00:20:00:4d:00:49:00:58:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
labelled as Unicode I can decode it as well but before I have to replace the ":"
hex2AscII(sysDescr.replace(":", "")
with this method
static String hex2AscII(String hex) {
StringBuilder ascii = new StringBuilder();
for (int i = 0; i < hex.length(); i+=2) {
String str = hex.substring(i, i+2);
ascii.append((char)Integer.parseInt(str, 16));
}
return ascii.toString();
}
Now I want to get the value for a Voltage, the MiB says
OCTECT STRING (SIZE(4))
It should be changed to float format
OK I do the SNMP query and get as result:
e6:d9:4c:41
witch should be a voltage around 12.8 Volt
Now I try to convert it to Float
System.out.println("################# TestSection ################# ");
int hex = 0xE6D94C41;
f = Float.intBitsToFloat(hex);
System.out.println(f);
System.out.printf("%f", f);
and get
-5.1308008E23
e6d94c41
So what is wrong with my code ?
Here is the proper way of doing it in Java:
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class SnmpUtil{
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;
}
public static void main(String []args){
byte[] bytes = SnmpUtil.hexStringToByteArray("e6d94c41");
float f = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getFloat();
System.out.println(f);
}
}
Related
I need to convert string to hexademical byte array,my code is:
public static byte[] stringToHex(final String buf)
{
return DatatypeConverter.parseHexBinary(buf);
}
According to java doc to convert string to Hex DatatypeConverteruse the following implementation
public byte[] parseHexBinary(String s) {
final int len = s.length();
// "111" is not a valid hex encoding.
if (len % 2 != 0) {
throw new IllegalArgumentException("hexBinary needs to be even-length: " + s);
}
byte[] out = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
int h = hexToBin(s.charAt(i));
int l = hexToBin(s.charAt(i + 1));
if (h == -1 || l == -1) {
throw new IllegalArgumentException("contains illegal character for hexBinary: " + s);
}
out[i / 2] = (byte) (h * 16 + l);
}
return out;
}
It means that only strings with the even length is legal to be converted.But in php there is no such constraint
For example code in php:
echo pack("H*", "250922f67dcbc2b97184464a91e7f8f");
And in java
String hex = "250922f67dcbc2b97184464a91e7f8f";
System.out.println(stringToHex(hex));//my method that was described earlier
Why the following string is legal in php?
PHP just adds a final 0 in case the number of characters is odd.
Both of these
echo pack("H*", "48454C50");
echo pack("H*", "48454C5");
yield
HELP
I have some byte-int operations. But I cant figure out the problem.
First of all I have a hex data and I am holding it as an integer
public static final int hexData = 0xDFC10A;
And I am converting it to byte array with this function:
public static byte[] hexToByteArray(int hexNum)
{
ArrayList<Byte> byteBuffer = new ArrayList<>();
while (true)
{
byteBuffer.add(0, (byte) (hexNum % 256));
hexNum = hexNum / 256;
if (hexNum == 0) break;
}
byte[] data = new byte[byteBuffer.size()];
for (int i=0;i<byteBuffer.size();i++){
data[i] = byteBuffer.get(i).byteValue();
}
return data;
}
And I want to convert 3 byte array to integer back again how can I do that?
Or you can also suggest other converting functions like hex-to-3-bytes-array and 3-bytes-to-int thank you again.
UPDATE
In c# someone use below function but not working in java
public static int byte3ToInt(byte[] byte3){
int res = 0;
for (int i = 0; i < 3; i++)
{
res += res * 0xFF + byte3[i];
if (byte3[i] < 0x7F)
{
break;
}
}
return res;
}
This will give you the value:
(byte3[0] & 0xff) << 16 | (byte3[1] & 0xff) << 8 | (byte3[2] & 0xff)
This assumes, the byte array is 3 bytes long. If you need to convert also shorter arrays you can use a loop.
The conversion in the other direction (int to bytes) can be written with logical operations like this:
byte3[0] = (byte)(hexData >> 16);
byte3[1] = (byte)(hexData >> 8);
byte3[2] = (byte)(hexData);
You could use Java NIO's ByteBuffer:
byte[] bytes = ByteBuffer.allocate(4).putInt(hexNum).array();
And the other way round is possible too. Have a look at this.
As an example:
final byte[] array = new byte[] { 0x00, (byte) 0xdf, (byte) 0xc1, 0x0a };//you need 4 bytes to get an integer (padding with a 0 byte)
final int x = ByteBuffer.wrap(array).getInt();
// x contains the int 0x00dfc10a
If you want to do it similar to the C# code:
public static int byte3ToInt(final byte[] byte3) {
int res = 0;
for (int i = 0; i < 3; i++)
{
res *= 256;
if (byte3[i] < 0)
{
res += 256 + byte3[i]; //signed to unsigned conversion
} else
{
res += byte3[i];
}
}
return res;
}
to convert Integer to hex: integer.toHexString()
to convert hexString to Integer: Integer.parseInt("FF", 16);
Please help me on converting a hexstring to base64
here is the cede where I'm getting the exception
String hexString = "bf940165bcc3bca12321a5cc4c753220129337b48ad129d880f718d147a2cd1bfa79de92239ef1bc06c2f05886b0cd5d";
private static String ConvertHexStringToBase64(String hexString) {
System.out.println(hexString);
if ((hexString.length()) % 2 > 0)
throw new NumberFormatException("Input string was not in a correct format.");
byte[] buffer = new byte[hexString.length() / 2];
int i = 0;
while (i < hexString.length())
{
buffer[i / 2] = Byte.parseByte(hexString.substring(i, 2));
i += 2;
}
System.out.println("hexSring"+hexString+"afterconverttobase64"+Base64.encodeBase64String(buffer));
return Base64.encodeBase64String(buffer);
}
I'm getting an exception here::bf940165bcc3bca12321a5cc4c753220129337b48ad129d880f718d147a2cd1bfa79de92239ef1bc06c2f05886b0cd5d
Exception in thread "main" java.lang.NumberFormatException: For input string: "bf"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:449)
at java.lang.Byte.parseByte(Byte.java:151)
at java.lang.Byte.parseByte(Byte.java:108)
at com.motorola.gst.DecryptTest3.ConvertHexStringToBase64(DecryptTest3.java:38)
at com.motorola.gst.DecryptTest3.main(DecryptTest3.java:16)
First of all you have to specify the specify the radix(16 in your case) in the parseByte method to avoid the numberFormat exception :
buffer[i / 2] = Byte.parseByte(hexString.substring(i, 2),16);
However your code seems broken, take a look at the corrected one :
if ((hexString.length()) % 2 > 0)
throw new NumberFormatException("Input string was not in a correct format.");
int[] buffer = new int[hexString.length() / 2];
int i = 2;
while (i < hexString.length())
{
buffer[i / 2] = Integer.parseInt(hexString.substring(i, i + 2),16);
i += 2;
}
Your loop was wrong and you have to parse as Integer because you have some values inside your input string that overflow the byte capability ...
If you need byte you could cast the parsed int to byte in this way :
byte[] buffer = new byte[hexString.length() / 2];
int i = 2;
while (i < hexString.length())
{
buffer[i / 2] = (byte)Integer.parseInt(hexString.substring(i, i + 2),16);
i += 2;
}
Found a similar solution, thought it might be good to share:
public static string convertHexToBase64String(String hexString)
{
string base64 = "";
//--Important: remove "0x" groups from hexidecimal string--
hexString = hexString.Replace("0x", "");
byte[] buffer = new byte[hexString.Length / 2];
for (int i = 0; i < hexString.Length; i++)
{
try
{
buffer[i / 2] = Convert.ToByte(Convert.ToInt32(hexString.Substring(i, 2), 16));
}
catch (Exception ex) { }
i += 1;
}
base64 = Convert.ToBase64String(buffer);
return base64;
}
Hope it helps someone else.
I am having problems of conversion through string->byte->byte[]
What I have done so far:
double db = 1.00;
double ab = db*100;
int k = (int) ab;
String aa = String.format("%06d", k);
String first = aa.substring(0,2);``
String second = aa.substring(2,4);
String third = aa.substring(4,6);
String ff = "0x"+first;
String nn = "0x"+second;
String yy = "0x"+third;
I want to write those bytes to an byte[]. What I mean is:
byte[] bytes = new byte[]{(byte) 0x02, (byte) 0x68, (byte) 0x14,
(byte) 0x93, (byte) 0x01, ff,nn,yy};
in this order and casted with 0x's. Any help is greatly appriciated.
Regards,
Ali
You can use Byte.decode()
Decodes a String into a Byte. Accepts decimal, hexadecimal, and octal numbers given by the following grammar:
DecodableString:
Signopt DecimalNumeral
Signopt 0x HexDigits
Signopt 0X HexDigits
Signopt # HexDigits
Signopt 0 OctalDigits
Below code will print 10, 11 which is value of 0XA, 0XB
byte[] temp = new byte[2];
temp[0] = Byte.decode("0xA");
temp[1] = Byte.decode("0xB");
System.out.println(temp[0]);
System.out.println(temp[1]);
As I see, the main question here is how to convert a 2 char String representing a hexa number to a byte type. The Byte class has a static method parseByte(String s, int radix) that can parse a String to number using the radix you want (in this case, 16). Here is an example of how you can do the parsing and save the result in a byte array:
public static void main(String [] args){
System.out.println(Arrays.toString(getBytes("0001020F")));
}
public static byte[] getBytes(String str) {
byte [] result = new byte[str.length() / 2]; //assuming str has even number of chars...
for(int i = 0; i < result.length; i++){
int startIndex = i * 2;
result[i] = Byte.parseByte(str.substring(startIndex, startIndex + 2), 16);
}
return result;
}
I work with cellphones and deal with MEID numbers on a daily basis. So instead of searching online for a MEID (a hex number of length 14) to pseudo ESN (a hex number of length 8) calculator, I figured I can make my own program. The way to obtain a pESN from MEID is fairly simple in theory. For example, given MEID 0xA0000000002329, to make a pESN, SHA-1 needs to be applied to the MEID. SHA-1 on A0000000002329 gives e3be267a2cd5c861f3c7ea4224df829a3551f1ab. Take the last 6 hex numbers of this result, and append it to 0x80 - the result is 0x8051F1AB.
Now here is the code I have so far:
public void sha1() throws NoSuchAlgorithmException {
String hexMEID = "A0000000002329";
MessageDigest mDigest = MessageDigest.getInstance("SHA1");
byte[] result = mDigest.digest(hexMEID.getBytes());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.length; i++) {
sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
}
System.out.println(sb.toString());
}
The problem is that using this method, SHA-1 on A0000000002329 gives a89b611b421f57705bd013297ce3fc835f706ab0 instead of e3be267a2cd5c861f3c7ea4224df829a3551f1ab. What am I doing wrong here??
Someone gave me a hint that "the trick is to apply SHA-1 to the number representing the MEID, not the string representing the MEID. You'll need to process it byte-by-byte, so you must give it two hex numbers at a time (since two hex numbers make a byte) and make sure they are interpreted as numbers and not ASCII characters". If this is true then how do I change my string into hex and then into byte so that SHA1 can give me the correct result???
Without libraries, you can follow the example here:
In Java, how do you convert a hex string to a byte[]?
byte[] b = new BigInteger(s,16).toByteArray();
One library (I'm sure there are many) that also provides this is POJava:
<dependency>
<groupId>org.pojava</groupId>
<artifactId>pojava</artifactId>
<version>2.8.1</version>
</dependency>
byte[] hexMEIDBytes=EncodingTool.hexDecode(hexMEID);
[EDIT] ==============
Here's a more complete example per your followup question:
byte[] hexMEIDBytes = EncodingTool.hexDecode(hexMEID);
byte[] hash = HashingTool.hash(hexMEIDBytes, HashingAlgorithm.SHA);
String pESN="0x80" + EncodingTool.hexEncode(hash).substring(34).toUpperCase();
// a hexMEID value of "A0000000002329" results in a pESN value of "0x8051F1AB"
For String to Hex:
public String StrToHex(String arg) {
return String.format("%040x", new BigInteger(arg.getBytes(//Your Charset//)));
}
For Hex to byte:
This below code wont work for "0".
public byte[] hexStrToByteArray(String s) {
int leng = s.length();
byte[] data = new byte[leng / 2];
for (int i = 0; i < leng; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
You can use the following two methods
public static synchronized String bytesToHex(byte [] buf){
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10){
strbuf.append("0");
}
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
public synchronized static byte[] hexToBytes(String hexString) {
byte[] b = new BigInteger(hexString,16).toByteArray();
return b;
}