How to read byte array data in Dart? - dart

connecting TCP Socket server and sending Request. and also Server sends the response in Byte array. How to read byte array data in dart.
Socket.connect('localhost', 8081)
.then((socket) {
//Establish the onData, and onDone callbacks
socket.listen((data) {
print(new String.fromCharCodes(data).trim()); //Here data is byte[]
//How to read byte array data
},
onDone: () {
print("Done");
// socket.destroy();
},
onError: (e) {
print('Server error: $e');
});
socket.add([255, 12, 0, 11, 0, 9, 34, 82, 69, 70, 84, 65, 72, 73, 76]);
});
}

It depends on with data type was encoded to bytes. Let's suppose it's String
Then you can do it with dart:convert library.
import 'dart:convert' show utf8;
final decoded = utf8.decode(data);

It's pretty clear that there's a message structure in those bytes. You give two examples of messages:
[255, 12, 0, 11, 0, 9, 34, 82, 69, 70, 84, 65, 72, 73, 76]
and
[255, 20, 0, 11, 0, 0, 0, 15, 80, 82, 69, 77, 84, 65, 72, 73, 76, 45, 53, 53, 57, 55, 48]
Both start with 255, followed by what looks like two or three little endian 16 bit words (12 and 11) and (20, 11 and 0) followed by a string, who's length is encoded in a leading byte. If you are expected to inter-operate with another system, you really need the protocol spec.
Assuming I've guessed the structure correctly, this code
main() {
Uint8List input = Uint8List.fromList([
255,
20,
0,
11,
0,
0,
0,
15,
80,
82,
69,
77,
84,
65,
72,
73,
76,
45,
53,
53,
57,
55,
48
]);
ByteData bd = input.buffer.asByteData();
print(bd.getUint16(1, Endian.little)); // print the first short
print(bd.getUint16(3, Endian.little)); // and the second
print(bd.getUint16(5, Endian.little)); // and the third
int stringLength = input[7]; // get the length of the string
print(utf8.decode(input.sublist(8, 8 + stringLength))); // decode the string
}
produces
20
11
0
PREMTAHIL-55970
as expected

Related

How to convert a byte array to a double (float value) in Dart

Based on this question, I have a list of bytes in Dart:
final data = [123, 34, 106, 115, 111, 110, 114, 112, 99, 34, 58, 34, 50, 46, 48, 34, 44, 34, 109, 101, 116, 104, 111, 100, 34, 58, 34, 115];
It represents a Float32 value from TensorFlow Lite. How do convert that to a readable double value?
Your data contains 28 bytes, and since it represents 32-bit float values (each of which are 4 bytes), that's equivalent to seven 32-bit values.
final data = [
123, 34, 106, 115, // 1
111, 110, 114, 112, // 2
99, 34, 58, 34, // 3
50, 46, 48, 34, // 4
44, 34, 109, 101, // 5
116, 104, 111, 100, // 6
34, 58, 34, 115, // 7
];
The ByteData class from the dart:typed_data library gives you different views on byte data. What you want is the Float32 view, which will give you a double in Dart.
final bytes = Uint8List.fromList(data);
final byteData = ByteData.sublistView(bytes);
double value = byteData.getFloat32(0);
print(value); // 8.433111377393183e+35
The 0 in getFloat32(0) means that you want to get the 32-bit float value starting at index 0 in the byte array. That only gives you the first value of the seven, though, so if you want the rest you need to loop though the entire byte list:
for (var i = 0; i < data.length; i += 4) {
print(byteData.getFloat32(i));
}
On every loop you increase the index by 4 to get the beginning of the next 32-bit float value. Run that loop and you'll see the results for all seven values:
8.433111377393183e+35
7.3795778785962275e+28
2.9925614505443553e+21
1.0139077133430874e-8
2.308231080230816e-12
7.366162972792583e+31
2.522593777484324e-18
See also
Working with bytes in Dart

Can't use .len of a bidimensional array

I have this simple code that doesn't compile.
const s = [_][_]int {
[_]int{08, 02, 22, 97, 38, 15, 00},
[_]int{49, 49, 99, 40, 17, 81, 18},
[_]int{81, 49, 31, 73, 55, 79, 14},
[_]int{52, 70, 95, 23, 04, 60, 11},
[_]int{22, 31, 16, 71, 51, 67, 63},
[_]int{24, 47, 32, 60, 99, 03, 45},
[_]int{32, 98, 81, 28, 64, 23, 67},
[_]int{67, 26, 20, 68, 02, 62, 12},
[_]int{24, 55, 58, 05, 66, 73, 99},
[_]int{21, 36, 23, 09, 75, 00, 76}
};
pub fn main() void
{
const w = s[0].len;
const h = s.len;
}
The compiler says:
./a.zig:1:14: error: inferred array size invalid here
const s = [_][_]int {
^
./a.zig:16:15: note: referenced here
const w = s[0].len;
What is the problem?
I'd be interested to know there's a deeper reason, but my simple understanding is that the current syntax [N]T allows for the array size to be elided using _, but not for more than one dimension.
So you can fix your problem using the following (N.B. I've used u8 because I'm unsure what your int is):
const s = [_][7]u8{
// Your items
}
I suspect this is because of the way the parsing rules are applied, so [7]u8 would be the type your nested array would hold, and will be used by the compiler to check contents are all of type [7]u8; you can confirm this by modifying one of your rows to have 6 elements and examining the resulting error.
If you want a variable number of items, you could start to look into an array of slices: [_][]u8, but I don't think that's what you're currently after.

Dart Bech32 and Hex encoding and decoding

I'm trying to decode this Bech32 address into a hex.
When given cosmos1qpjrq625nglf3xx9chdkq953nhrd3nygte44rt. It breaks it down into it's head which is 'cosmos' and the remainder is represented as a List of 8-bit unsigned integers (Uint8List).
When this is encoded to hexadecimal (HEX.Encode), i get a value of 00011203001a0a1413081f091106060518170d16000514111317030d11130408.
However, it is meant to be getting me 00643069549a3e9898c5c5db6016919dc6d8cc88 instead.
You can check this if you go to https://slowli.github.io/bech32-buffer/ -> and decode cosmos1qpjrq625nglf3xx9chdkq953nhrd3nygte44rt which gives 00643069549a3e9898c5c5db6016919dc6d8cc88.
I can't figure out the issue, is it perhaps
-The formatting is wrong, different bases? or am i doing this completely wrong.
Thanks and i appreciate any replies
Here is a snippet of code;
import 'package:bech32/bech32.dart';
import 'package:hex/hex.dart';
Bech32Codec bech32codec = Bech32Codec();
// target address : 00643069549a3e9898c5c5db6016919dc6d8cc88 -> to get to this address
String address = 'cosmos1qpjrq625nglf3xx9chdkq953nhrd3nygte44rt';
Bech32 bech32 = bech32codec.decode(address);
print(bech32.data);
// this returns [0, 1, 18, 3, 0, 26, 10, 20, 19, 8, 31, 9, 17, 6, 6, 5, 24, 23, 13, 22, 0, 5, 20, 17, 19, 23, 3, 13, 17, 19, 4, 8]
print(bech32.hrp);
print(bech32codec.encode(Bech32("cosmos", bech32.data)));
var answer2 = HEX.encode(bech32.data);
print(answer2);
var decode = HEX.decode('00643069549a3e9898c5c5db6016919dc6d8cc88');
print(decode);
// this returns [0, 100, 48, 105, 84, 154, 62, 152, 152, 197, 197, 219, 96, 22, 145, 157, 198, 216, 204, 136]

Unable to convert hex string to uint8 byte array

i need to convert hex string to byte array using swift. I have tried with following example hex string
"7B737369643A32333A34333A34353A31352C70617373776F72643A31323334357D"
This is my code
func sendCmd (CMD: [UInt8],length: Int ,hexString: String)
{
var tosend = Array<UInt8>()
var lenval = Array<UInt8>(repeating: 0, count: 2)
lenval[0] = (UInt8)(length & 0xff)
lenval[1] = (UInt8)((length >> 8) & 0xff)
tosend.append(CMD[0])
tosend.append(CMD[1])
tosend.append(lenval[0])
tosend.append(lenval[1])
}
I got output like this
[123, 115, 115, 105, 100, 58, 50, 51, 58, 52, 51, 58, 52, 53, 58, 49, 53, 44, 112, 97, 115, 115, 119, 111, 114, 100, 58, 49, 50, 51, 52, 53, 125]
But i need to get output like this
[0x7B, 0x73, 0x73, 0x69, ......]
and finally i have to append output array to "tosend" byte array(Array).
Any idea?

Swift converting signed array of Int [int8] to unsigned array of Int [UInt8]

How to convert signed array of [Int8] to unsigned array of [UInt8].
let arryData: [Int8] = [-108, 11, -107, -14, 35, -57, -116, 118, 54, 91, 12, 67, 21, 29, -44, 111]
I just want to convert this above into array of Unsigned [UInt8]. How to achieve this in swift.? Thanks in advance.
If your intention is to convert signed 8-bit integers to
unsigned ones with the same bit representation (e.g. -1 -> 255):
let intArray: [Int8] = [0, 1, 2, 127, -1, -2, -128]
let uintArray = intArray.map { UInt8(bitPattern: $0) }
print(uintArray)
// [0, 1, 2, 127, 255, 254, 128]
[Int8] -> [UInt8]
You haven't specified how you want to treat negative values; by flipping them to their positive counterpart or by removing them. Below follows both cases.
Transforming negative values to positive ones by flipping sign:
let arrayData: [Int8] = [-108, 11, -107, -14, 35, -57, -116, 118, 54, 91, 12, 67, 21, 29, -44, 111]
let arrayDataUnsigned = arrayData.map { UInt8(abs($0)) }
/* [108, 11, 107, 14, 35, 57, 116, 118, 54, 91,
12, 67, 21, 29, 44, 111] */
Or, by removing the negative values:
let arrayDataUnsigned = arrayData.flatMap { $0 < 0 ? nil : UInt8($0) }
/* [11, 35, 118, 54, 91, 12, 67, 21, 29, 111] */

Resources