How to read a byte in Dart.? - flutter

I have below code in Java. How to implement this in Dart.?? Can someone help on this.?
//byte array
private byte[] data;
//read a byte
public byte readByte(){
byte x = data[offset];
offset ++;
return x;
}

You can use ByteData Class like following, this will create ByteArray of size 8, from which you can access the data by index like next line:
var bdata = new ByteData(8);
int huh = bdata.getInt32(0);

Related

Invalid or corrupted pad block

I am trying to use pointycastle package to decrypt a message using the below code
static String decrypt(String password, String ciphertext}) {
Uint8List derivedKey = deriveKey(password);
KeyParameter keyParam = KeyParameter(derivedKey);
BlockCipher aes = AESFastEngine();
Uint8List cipherIvBytes = base64.decode(ciphertext);
Uint8List iv =
Uint8List.fromList(HEX.decode("a4094fd5d6041eb3a7a77d7fa73ea329"))
..setRange(0, aes.blockSize, cipherIvBytes);
BlockCipher cipher = CBCBlockCipher(aes);
ParametersWithIV params = ParametersWithIV(keyParam, iv);
cipher.init(false, params);
int cipherLen = cipherIvBytes.length - aes.blockSize;
Uint8List cipherBytes = Uint8List(cipherLen)
..setRange(0, cipherLen, cipherIvBytes, aes.blockSize);
Uint8List paddedText = _processBlocks(cipher, cipherBytes);
log('before padding'); //works until this point
Uint8List textBytes = unpad(paddedText);
log(String.fromCharCodes(textBytes));
return String.fromCharCodes(textBytes);
}
below are the functions for _processBlocks and unpad
static Uint8List _processBlocks(BlockCipher cipher, Uint8List inp) {
var out = Uint8List(inp.lengthInBytes);
for (var offset = 0; offset < inp.lengthInBytes;) {
var len = cipher.processBlock(inp, offset, out, offset);
offset += len;
}
return out;
}
static Uint8List unpad(Uint8List src) {
var pad = PKCS7Padding();
pad.init(null);
int padLength = pad.padCount(src);
int len = src.length - padLength;
return Uint8List(len)..setRange(0, len, src);
}
My problem is when I try to decrypt the message I have it show me this error
Invalid argument(s): Invalid or corrupted pad block
this is a sample key and message
key : CE6C4B509712CAA6237B336A517B4245
message : pAlP1dYEHrOnp31/pz6jKSOBf/UwAYc31WqbPBhCGjXeMGfjxWqb8IC7U3yS/niViwhlot8vvMVGR9DvV9+Rchy3tsABb4NczP88JpfL8S9ifNGBc+d8dvOGFyB2K5cXLLaiTqA+ReEHbRtp0bOjisb/krwIzafnU3OaIbhl/nnsWmuhdpqNNem1ZPkrdhCMuQrdad6pU6cvg0yLdMZ6Z8PQUOoJ8e64n53Q4j88Gtey71cOt/vwW8aUlUbgG1D0tyu2VlWat5IAn5/AutX88Pu20YX9s3MPf4AAe5U40FKm34PerYzj3DjZX7/fafjoIIh4AZ1Vva36ooI2kF2GFsHbUpbOMUa5Gz61aca4wm0Jq7KdUH4GhMLkMCCEF+C5JPsRBnCo3Ickh3YZTHWbmy/63F7chcrqd8fxOCNMqqeaQhakFdeEIao47gpb62OLtpjTytLQgQ1rYjdbA+vdqdOy1ZV0CIepIRfNAy4Bge5ifMQLyaG2wha3GKO+f6+c7qmwSNAGY/mxKHNQP/eHemMf/uNOSiOE32IZ29L+3/Ckajgk+uOuO6xgBIAMzP40Eqh0l7uvZgbRUbt5Ws2Fw8QpnoOm0S2T2koA0MZPISaJdE5Gzdmfk5gxGVtOkEUqTMw69xAN7eMYHTd5cW6bbjEefijgH15GtgkzUXJb7LPDYO+rnwTHprHg/JRxeFzDnYQn9VjlBDCYzKa41qjo/Q==
What could be the problem here. And what are the possible solutions or workarounds for this error. Thanks in advance.

write float to EEPROM convert float to uint8_t

Hello I have two simple function to write value to EEPROM, but this don't work correctly. What am i doing wrong something with the conversion?
HAL_StatusTypeDef writeEEPROMByte(uint32_t address, uint8_t data) {
HAL_StatusTypeDef status;
address = address + EEPROM_BASE_ADDRESS;
HAL_FLASHEx_DATAEEPROM_Unlock(); //Unprotect the EEPROM to allow writing
status = HAL_FLASHEx_DATAEEPROM_Program(TYPEPROGRAMDATA_BYTE, address, data);
HAL_FLASHEx_DATAEEPROM_Lock(); // Reprotect the EEPROM
return status;
}
uint8_t readEEPROMByte(uint32_t address) {
uint8_t data = 0;
address = address + EEPROM_BASE_ADDRESS;
data = *(__IO uint32_t*)address;
return data;
}
void saveToEEPROM (uint32_t address, float data)
{
uint8_t *array;
array = (uint8_t*)(&data);
for(uint32_t i=0;i<4;i++) //float to array of uint8_t
{
writeEEPROMByte(address, array[i]);
}
}
float loadFromEEPROM (uint32_t address)
{
float value = 0;
uint8_t data[3];
for(uint32_t i=0;i<4;i++) //float to array of uint8_t
{
data[i] = readEEPROMByte(i+address);
}
value = *(float *)(&data);
return value;
}
Output for float is 64.00 or 65-70 for bigger numbers
Thanks for answers. I edited functions and change to double precision because I using atof(). But still I don't have good readout,
data[7-i] = readEEPROMByte(i+address);
Give better results e.g.
save - read
2 - 64,
3 - 2112,
4 - 4160,
void saveConfigToEEPROM (uint32_t address, double data)
{
uint8_t *array;
array = (uint8_t*)(&data);
for(int i=0;i<8;i++) //float to array of uint8_t
{
writeEEPROMByte(address+i, array[i]);
}
}
double loadConfigFromEEPROM (uint32_t address)
{
double value = 0;
uint8_t data[8];
for(int i=0;i<8;i++) //float to array of uint8_t
{
data[i] = readEEPROMByte(address+i);
}
value = *(double *)(&data);
return value;
}
In the loop in function saveToEEPROM you overwrite the same address repeatedly.
In the loop in loadFromEEPROM you read 4 bytes from 4 different addresses but try to save them in a buffer 3 bytes long.
Also, in readEEPROMByte you cast the address to uint32_t pointer, read a uint32_t and then return it as a uint8_t. This could be a misaligned read, which might be fine on this platform (you don't specify exactly which part you are using) but to be on the safe side and to make the code easier to read I would just do a byte read (cast to uint8_t pointer).
Similarly casting the array of bytes to float pointer in loadFromEEPROM is not good practice, but again might still be alright.

Converts a string into an array of bytes dart

I am consuming a web service that return an XML of data, how can i convert a string containing lexical representation xsd:hexBinary not base64 format to Uint8List, coming from java i can do this by :
import javax.xml.bind.DatatypeConverter;
....
byte[] decoder = DatatypeConverter.parseHexBinary(hexStringXls);
or
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;
}
Is this what you want?
final s = "somestring";
final List<int> bytes = s.codeUnits;
https://api.dart.dev/stable/2.8.4/dart-core/String/codeUnits.html

How do I use BER encoding with object System.DirectoryServices.Protocols.BerConverter.Encode("???", myData)

I need to encode and decode BER data. .NET has the class System.DirectoryServices.Protocols.BerConverter
The static method requires me to enter a string in the first parameter as shown below
byte[] oid = { 0x30, 0xD, 0x6, 0x9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0xD, 0x1, 0x1, 0x1, 0x5, 0x0 }; // Object ID for RSA
var result2 = System.DirectoryServices.Protocols.BerConverter.Decoding("?what goes here?", oid);
BER encoding is used in LDAP, Certificates, and is commonplace in many other formats.
I'll be happy with information telling me how to Encode or Decode on this class. There is nothing on Stack Overflow or the first few pages of Google (or Bing) regarding this.
Question
How do I convert the byte array above to the corresponding OID using BER decoding?
How can I parse (or attempt to parse) SubjectPublicKeyInfo ASN.1 data in DER or BER format?
It seems the DER encoding\decoding classes are internal to the .NET framework. If so, where are they? (I'd like to ask connect.microsoft.com to make these members public)
How do I convert the byte array above to the corresponding OID using BER decoding?
After you have extracted the OID byte array, you can convert it to an OID string using OidByteArrayToString(). I have included the code below, since I couldn't find a similar function in the .NET libraries.
How can I parse (or attempt to parse) SubjectPublicKeyInfo ASN.1 data in DER or BER format?
I was not able to find a TLV parser in the .NET SDK either. Below is an implementation of a BER TLV parser, BerTlv. Since DER is a subset of BER, parsing will work the same way. Given a BER-TLV byte[] array, it will return a list of BerTlv objects that support access of sub TLVs.
It seems the DER encoding\decoding classes are internal to the .NET framework. If so, where are they? (I'd like to ask connect.microsoft.com to make these members public)
Maybe somebody else can answer this question.
Summary
Here is an example of how you can use the code provided below. I have used the public key data you provided in your previous post. The BerTlv should probably be augmented to support querying like BerTlv.getValue(rootTlvs, '/30/30/06');.
public static void Main(string[] args)
{
string pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrEee0Ri4Juz+QfiWYui/E9UGSXau/2P8LjnTD8V4Unn+2FAZVGE3kL23bzeoULYv4PeleB3gfmJiDJOKU3Ns5L4KJAUUHjFwDebt0NP+sBK0VKeTATL2Yr/S3bT/xhy+1xtj4RkdV7fVxTn56Lb4udUnwuxK4V5b5PdOKj/+XcwIDAQAB";
byte[] pubkeyByteArray = Convert.FromBase64String(pubkey);
List<BerTlv> rootTlvs = BerTlv.parseTlv(pubkeyByteArray);
BerTlv firstTlv = rootTlvs.Where(tlv => tlv.Tag == 0x30).First();//first sequence (tag 30)
BerTlv secondTlv = firstTlv.SubTlv.Where(tlv => tlv.Tag == 0x30).First();//second sequence (tag 30)
BerTlv oid = secondTlv.SubTlv.Where(tlv => tlv.Tag == 0x06).First();//OID tag (tag 30)
string strOid = OidByteArrayToString(oid.Value);
Console.WriteLine(strOid);
}
Output:
1.2.840.113549.1.1.1
OID Encode/Decode
public static byte[] OidStringToByteArray(string oid)
{
string[] split = oid.Split('.');
List<byte> retVal = new List<byte>();
//root arc
if (split.Length > 0)
retVal.Add((byte)(Convert.ToInt32(split[0])*40));
//first arc
if (split.Length > 1)
retVal[0] += Convert.ToByte(split[1]);
//subsequent arcs
for (int i = 2; i < split.Length; i++)
{
int arc_value = Convert.ToInt32(split[i]);
Stack<byte> bytes = new Stack<byte>();
while (arc_value != 0)
{
byte val = (byte) ((arc_value & 0x7F) | (bytes.Count == 0 ? 0x0:0x80));
arc_value >>= 7;
bytes.Push(val);
}
retVal.AddRange(bytes);
}
return retVal.ToArray();
}
public static string OidByteArrayToString(byte[] oid)
{
StringBuilder retVal = new StringBuilder();
//first byte
if (oid.Length > 0)
retVal.Append(String.Format("{0}.{1}", oid[0] / 40, oid[0] % 40));
// subsequent bytes
int current_arc = 0;
for (int i = 1; i < oid.Length; i++)
{
current_arc = (current_arc <<= 7) | oid[i] & 0x7F;
//check if last byte of arc value
if ((oid[i] & 0x80) == 0)
{
retVal.Append('.');
retVal.Append(Convert.ToString(current_arc));
current_arc = 0;
}
}
return retVal.ToString();
}
BER-TLV Parser
class BerTlv
{
private int tag;
private int length;
private int valueOffset;
private byte[] rawData;
private List<BerTlv> subTlv;
private BerTlv(int tag, int length, int valueOffset, byte[] rawData)
{
this.tag = tag;
this.length = length;
this.valueOffset = valueOffset;
this.rawData = rawData;
this.subTlv = new List<BerTlv>();
}
public int Tag
{
get { return tag; }
}
public byte[] RawData
{
get { return rawData; }
}
public byte[] Value
{
get
{
byte[] result = new byte[length];
Array.Copy(rawData, valueOffset, result, 0, length);
return result;
}
}
public List<BerTlv> SubTlv
{
get { return subTlv; }
}
public static List<BerTlv> parseTlv(byte[] rawTlv)
{
List<BerTlv> result = new List<BerTlv>();
parseTlv(rawTlv, result);
return result;
}
private static void parseTlv(byte[] rawTlv, List<BerTlv> result)
{
for (int i = 0, start=0; i < rawTlv.Length; start=i)
{
//parse Tag
bool constructed_tlv = (rawTlv[i] & 0x20) != 0;
bool more_bytes = (rawTlv[i] & 0x1F) == 0x1F;
while (more_bytes && (rawTlv[++i] & 0x80) != 0) ;
i++;
int tag = Util.getInt(rawTlv, start, i-start);
//parse Length
bool multiByte_Length = (rawTlv[i] & 0x80) != 0;
int length = multiByte_Length ? Util.getInt(rawTlv, i+1, rawTlv[i] & 0x1F) : rawTlv[i];
i = multiByte_Length ? i + (rawTlv[i] & 0x1F) + 1: i + 1;
i += length;
byte[] rawData = new byte[i - start];
Array.Copy(rawTlv, start, rawData, 0, i - start);
BerTlv tlv = new BerTlv(tag, length, i - length, rawData);
result.Add(tlv);
if (constructed_tlv)
parseTlv(tlv.Value, tlv.subTlv);
}
}
}
Here is a utility class that contains some functions used in the class above. It is included for the sake of clarity how it works.
class Util
{
public static string getHexString(byte[] arr)
{
StringBuilder sb = new StringBuilder(arr.Length * 2);
foreach (byte b in arr)
{
sb.AppendFormat("{0:X2}", b);
}
return sb.ToString();
}
public static byte[] getBytes(String str)
{
byte[] result = new byte[str.Length >> 1];
for (int i = 0; i < result.Length; i++)
{
result[i] = (byte)Convert.ToInt32(str.Substring(i * 2, 2), 16);
}
return result;
}
public static int getInt(byte[] data, int offset, int length)
{
int result = 0;
for (int i = 0; i < length; i++)
{
result = (result << 8) | data[offset + i];
}
return result;
}
}

How do I save an UIImage as BMP?

Can I save (write to file) UIImage object as bitmap file (.bmp extension) in iPhone’s document directory?
Thanks in advance.
I don’t think BMP is supported on iPhone. Maybe somebody wrote a category for UIImage that does saving into BMP, but I don’t know about any. I guess You’ll have to get the bitmap data from the UIImage and write them yourself, BMP is quite a simple file format. All you have to do is write out the header and then the uncompressed data. The header is a structure called BITMAPINFOHEADER, see MSDN. Getting the bitmap data of an UIImage is described in Apple’s Technical Q&A1509.
Right now I am not concerned about the size. Just want to know can I write image data as .bmp file.
Realize this is an old post, but in case someone finds it like I did looking for a solution.
I basically needed to FTP UIImage as a small BMP, so I hacked this crude class in MonoTouch.
I borrowed from zxing.Bitmap.cs and Example 1 from wikipedia BMP article. It appears to work. Might have been slicker to do an extension like AsBMP() or something like that.
(I don't know what the objective-c equivalent is, but hopefully this is helpful to someone.)
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MonoTouch.CoreGraphics;
public class BitmapFileRGBA8888
{
public byte[] Data; // data needs to be BGRA
public const int PixelDataOffset = 54;
public BitmapFileRGBA8888(UIImage image)
{
CGImage imageRef = image.CGImage;
int width = imageRef.Width;
int height = imageRef.Height;
Initialize((uint)width, (uint)height);
CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB();
IntPtr rawData = Marshal.AllocHGlobal(height*width*4);
CGContext context = new CGBitmapContext(
rawData, width, height, 8, 4*width, colorSpace, CGImageAlphaInfo.PremultipliedLast
);
context.DrawImage(new RectangleF(0.0f,0.0f,(float)width,(float)height),imageRef); // RGBA
byte[] pixelData = new byte[height*width*4];
Marshal.Copy(rawData,pixelData,0,pixelData.Length);
Marshal.FreeHGlobal(rawData);
int di = PixelDataOffset;
int si;
for (int y = 0; y < height; y++)
{
si = (height-y-1) * 4 * width;
for (int x = 0; x < width; x++)
{
CopyFlipPixel(pixelData, si, Data, di);
di += 4; // destination marchs forward
si += 4;
}
}
}
private void CopyFlipPixel(byte[] Src, int Src_offset, byte[] Dst, int Dst_offset)
{
int S = Src_offset;
int D = Dst_offset + 2;
Dst[D--] = Src[S++]; // R
Dst[D--] = Src[S++]; // G
Dst[D--] = Src[S++]; // B
Dst[Dst_offset+3] = Src[S]; // alpha
}
private void Initialize(uint W, uint H)
{
uint RawPixelDataSize = W * H * 4;
uint Size = RawPixelDataSize + 14 + 40;
Data = new byte[Size];
Data[0] = 0x42; Data[1] = 0x4D; // BITMAPFILEHEADER "BM"
SetLong(0x2, Size); // file size
SetLong(0xA, PixelDataOffset); // offset to pixel data
SetLong(0xE, 40); // bytes in DIB header (BITMAPINFOHEADER)
SetLong(0x12, W);
SetLong(0x16, H);
SetShort(0x1A, 1); // 1 plane
SetShort(0x1C, 32); // 32 bits
SetLong(0x22, RawPixelDataSize);
SetLong(0x26, 2835); // h/v pixels per meter device resolution
SetLong(0x2A, 2835);
}
private void SetShort(int Offset, UInt16 V)
{
var byts = BitConverter.GetBytes(V);
if (!BitConverter.IsLittleEndian) Array.Reverse(byts);
Array.Copy(byts,0,Data,Offset,byts.Length);
}
private void SetLong(int Offset, UInt32 V)
{
var byts = BitConverter.GetBytes(V);
if (!BitConverter.IsLittleEndian) Array.Reverse(byts);
Array.Copy(byts,0,Data,Offset,byts.Length);
}
} // END CLASS
Basically
var Bmp = new BitmapFileRGBA8888(TempImage);
FTP.UploadBin(Bmp.Data, "test.bmp"); // or just write as binary file
Since BMP is not a compressed format, is this a good idea?
Presumably, image size is even more important on portable devices.