I want to know how the byte code work in thermal printer
tcmd = new byte[7];
tcmd[0] = 0x1B;
tcmd[1] = 0x5A;
tcmd[2] = 0x00;
tcmd[3] = 0x02;
tcmd[4] = 0x07;
tcmd[5] = 0x17;
tcmd[6] = 0x00;
String content = "SDK 2D-Code print test.";
wfComm.sndByte(tcmd);
wfComm.sendMsg(content, "GBK");
this code send the data to printer and the printer print the qr code that has the string , but if i send this without the byte array the printer simply print the string.
I want to understand the byte code if you can give me the documentation in which show that how this byte work
Check this image
The code is tested and verified..it will convert qr code to byte and print it in paper.just create utils class as described below and call this method..
byte[] command = Utils.decodeBitmap(bitmap);
mService.write(command);
public class Utils {
// UNICODE 0x23 = #
public static final byte[] UNICODE_TEXT = new byte[] {0x23, 0x23, 0x23,
0x23, 0x23, 0x23,0x23, 0x23, 0x23,0x23, 0x23, 0x23,0x23, 0x23, 0x23,
0x23, 0x23, 0x23,0x23, 0x23, 0x23,0x23, 0x23, 0x23,0x23, 0x23, 0x23,
0x23, 0x23, 0x23};
private static String hexStr = "0123456789ABCDEF";
private static String[] binaryArray = { "0000", "0001", "0010", "0011",
"0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011",
"1100", "1101", "1110", "1111" };
public static byte[] decodeBitmap(Bitmap bmp){
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
List<String> list = new ArrayList<String>(); //binaryString list
StringBuffer sb;
int bitLen = bmpWidth / 8;
int zeroCount = bmpWidth % 8;
String zeroStr = "";
if (zeroCount > 0) {
bitLen = bmpWidth / 8 + 1;
for (int i = 0; i < (8 - zeroCount); i++) {
zeroStr = zeroStr + "0";
}
}
for (int i = 0; i < bmpHeight; i++) {
sb = new StringBuffer();
for (int j = 0; j < bmpWidth; j++) {
int color = bmp.getPixel(j, i);
int r = (color >> 16) & 0xff;
int g = (color >> 8) & 0xff;
int b = color & 0xff;
// if color close to white,bit='0', else bit='1'
if (r > 160 && g > 160 && b > 160)
sb.append("0");
else
sb.append("1");
}
if (zeroCount > 0) {
sb.append(zeroStr);
}
list.add(sb.toString());
}
List<String> bmpHexList = binaryListToHexStringList(list);
String commandHexString = "1D763000";
String widthHexString = Integer
.toHexString(bmpWidth % 8 == 0 ? bmpWidth / 8
: (bmpWidth / 8 + 1) );
if (widthHexString.length() > 2) {
Log.e("decodeBitmap error", " width is too large");
return null;
} else if (widthHexString.length() == 1) {
widthHexString = "0" + widthHexString;
}
widthHexString = widthHexString + "00";
String heightHexString = Integer.toHexString(bmpHeight);
if (heightHexString.length() > 2) {
Log.e("decodeBitmap error", " height is too large");
return null;
}
else if (heightHexString.length() == 1) {
heightHexString = "0" + heightHexString;
}
heightHexString = heightHexString + "00";
List<String> commandList = new ArrayList<String>();
commandList.add(commandHexString+widthHexString+heightHexString);
commandList.addAll(bmpHexList);
return hexList2Byte(commandList);
}
public static List<String> binaryListToHexStringList(List<String> list) {
List<String> hexList = new ArrayList<String>();
for (String binaryStr : list) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < binaryStr.length(); i += 8) {
String str = binaryStr.substring(i, i + 8);
String hexString = myBinaryStrToHexString(str);
sb.append(hexString);
}
hexList.add(sb.toString());
}
return hexList;
}
public static String myBinaryStrToHexString(String binaryStr) {
String hex = "";
String f4 = binaryStr.substring(0, 4);
String b4 = binaryStr.substring(4, 8);
for (int i = 0; i < binaryArray.length; i++) {
if (f4.equals(binaryArray[i]))
hex += hexStr.substring(i, i + 1);
}
for (int i = 0; i < binaryArray.length; i++) {
if (b4.equals(binaryArray[i]))
hex += hexStr.substring(i, i + 1);
}
return hex;
}
public static byte[] hexList2Byte(List<String> list) {
List<byte[]> commandList = new ArrayList<byte[]>();
for (String hexStr : list) {
commandList.add(hexStringToBytes(hexStr));
}
byte[] bytes = sysCopy(commandList);
return bytes;
}
public static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
public static byte[] sysCopy(List<byte[]> srcArrays) {
int len = 0;
for (byte[] srcArray : srcArrays) {
len += srcArray.length;
}
byte[] destArray = new byte[len];
int destLen = 0;
for (byte[] srcArray : srcArrays) {
System.arraycopy(srcArray, 0, destArray, destLen, srcArray.length);
destLen += srcArray.length;
}
return destArray;
}
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}}
Related
I am implementing POS bluetooth printer with ESC/POS commands and trying to print bitmap image.
Image is getting printing but always it is printing some white space at start and then printing an image,because of which i am not able to print 1 image per label.
following is my code for printing and image
int bmpNewWidth = bmp.getWidth();
int bmpNewHeight = bmp.getHeight();
byte[] printBMPPackageHead = ESCUtil.bmpCmdHead(bmpMode,bmpNewWidth);
int bmpBlockHeight = 0;
int bmpBlockNums =0;
if((bmpMode == 0) || (bmpMode ==1))
{
bmpBlockHeight = 8;
}
else if((bmpMode == 32) || (bmpMode ==33))
{
bmpBlockHeight = 24;
}
else
{
Log.d(TAG,"****bmpMode set error!!*****");
return (new byte[1]);
}
bmpBlockNums = ((bmpNewHeight % bmpBlockHeight) == 0)? (bmpNewHeight/bmpBlockHeight) : (bmpNewHeight/bmpBlockHeight +1);
int bmpBlockCMDSize = printBMPPackageHead.length + bmpNewWidth*bmpBlockHeight/8;
byte[] bmpPrintData = new byte[bmpBlockNums*bmpBlockCMDSize];
for(int n = 0; n < bmpBlockNums; n++)
{
byte[] bmpBlockPxBytes = getBitmapBlockData(n,bmpNewWidth,bmpBlockHeight,bmp);
byte[][] bmpBlockPrintData = {printBMPPackageHead,bmpBlockPxBytes};
System.arraycopy(ESCUtil.byteMerger(bmpBlockPrintData),0,bmpPrintData,n*bmpBlockCMDSize,bmpBlockCMDSize);
}
return bmpPrintData;
}
and
public static byte[] bmpCmdHead(int mode, int bitmapWidth)
{
//byte[] result = new byte[]{ESC,42,0,0,0};
byte[] result = new byte[]{ESC,42,0,0,0};
result[2] = (byte)mode;
result[3] = (byte)(bitmapWidth%256);
result[4] = (byte)(bitmapWidth/256);
return result;
}
public static byte[] getBitmapBlockData(int blocknum, int bmpWidth, int bmpBlockHeight, Bitmap bmp)
{
int blockHeightBytes = bmpBlockHeight/8;
byte[] blockData = new byte[bmpWidth*blockHeightBytes];
for (int i = 0;i < bmpWidth; i++)
{
for(int j = 0;j < blockHeightBytes;j++)
{
for(int p = 0; p < 8; p++)
{
byte px = px2Byte(i,blocknum * bmpBlockHeight+j*8+p,bmp);
blockData[i*blockHeightBytes+j] |= (px << (7-p));
}
}
}
return blockData;
}
this is it.Before calling this function i have called only init printer command that's it.
Please help me. Thanks in advance.
I using the following class for UnZip password-protected file but unzipping to too much slow to fast it or any improvement in such class or method. Thanks in advance.
Class for Unzip Password Protect Zip file.
public class ZipDecryptInputStream extends InputStream {
private static final int[] CRC_TABLE = new int[256];
private static final int DECRYPT_HEADER_SIZE = 12;
private static final int[] LFH_SIGNATURE = {0x50, 0x4b, 0x03, 0x04};
static {
for (int i = 0; i < 256; i++) {
int r = i;
for (int j = 0; j < 8; j++) {
if ((r & 1) == 1) {
r = (r >>> 1) ^ 0xedb88320;
} else {
r >>>= 1;
}
}
CRC_TABLE[i] = r;
}
}
private final InputStream delegate;
private final String password;
private final int[] keys = new int[3];
private State state = State.SIGNATURE;
private int skipBytes;
private int compressedSize;
private int value;
private int valuePos;
private int valueInc;
public ZipDecryptInputStream(InputStream stream, String password) {
this.delegate = stream;
this.password = password;
}
#Override
public int read() throws IOException {
int result = delegate.read();
if (skipBytes == 0) {
switch (state) {
case SIGNATURE:
if (result != LFH_SIGNATURE[valuePos]) {
state = State.TAIL;
} else {
valuePos++;
if (valuePos >= LFH_SIGNATURE.length) {
skipBytes = 2;
state = State.FLAGS;
}
}
break;
case FLAGS:
if ((result & 1) == 0) {
throw new IllegalStateException("ZIP not password protected.");
}
if ((result & 64) == 64) {
throw new IllegalStateException("Strong encryption used.");
}
if ((result & 8) == 8) {
throw new IllegalStateException("Unsupported ZIP format.");
}
result -= 1;
compressedSize = 0;
valuePos = 0;
valueInc = DECRYPT_HEADER_SIZE;
state = State.COMPRESSED_SIZE;
skipBytes = 11;
break;
case COMPRESSED_SIZE:
compressedSize += result << (8 * valuePos);
result -= valueInc;
if (result < 0) {
valueInc = 1;
result += 256;
} else {
valueInc = 0;
}
valuePos++;
if (valuePos > 3) {
valuePos = 0;
value = 0;
state = State.FN_LENGTH;
skipBytes = 4;
}
break;
case FN_LENGTH:
case EF_LENGTH:
value += result << 8 * valuePos;
if (valuePos == 1) {
valuePos = 0;
if (state == State.FN_LENGTH) {
state = State.EF_LENGTH;
} else {
state = State.HEADER;
skipBytes = value;
}
} else {
valuePos = 1;
}
break;
case HEADER:
initKeys(password);
for (int i = 0; i < DECRYPT_HEADER_SIZE; i++) {
updateKeys((byte) (result ^ decryptByte()));
result = delegate.read();
}
compressedSize -= DECRYPT_HEADER_SIZE;
state = State.DATA;
// intentionally no break
case DATA:
result = (result ^ decryptByte()) & 0xff;
updateKeys((byte) result);
compressedSize--;
if (compressedSize == 0) {
valuePos = 0;
state = State.SIGNATURE;
}
break;
case TAIL:
// do nothing
}
} else {
skipBytes--;
}
return result;
}
#Override
public void close() throws IOException {
delegate.close();
super.close();
}
private void initKeys(String password) {
keys[0] = 305419896;
keys[1] = 591751049;
keys[2] = 878082192;
for (int i = 0; i < password.length(); i++) {
updateKeys((byte) (password.charAt(i) & 0xff));
}
}
private void updateKeys(byte charAt) {
keys[0] = crc32(keys[0], charAt);
keys[1] += keys[0] & 0xff;
keys[1] = keys[1] * 134775813 + 1;
keys[2] = crc32(keys[2], (byte) (keys[1] >> 24));
}
private byte decryptByte() {
int temp = keys[2] | 2;
return (byte) ((temp * (temp ^ 1)) >>> 8);
}
private int crc32(int oldCrc, byte charAt) {
return ((oldCrc >>> 8) ^ CRC_TABLE[(oldCrc ^ charAt) & 0xff]);
}
private enum State {
SIGNATURE, FLAGS, COMPRESSED_SIZE, FN_LENGTH, EF_LENGTH, HEADER, DATA, TAIL
}
}
Usage
InputStream zin = new FileInputStream(new File(zipFilePath));
ZipDecryptInputStream inputStream = new ZipDecryptInputStream(zin, "myPassWord");
ZipInputStream zis = new ZipInputStream(inputStream);
ZipEntry ze ;
while ((ze = zis.getNextEntry()) != null) {
FileOutputStream fos = new FileOutputStream(unzipAtLocation + File.separator + ze.getName());
int BUFFER = 2048;
byte[] data = new byte[BUFFER];
int count;
while ((count = zis.read(data, 0, BUFFER)) != -1) {
fos.write(data, 0, count);
}
}
zis.close();
Did you consider using ByteArrayOutputStream instead of FileOutputStream? I have also problem with reading files the other day, which took to much time and I found somewhere in google example with ByteArrayOutputStream and that helps a lot
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] ba = new byte[(int) files[i].length()];
for (int readNum; (readNum = fis.read(ba)) != -1; ) {
bos.write(ba, 0, readNum);
}
I have a piece of problem that I want to achieve in android.
The formula is
Server Seed + Client Seed (->byte[4]) + Bet Number (->byte[4])
Double SHA2-512 hash the result
Keep taking groups of 3 bytes and converting to an integer, until a value less than 16 million is found. If you run out of bytes, hash it
again and start over.
Find the value's modulus of 1 million
The modulus is the bet result!
Which have an example code in C#
static bool VerifyBetResult(string serverSeed, int clientSeed, int betNumber,
long betResult, string serverSeedHash = null)
{
Func<string, byte[]> strtobytes = s => Enumerable
.Range(0, s.Length / 2)
.Select(x => byte.Parse(s.Substring(x * 2, 2), NumberStyles.HexNumber))
.ToArray();
byte[] server = strtobytes(serverSeed);
byte[] client = BitConverter.GetBytes(clientSeed).Reverse().ToArray();
byte[] num = BitConverter.GetBytes(betNumber).Reverse().ToArray();
byte[] serverhash = serverSeedHash == null ? null : strtobytes(serverSeedHash);
byte[] data = server.Concat(client).Concat(num).ToArray();
using (SHA512 sha512 = new SHA512Managed())
{
if (serverhash != null)
using (SHA256 sha256 = new SHA256Managed())
if (!sha256.ComputeHash(server).SequenceEqual(serverhash))
throw new Exception("Server seed hash does not match server seed");
byte[] hash = sha512.ComputeHash(sha512.ComputeHash(data));
while (true)
{
for (int x = 0; x <= 61; x += 3)
{
long result = (hash[x] << 16) | (hash[x + 1] << 8) | hash[x + 2];
if (result < 16000000)
return result % 1000000 == betResult;
}
hash = sha512.ComputeHash(hash);
}
}
}
Using these values
serverSeed = e600f76aa6c520dff7db34559bd05cb1048b1830a07cd81844147a19048fc9be;
clientSeed = 443944;
betNumber = 0;
serverHash = ca90022ac66a6a77d8b5072e101bff505c2bff552b1b9a0785f0c438d5b6228f;
I want to find the (result % 1000000) which should be = 563383
But I got -25564 and the serverHash does not match the serverSeed when hashing the seed to sha256
Update
This is my code:
private byte[] reverse(byte[] b){
int i = b.length - 1;
byte newB[] = new byte[4];
for(int x = 0; x < b.length; x++){
newB[x] = b[i];
i--;
}
return newB;
}
private byte[] strToByte(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 long verifyBet(){
//MessageDigest md256 = null;
MessageDigest md512 = null;
try {
//md256 = MessageDigest.getInstance("SHA-256");
md512 = MessageDigest.getInstance("SHA-512");
} catch (Exception e) {
e.printStackTrace();
}
String //res = "ServerSeed = ",
sSeed = "e600f76aa6c520dff7db34559bd05cb1048b1830a07cd81844147a19048fc9be";
//sHash = "ca90022ac66a6a77d8b5072e101bff505c2bff552b1b9a0785f0c438d5b6228f";
int cSeed = 443944,
num = 0;
byte serverSeed[] = strToByte(sSeed),
//serverHash[] = strToByte(sHash),
clientSeed[] = reverse(ByteBuffer.allocate(4).putInt(cSeed).array()),
betNumber[] = reverse(ByteBuffer.allocate(4).putInt(num).array());
byte data[] = ByteBuffer.allocate(serverSeed.length + clientSeed.length + betNumber.length)
.put(serverSeed).put(clientSeed).put(betNumber).array();
data = md512.digest(data);
data = md512.digest(data);
long secret = 0;
boolean found = false;
while(!found){
for(int x = 0; x <= 61; x += 3){
long result = (data[x] << 16 | data[x+1] << 8) | data[x+2];
if (result < 16000000){
secret = result % 1000000;
found = true;
}
}
data = md512.digest(data);
}
return secret;
}
After much more research I found that byte in java is signed while the code I am basing from is calculating in unsigned byte which is why I am getting result in negative..
How can I get set of bytes in 'unsigned' form?
After so much research and testing. I finally got it. This is the code.
private byte[] strToByte(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 long verifyBet(int _num){
MessageDigest md512 = null;
try {
md512 = MessageDigest.getInstance("SHA-512");
} catch (Exception e) {
e.printStackTrace();
}
String sSeed = "e600f76aa6c520dff7db34559bd05cb1048b1830a07cd81844147a19048fc9be";
int cSeed = 443944,
num = _num;
byte serverSeed[] = strToByte(sSeed),
clientSeed[] = ByteBuffer.allocate(4).putInt(cSeed).array(),
betNumber[] = ByteBuffer.allocate(4).putInt(num).array();
byte data[] = ByteBuffer.allocate(serverSeed.length + clientSeed.length + betNumber.length)
.put(serverSeed).put(clientSeed).put(betNumber).array();
data = md512.digest(data);
data = md512.digest(data);
long secret = 0;
boolean found = false;
while(!found){
for(int x = 0; x <= 61; x += 3){
long result = ((data[x] & 0xFF) << 16 | (data[x+1] & 0xFF) << 8) | data[x+2] & 0xFF;
if (result < 16000000){
secret = result % 1000000;
found = true;
x = 62;
}
}
data = md512.digest(data);
}
return secret;
}
I am developing in Android BLE.
I try to send string to BLE device(like TI CC2541) , and it seems can not send string direct to BLE device.
It need to convert the String to Byte.
I have search some information , there has someone use URLEncoder.encode.
But I am not sure which is the answer what I need.
But how to convert the String to Byte?
The following code is writeCharacteristic for BLE
public void writeString(String text) {
// TODO Auto-generated method stub
BluetoothGattService HelloService = mBluetoothGatt.getService(HELLO_SERVICE_UUID);
BluetoothGattCharacteristic StringCharacteristic = HelloService.getCharacteristic(UUID_HELLO_CHARACTERISTIC_WRITE_STRING);
mBluetoothGatt.setCharacteristicNotification(StringCharacteristic , true);
int A = Integer.parseInt(text);
//How to convert the String to Byte here and set the Byte to setValue ?????
StringCharacteristic .setValue(A, BluetoothGattCharacteristic.FORMAT_UINT8, 0);
mBluetoothGatt.writeCharacteristic(StringCharacteristic );
Log.d(TAG, "StepCount Characteristic End!");
}
How to convert the String to Byte?
Where you get your String:
byte[] strBytes = text.getBytes();
byte[] bytes = context.yourmWriteCharacteristic.getValue();
Please add a null check too like:
if (bytes == null) {
Log.w("Cannot get Values from mWriteCharacteristic.");
dismiss();// equivalent action
}
if (bytes.length <= strBytes.length) {
for(int i = 0; i < bytes.length; i++) {
bytes[i] = strBytes[i];
}
} else {
for (int i = 0; i < strBytes.length; i++) {
bytes[i] = strBytes[i];
}
}
Now, something like:
StepCount_Characteristic.setValue(bytes);
mBluetoothGatt.writeCharacteristic(StepCount_Characteristic);
I found the following code help me convert the string.
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);
}
If you want to convert string value. you just need to call like the following:
String text;
byte[] value = parseHex(text);
I've got a String like this:
init_thread = "2b11020000ed"
I have to send this string via bluetooth, for what I do this:
byte[] init = init_thread.getBytes();
GlobalVar.mTransmission.write(init);
What I need is to define that the init_thread string is an hex string before converting it to bytes, because if I do this way, it is getting it wrong:
What is doing now = 2(1byte), b(1byte), 1(1byte), 1(1byte)...
What must do = 2b(1byte), 11(1byte), 02(1byte)...
Convert hex to byte and byte to hex.
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;
}
final protected static char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
public static String byteArrayToHexString(byte[] bytes) {
char[] hexChars = new char[bytes.length*2];
int v;
for(int j=0; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j*2] = hexArray[v>>>4];
hexChars[j*2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
If we want to convert hex to byte array, we should make sure that hex string length should be of even length. Below method handles this
public static byte[] hexToByteArray(String hex) {
hex = hex.length()%2 != 0?"0"+hex:hex;
byte[] b = new byte[hex.length() / 2];
for (int i = 0; i < b.length; i++) {
int index = i * 2;
int v = Integer.parseInt(hex.substring(index, index + 2), 16);
b[i] = (byte) v;
}
return b;
}