How to convert 2 bytes to Int16 in dart? - flutter

There is a method in bitconverter class in java which has a method called toInt16
But in dart i am unable to cast short as Int16
public static short toInt16( byte[] bytes, int index )
throws Exception {
if ( bytes.length != 8 )
throw new Exception( "The length of the byte array must be at least 8 bytes long." );
return (short) ( ( 0xff & bytes[index] ) << 8 | ( 0xff & bytes[index + 1] ) << 0 );
}
can someone help me with this conversion to dart language ?
Here is the updated dart version of answer that i followed using the ByteData class suggested by emerssso and this works for me
int toInt16(Uint8List byteArray, int index)
{
ByteBuffer buffer = byteArray.buffer;
ByteData data = new ByteData.view(buffer);
int short = data.getInt16(index, Endian.little);
return short;
}
I had to specifically set Endian.little because originally getInt16 method is set to BigEndian but my byte data was in former order

I think you are looking for one of the methods on the ByteData class available in dart:typed_data. Wrap your byte array in a ByteData via ByteData.view() and then you can arbitrarily access bytes as a specified type. You could then do i.e. byteData.getInt16(index);.
https://api.dart.dev/stable/2.7.1/dart-typed_data/ByteData-class.html

Related

Is there any way to make normal int(65) to hex int(0x65) in flutter?

I'm using flutter_blue for ble communication. I need to send list in write characteristic.
eg. Let say input value is 'A'.
I want the result to be 0x41(int).
Instead I got the result 41(int).
When I send to ble device 0x41 then the reader can get the correct result 'A'.I can't find how to put 0x to infront of a int value.
You can do like this
/// Multiple chars
final _codeUnits = 'Abcd'.codeUnits;
_codeUnits.forEach((codeUnit) => print('0x$codeUnit'));
// Output: 0x65, 0x98, 0x99, 0x100
/// If it is single char
final codeUnit = 'A'.codeUnits.elementAt(0);
print('0x$codeUnit');
// Output: 0x65
// Decode
print(String.fromCharCode('A'.codeUnits.elementAt(0)));
// Output: A
I have the same problem;
I want to get an integer like 0x61 (runtimeType == int)
int count = 9999;
/// count.toRadixString(16); ===> 0x270F runtimeType == String
int.parse(count.toRadixString(16)); /// output => 9999

Convert two 16 Bit Registers to 32 Bit real value flutter

I am using a Modbus flutter lib, reading 2 registers I obtain:
[22136, 4660]
This means: 0x12345678 I need a function to convert it to a 32 bit real value: 305419896, in easymodbustcp library I found:
/**
* Convert two 16 Bit Registers to 32 Bit real value
* #param registers 16 Bit Registers
* #return 32 bit real value
*/
public static float ConvertRegistersToFloat(int[] registers) throws IllegalArgumentException
{
if (registers.length != 2)
throw new IllegalArgumentException("Input Array length invalid");
int highRegister = registers[1];
int lowRegister = registers[0];
byte[] highRegisterBytes = toByteArray(highRegister);
byte[] lowRegisterBytes = toByteArray(lowRegister);
byte[] floatBytes = {
highRegisterBytes[1],
highRegisterBytes[0],
lowRegisterBytes[1],
lowRegisterBytes[0]
};
return ByteBuffer.wrap(floatBytes).getFloat();
}
Any help to do it in flutter / dart?
This can be done with bit shifts and a bitwise or. You need to shift the 2 higher bytes by 16 bits, then or it to get the value you want.
void main() {
List<int> vals = [22136, 4660];
int result = vals[1] << 16 | vals[0];
print(result);//305419896
}
You could also achieve the same result in this case by replacing the bitwise or with addition.
void main() {
List<int> vals = [22136, 4660];
int result = (vals[1] << 16) + vals[0];
print(result);//305419896
}

Flutter List<int> LITTLE ENDIAN Order?

I am converting Java code to Dart, but I am stuck in Little Endian oder, Any ideas to help me?
Java:
void displayString(byte[] record) {
ByteBuffer bb = ByteBuffer.wrap(record);
bb.order(ByteOrder.LITTLE_ENDIAN);
.....
}
Dart:
_displayString(List<int> record) {
var _list = Uint8List.fromList(record);
// HOW TO ORDER LITTLE ENDIAN Like Java
.....
}
The closest equivalent to Java Byte buffer is Dart's ByteData.
var byteData = _list.buffer.asByteData();
You can't set its order globally, but you can specify it for each get or set.
byteData.setFloat32(0, 3.04, Endian.little);

Obtain text fields from a png file

Nothing seems to work so far. I got to see with pnginfo the following message:
concept_Sjet_dream6.png...
Image Width: 200 Image Length: 240
Bitdepth (Bits/Sample): 8
Channels (Samples/Pixel): 2
Pixel depth (Pixel Depth): 16
Colour Type (Photometric Interpretation): GRAYSCALE with alpha channel
Image filter: Single row per byte filter
Interlacing: No interlacing
Compression Scheme: Deflate method 8, 32k window
Resolution: 11811, 11811 (pixels per meter)
FillOrder: msb-to-lsb
Byte Order: Network (Big Endian)
Number of text strings: 1 of 9
Comment (xTXt deflate compressed): The comment
But the remaining text strings are missing. I did also try other solutions in stackoverflow, they didn't work either. pngchunks provides this information:
Chunk: Data Length 13 (max 2147483647), Type 1380206665 [IHDR]
Critical, public, PNG 1.2 compliant, unsafe to copy
IHDR Width: 200
IHDR Height: 240
IHDR Bitdepth: 8
IHDR Colortype: 4
IHDR Compression: 0
IHDR Filter: 0
IHDR Interlace: 0
IHDR Compression algorithm is Deflate
IHDR Filter method is type zero (None, Sub, Up, Average, Paeth)
IHDR Interlacing is disabled
Chunk CRC: -277290027
Chunk: Data Length 1 (max 2147483647), Type 1111970419 [sRGB]
Ancillary, public, PNG 1.2 compliant, unsafe to copy
... Unknown chunk type
Chunk CRC: -1362223895
Chunk: Data Length 2 (max 2147483647), Type 1145523042 [bKGD]
Ancillary, public, PNG 1.2 compliant, unsafe to copy
... Unknown chunk type
Chunk CRC: -2020619073
Chunk: Data Length 9 (max 2147483647), Type 1935231088 [pHYs]
Ancillary, public, PNG 1.2 compliant, safe to copy
... Unknown chunk type
Chunk CRC: 2024095606
Chunk: Data Length 7 (max 2147483647), Type 1162692980 [tIME]
Ancillary, public, PNG 1.2 compliant, unsafe to copy
... Unknown chunk type
Chunk CRC: 292503155
Chunk: Data Length 19 (max 2147483647), Type 1951942004 [tEXt]
Ancillary, public, PNG 1.2 compliant, safe to copy
... Unknown chunk type
Chunk CRC: -528748773
Chunk: Data Length 8192 (max 2147483647), Type 1413563465 [IDAT]
Critical, public, PNG 1.2 compliant, unsafe to copy
IDAT contains image data
Chunk CRC: -309524018
Chunk: Data Length 8192 (max 2147483647), Type 1413563465 [IDAT]
Critical, public, PNG 1.2 compliant, unsafe to copy
IDAT contains image data
Chunk CRC: -1646200198
Chunk: Data Length 2301 (max 2147483647), Type 1413563465 [IDAT]
Critical, public, PNG 1.2 compliant, unsafe to copy
IDAT contains image data
Chunk CRC: -810299134
Chunk: Data Length 0 (max 2147483647), Type 1145980233 [IEND]
Critical, public, PNG 1.2 compliant, unsafe to copy
IEND contains no data
Chunk CRC: -1371381630
Sample image:
I'm very confused. Thank you anyone.
PD: apparently this happens with every image, this is not a special case but the usual case.
This is a simple Java way to extract text information from a "valid" png file. International characters may not show well on console.
import java.io.*;
import java.util.zip.InflaterInputStream;
public class PNGExtractText
{
/** PNG signature constant */
public static final long SIGNATURE = 0x89504E470D0A1A0AL;
/** PNG Chunk type constants, 4 Critical chunks */
/** Image header */
private static final int IHDR = 0x49484452; // "IHDR"
/** Image trailer */
private static final int IEND = 0x49454E44; // "IEND"
/** Palette */
/** Textual data */
private static final int tEXt = 0x74455874; // "tEXt"
/** Compressed textual data */
private static final int zTXt = 0x7A545874; // "zTXt"
/** International textual data */
private static final int iTXt = 0x69545874; // "iTXt"
/** Background color */
public static void showText(InputStream is) throws Exception
{
//Local variables for reading chunks
int data_len = 0;
int chunk_type = 0;
byte[] buf=null;
long signature = readLong(is);
if (signature != SIGNATURE)
{
System.out.println("--- NOT A PNG IMAGE ---");
return;
}
/** Read header */
/** We are expecting IHDR */
if ((readInt(is)!=13)||(readInt(is) != IHDR))
{
System.out.println("--- NOT A PNG IMAGE ---");
return;
}
buf = new byte[13+4];//13 plus 4 bytes CRC
is.read(buf,0,17);
while (true)
{
data_len = readInt(is);
chunk_type = readInt(is);
//System.out.println("chunk type: 0x"+Integer.toHexString(chunk_type));
if (chunk_type == IEND)
{
System.out.println("IEND found");
int crc = readInt(is);
break;
}
switch (chunk_type)
{
case zTXt:
{
System.out.println("zTXt chunk:");
buf = new byte[data_len];
is.read(buf);
int keyword_len = 0;
while(buf[keyword_len]!=0) keyword_len++;
System.out.print(new String(buf,0,keyword_len,"UTF-8")+": ");
InflaterInputStream ii = new InflaterInputStream(new ByteArrayInputStream(buf,keyword_len+2, data_len-keyword_len-2));
InputStreamReader ir = new InputStreamReader(ii,"UTF-8");
BufferedReader br = new BufferedReader(ir);
String read = null;
while((read=br.readLine()) != null) {
System.out.println(read);
}
System.out.println("**********************");
is.skip(4);
break;
}
case tEXt:
{
System.out.println("tEXt chunk:");
buf = new byte[data_len];
is.read(buf);
int keyword_len = 0;
while(buf[keyword_len]!=0) keyword_len++;
System.out.print(new String(buf,0,keyword_len,"UTF-8")+": ");
System.out.println(new String(buf,keyword_len+1,data_len-keyword_len-1,"UTF-8"));
System.out.println("**********************");
is.skip(4);
break;
}
case iTXt:
{
// System.setOut(new PrintStream(new File("TextChunk.txt"),"UTF-8"));
/**
* Keyword: 1-79 bytes (character string)
* Null separator: 1 byte
* Compression flag: 1 byte
* Compression method: 1 byte
* Language tag: 0 or more bytes (character string)
* Null separator: 1 byte
* Translated keyword: 0 or more bytes
* Null separator: 1 byte
* Text: 0 or more bytes
*/
System.out.println("iTXt chunk:");
buf = new byte[data_len];
is.read(buf);
int keyword_len = 0;
int trans_keyword_len = 0;
int lang_flg_len = 0;
boolean compr = false;
while(buf[keyword_len]!=0) keyword_len++;
System.out.print(new String(buf,0,keyword_len,"UTF-8"));
if(buf[++keyword_len]==1) compr = true;
keyword_len++;//Skip the compresssion method byte.
while(buf[++keyword_len]!=0) lang_flg_len++;
//////////////////////
System.out.print("(");
if(lang_flg_len>0)
System.out.print(new String(buf,keyword_len-lang_flg_len, lang_flg_len, "UTF-8"));
while(buf[++keyword_len]!=0) trans_keyword_len++;
if(trans_keyword_len>0)
System.out.print(" "+new String(buf,keyword_len-trans_keyword_len, trans_keyword_len, "UTF-8"));
System.out.print("): ");
/////////////////////// End of key.
if(compr) //Compressed text
{
InflaterInputStream ii = new InflaterInputStream(new ByteArrayInputStream(buf,keyword_len+1, data_len-keyword_len-1));
InputStreamReader ir = new InputStreamReader(ii,"UTF-8");
BufferedReader br = new BufferedReader(ir);
String read = null;
while((read=br.readLine()) != null) {
System.out.println(read);
}
}
else //Uncompressed text
{
System.out.println(new String(buf,keyword_len+1,data_len-keyword_len-1,"UTF-8"));
}
System.out.println("**********************");
is.skip(4);
break;
}
default:
{
buf = new byte[data_len+4];
is.read(buf,0, data_len+4);
break;
}
}
}
is.close();
}
private static int readInt(InputStream is) throws Exception
{
byte[] buf = new byte[4];
is.read(buf,0,4);
return (((buf[0]&0xff)<<24)|((buf[1]&0xff)<<16)|
((buf[2]&0xff)<<8)|(buf[3]&0xff));
}
private static long readLong(InputStream is) throws Exception
{
byte[] buf = new byte[8];
is.read(buf,0,8);
return (((buf[0]&0xffL)<<56)|((buf[1]&0xffL)<<48)|
((buf[2]&0xffL)<<40)|((buf[3]&0xffL)<<32)|((buf[4]&0xffL)<<24)|
((buf[5]&0xffL)<<16)|((buf[6]&0xffL)<<8)|(buf[7]&0xffL));
}
public static void main(String args[]) throws Exception
{
FileInputStream fs = new FileInputStream(args[0]);
showText(fs);
}
}
Note:: usage: java PNGExtractText image.png
This is what I got from the test image ctzn0g04.png from official png test suite :
D:\tmp>java PNGExtractText ctzn0g04.png
tEXt chunk:
Title: PngSuite
**********************
tEXt chunk:
Author: Willem A.J. van Schaik
(willem#schaik.com)
**********************
zTXt chunk:
Copyright: Copyright Willem van Schaik, Singapore 1995-96
**********************
zTXt chunk:
Description: A compilation of a set of images created to test the
various color-types of the PNG format. Included are
black&white, color, paletted, with alpha channel, with
transparency formats. All bit-depths allowed according
to the spec are present.
**********************
zTXt chunk:
Software: Created on a NeXTstation color using "pnmtopng".
**********************
zTXt chunk:
Disclaimer: Freeware.
**********************
IEND found
Edit: Just found your link and tried with the image, got this:
D:\tmp>java PNGExtractText concept_Sjet_dream6.png
tEXt chunk:
Comment: The comment
**********************
IEND found
The above example has become part of a Java image library which can be found at https://github.com/dragon66/icafe

Blackberry encode MD5 different from MD5 in C#

I have my passwords encoded in MD5 in C# and inserted in my DB.
MD5 MD5Hasher = MD5.Create();
byte[] PasswordHash = MD5Hasher.ComputeHash(Encoding.Unicode.GetBytes(PasswordText.Value));
PasswordHash is inserted as is and look like 0x09C09E5B52580E477514FA.......... for example.
In the blackberry app, I get the password, want to encode it to pass it to a web service that will compare both hashed password. The problem is my result is different from the MD5 I create in my Blackberry app.
password = Crypto.encodeStringMD5(password);
Then below my function:
public static String encodeStringMD5(String s) throws Exception {
byte[] bytes = s.getBytes();
MD5Digest digest = new MD5Digest();
digest.update(bytes, 0, bytes.length);
int length = digest.getDigestLength();
byte[] md5 = new byte[length];
digest.getDigest(md5, 0, true);
return convertToHex(md5);
}
private static String convertToHex(byte[] data) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; i++) {
int halfbyte = (data[i] >>> 4) & 0x0F;
int two_halfs = 0;
do {
if ((0 <= halfbyte) && (halfbyte <= 9))
buf.append((char) ('0' + halfbyte));
else
buf.append((char) ('a' + (halfbyte - 10)));
halfbyte = data[i] & 0x0F;
} while(two_halfs++ < 1);
}
return buf.toString();
}
So it returns something like this: 07054da3aea1cc98377fe0..........
Any idea how I can get the same hashed password that I create with my C# function in the Blackberry?
Thank you!
The getBytes() method of java String returns a different encoding than the Encoding.Unicode in .NET. You need to specify unambiguous encoding algorithms. Use UTF-8 for both platforms and you should be ok. You can also try providing a charset name to the getBytes method on the Java side; try getBytes("UTF-16")
GregS answered your question directly; but as an aside I would recommend against having the client create the MD5 sum. If the server manages creating the MD5sum, you can further ensure that the password can't be reverse engineered (eg rainbow table) by adding a "salt" value to the password before encoding it on the server. If you do that on the client, you must expose the salt to the client which is less secure.
Do you check the format? Many languages create the same hashes but in different formats.
For example:
5f45r5ssfds544g56fd4gfd56g4f6dgf
vs.
5f-45-r5-ss-fd-s5-44-g5-6f-d4-gf-d5-6g-4f-6d-gf
Try checking for both formats when converting to a string.