flutter_smartconfig/android/src/main/java/com/espressif/iot/esptouch/util/ByteUtil.java

324 lines
9.8 KiB
Java

package com.espressif.iot.esptouch.util;
import java.io.UnsupportedEncodingException;
import java.util.Random;
/**
* In Java, it don't support unsigned int, so we use char to replace uint8.
* The range of byte is [-128,127], and the range of char is [0,65535].
* So the byte could used to store the uint8.
* (We assume that the String could be mapped to assic)
*
* @author afunx
*/
public class ByteUtil {
public static final String ESPTOUCH_ENCODING_CHARSET = "UTF-8";
/**
* Put String to byte[]
*
* @param destbytes the byte[] of dest
* @param srcString the String of src
* @param destOffset the offset of byte[]
* @param srcOffset the offset of String
* @param count the count of dest, and the count of src as well
*/
public static void putString2bytes(byte[] destbytes, String srcString,
int destOffset, int srcOffset, int count) {
for (int i = 0; i < count; i++) {
destbytes[count + i] = srcString.getBytes()[i];
}
}
/**
* Convert uint8 into char( we treat char as uint8)
*
* @param uint8 the unit8 to be converted
* @return the byte of the unint8
*/
public static byte convertUint8toByte(char uint8) {
if (uint8 > Byte.MAX_VALUE - Byte.MIN_VALUE) {
throw new RuntimeException("Out of Boundary");
}
return (byte) uint8;
}
/**
* Convert char into uint8( we treat char as uint8 )
*
* @param b the byte to be converted
* @return the char(uint8)
*/
public static char convertByte2Uint8(byte b) {
// char will be promoted to int for char don't support & operator
// & 0xff could make negatvie value to positive
return (char) (b & 0xff);
}
/**
* Convert byte[] into char[]( we treat char[] as uint8[])
*
* @param bytes the byte[] to be converted
* @return the char[](uint8[])
*/
public static char[] convertBytes2Uint8s(byte[] bytes) {
int len = bytes.length;
char[] uint8s = new char[len];
for (int i = 0; i < len; i++) {
uint8s[i] = convertByte2Uint8(bytes[i]);
}
return uint8s;
}
/**
* Put byte[] into char[]( we treat char[] as uint8[])
*
* @param destUint8s the char[](uint8[]) array
* @param srcBytes the byte[]
* @param destOffset the offset of char[](uint8[])
* @param srcOffset the offset of byte[]
* @param count the count of dest, and the count of src as well
*/
public static void putbytes2Uint8s(char[] destUint8s, byte[] srcBytes,
int destOffset, int srcOffset, int count) {
for (int i = 0; i < count; i++) {
destUint8s[destOffset + i] = convertByte2Uint8(srcBytes[srcOffset
+ i]);
}
}
/**
* Convert byte to Hex String
*
* @param b the byte to be converted
* @return the Hex String
*/
public static String convertByte2HexString(byte b) {
char u8 = convertByte2Uint8(b);
return Integer.toHexString(u8);
}
/**
* Convert char(uint8) to Hex String
*
* @param u8 the char(uint8) to be converted
* @return the Hex String
*/
public static String convertU8ToHexString(char u8) {
return Integer.toHexString(u8);
}
/**
* Split uint8 to 2 bytes of high byte and low byte. e.g. 20 = 0x14 should
* be split to [0x01,0x04] 0x01 is high byte and 0x04 is low byte
*
* @param uint8 the char(uint8)
* @return the high and low bytes be split, byte[0] is high and byte[1] is
* low
*/
public static byte[] splitUint8To2bytes(char uint8) {
if (uint8 < 0 || uint8 > 0xff) {
throw new RuntimeException("Out of Boundary");
}
String hexString = Integer.toHexString(uint8);
byte low;
byte high;
if (hexString.length() > 1) {
high = (byte) Integer.parseInt(hexString.substring(0, 1), 16);
low = (byte) Integer.parseInt(hexString.substring(1, 2), 16);
} else {
high = 0;
low = (byte) Integer.parseInt(hexString.substring(0, 1), 16);
}
byte[] result = new byte[]{high, low};
return result;
}
/**
* Combine 2 bytes (high byte and low byte) to one whole byte
*
* @param high the high byte
* @param low the low byte
* @return the whole byte
*/
public static byte combine2bytesToOne(byte high, byte low) {
if (high < 0 || high > 0xf || low < 0 || low > 0xf) {
throw new RuntimeException("Out of Boundary");
}
return (byte) (high << 4 | low);
}
/**
* Combine 2 bytes (high byte and low byte) to
*
* @param high the high byte
* @param low the low byte
* @return the char(u8)
*/
public static char combine2bytesToU16(byte high, byte low) {
char highU8 = convertByte2Uint8(high);
char lowU8 = convertByte2Uint8(low);
return (char) (highU8 << 8 | lowU8);
}
/**
* Generate the random byte to be sent
*
* @return the random byte
*/
private static byte randomByte() {
return (byte) (127 - new Random().nextInt(256));
}
/**
* Generate the random byte to be sent
*
* @param len the len presented by u8
* @return the byte[] to be sent
*/
public static byte[] randomBytes(char len) {
byte[] data = new byte[len];
for (int i = 0; i < len; i++) {
data[i] = randomByte();
}
return data;
}
public static byte[] genSpecBytes(char len) {
byte[] data = new byte[len];
for (int i = 0; i < len; i++) {
data[i] = '1';
}
return data;
}
/**
* Generate the random byte to be sent
*
* @param len the len presented by byte
* @return the byte[] to be sent
*/
public static byte[] randomBytes(byte len) {
char u8 = convertByte2Uint8(len);
return randomBytes(u8);
}
/**
* Generate the specific byte to be sent
*
* @param len the len presented by byte
* @return the byte[]
*/
public static byte[] genSpecBytes(byte len) {
char u8 = convertByte2Uint8(len);
return genSpecBytes(u8);
}
public static String parseBssid(byte[] bssidBytes, int offset, int count) {
byte[] bytes = new byte[count];
System.arraycopy(bssidBytes, offset, bytes, 0, count);
return parseBssid(bytes);
}
/**
* parse "24,-2,52,-102,-93,-60" to "18,fe,34,9a,a3,c4"
* parse the bssid from hex to String
*
* @param bssidBytes the hex bytes bssid, e.g. {24,-2,52,-102,-93,-60}
* @return the String of bssid, e.g. 18fe349aa3c4
*/
public static String parseBssid(byte[] bssidBytes) {
StringBuilder sb = new StringBuilder();
int k;
String hexK;
String str;
for (byte bssidByte : bssidBytes) {
k = 0xff & bssidByte;
hexK = Integer.toHexString(k);
str = ((k < 16) ? ("0" + hexK) : (hexK));
System.out.println(str);
sb.append(str);
}
return sb.toString();
}
/**
* @param string the string to be used
* @return the byte[] of String according to {@link #ESPTOUCH_ENCODING_CHARSET}
*/
public static byte[] getBytesByString(String string) {
try {
return string.getBytes(ESPTOUCH_ENCODING_CHARSET);
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("the charset is invalid");
}
}
private static void test_splitUint8To2bytes() {
// 20 = 0x14
byte[] result = splitUint8To2bytes((char) 20);
if (result[0] == 1 && result[1] == 4) {
System.out.println("test_splitUint8To2bytes(): pass");
} else {
System.out.println("test_splitUint8To2bytes(): fail");
}
}
private static void test_combine2bytesToOne() {
byte high = 0x01;
byte low = 0x04;
if (combine2bytesToOne(high, low) == 20) {
System.out.println("test_combine2bytesToOne(): pass");
} else {
System.out.println("test_combine2bytesToOne(): fail");
}
}
private static void test_convertChar2Uint8() {
byte b1 = 'a';
// -128: 1000 0000 should be 128 in unsigned char
// -1: 1111 1111 should be 255 in unsigned char
byte b2 = (byte) -128;
byte b3 = (byte) -1;
if (convertByte2Uint8(b1) == 97 && convertByte2Uint8(b2) == 128
&& convertByte2Uint8(b3) == 255) {
System.out.println("test_convertChar2Uint8(): pass");
} else {
System.out.println("test_convertChar2Uint8(): fail");
}
}
private static void test_convertUint8toByte() {
char c1 = 'a';
// 128: 1000 0000 should be -128 in byte
// 255: 1111 1111 should be -1 in byte
char c2 = 128;
char c3 = 255;
if (convertUint8toByte(c1) == 97 && convertUint8toByte(c2) == -128
&& convertUint8toByte(c3) == -1) {
System.out.println("test_convertUint8toByte(): pass");
} else {
System.out.println("test_convertUint8toByte(): fail");
}
}
private static void test_parseBssid() {
byte b[] = {15, -2, 52, -102, -93, -60};
if (parseBssid(b).equals("0ffe349aa3c4")) {
System.out.println("test_parseBssid(): pass");
} else {
System.out.println("test_parseBssid(): fail");
}
}
public static void main(String args[]) {
test_convertUint8toByte();
test_convertChar2Uint8();
test_splitUint8To2bytes();
test_combine2bytesToOne();
test_parseBssid();
}
}