1

When I convert the hex value to ASCII and pass on the ASCII to textField, it doubles the text length. Below is the conversion I used and if you see from the screenshot, the total characters for both the textfields are 16, but it is showing as 32. May I know why the length is doubling? enter image description here

String hexToAscii(String hexString) => List.generate(
        hexString.length ~/ 2,
        (i) => String.fromCharCode(
            int.parse(hexString.substring(i * 2, (i * 2) + 2), radix: 16)),
      ).join();

// Adding Textfield

final modelController = TextEditingController();
modelController.text = hexToAscii(tempData[0]); // Passing Data. I used your method in place of hexToAscii method. No Change

    _buildExpandableContent(int selectedENPIndex) {
List<Widget> columnContent = [];

for (int i = 0; i < namePlates[selectedENPIndex].contents.length; i++) {
  TextEditingController dynamicController = TextEditingController();

  //var allowedCharacters = 'r\'^[a-zA-Z0-9. ]*\'';
  var allowedCharacters = namePlates[selectedENPIndex].acceptingString[i];
  //print("Allowed Characters: $allowedCharacters");

  var allowedRegEx = RegExp(escape(allowedCharacters));
  //print("Allowed RegEx: $allowedRegEx");
  if (selectedENPIndex == 0) {
    if (namePlates[selectedENPIndex]
            .contents[i]
            .replaceAll(RegExp('[^A-Za-z0-9]'), '')
            .toLowerCase() ==
        ENPTextFieldNames.model.name) {
      dynamicController = modelController;
    } 
  }



  columnContent.add(Container(
    padding: const EdgeInsets.only(left: 50, right: 50, bottom: 10),
    child: TextFormField(
      enableInteractiveSelection: false,
      maxLength: selectedENPIndex == 2 ? 24 : 16,
      // autofocus: true,
      cursorColor: _selectedTheme.primaryColorDark,

      // inputFormatters: <TextInputFormatter>[
      //   FilteringTextInputFormatter.allow(RegExp(allowedCharacters))
      // ],
      onChanged: (value) {
        checkRegEx();
        _selectedField = dynamicController;
      },
      controller: dynamicController,
      validator: (value) {
        if (value == null || value.trim().isEmpty) {
          return "Please enter ${namePlates[selectedENPIndex].contents[i]}";
        }
        return null;
      },
      decoration: InputDecoration(
          border: UnderlineInputBorder(
              borderSide:
                  BorderSide(color: _selectedTheme.primaryColorDark)),
          enabledBorder: UnderlineInputBorder(
              borderSide:
                  BorderSide(color: _selectedTheme.primaryColorDark)),
          focusedBorder: UnderlineInputBorder(
              borderSide: BorderSide(
                  color: _selectedTheme.primaryColorDark, width: 2)),
          labelText: namePlates[selectedENPIndex].contents[i],
          hintText: namePlates[selectedENPIndex].acceptingString[i],
          labelStyle: TextStyle(color: _selectedTheme.primaryColorDark)),
    ),
  ));
}
columnContent.add(const Padding(
  padding: EdgeInsets.only(top: 20, bottom: 20),
));

return columnContent;

} enter image description here //Dart Pad

void main() {
 var hexString = "004D006F00640065006C0020004D006F00640065006C0020004D006F00640065";
  
  print(hexToAscii(hexString)); // Output is Model Model Mode
  print(hexToAscii(hexString).length); // Output is 32, this should be 16. Attached the Dart Pad screenshot 
}


String hexToAscii(String hexString) => List.generate(
        hexString.length ~/ 2,
        (i) => String.fromCharCode(
            int.parse(hexString.substring(i * 2, (i * 2) + 2), radix: 16)),
      ).join();
6
  • 1
    use hex converter: import 'dart:convert'; import 'package:convert/convert.dart'; void main() { final string = ascii.fuse(hex).decode('68656c6c6f'); print('string: >$string<'); } Commented Jun 21, 2024 at 8:17
  • @pskink Thanks. I used your solution. It's still the same. Prints the length as 32 instead of 16 Commented Jun 21, 2024 at 8:53
  • modelController is not used anywhere in your code - you are only assigning modelController.text = hexToAscii(tempData[0]);, nothing more, post the minimal but complete code to reproduce your issue Commented Jun 21, 2024 at 12:32
  • 1
    You haven't showed what the input hex string is. How do we know that it isn't 64 hex digits? Your claim is that the hex conversion "doubles the length", but you haven't shown evidence that it has anything to do with the hex conversion at all. For example: debugPrint(tempData[0].length); debugPrint(hexToAscii(tempData[0]).length); Commented Jun 21, 2024 at 14:32
  • 1
    as you can see in 004D006F00640065006C0020004D006F00640065006C0020004D006F00640065 every even byte is 00 so the string is _M_o_d_e_l_ _M_o_d_e_l_ _M_o_d_e where _ represents unprintable 0x00 but the result you see in the TextFormField is: Model Model Mode Commented Jun 22, 2024 at 7:14

1 Answer 1

0

The issue you're facing is likely due to the presence of null characters (i.e., \u0000) in your ASCII string.

These null characters are often used as padding in UTF-16 encoding and may cause the text length to double when processed as a string in Dart.

You can improve your hexToAscii function by filtering out the null characters after converting the hex string to ASCII and ensuring the conversion process correctly handles the input string.

This should properly work for you.

String hexToAscii(String hexString) {
  // Convert hex string to ASCII, then remove null characters
  return List.generate(
    hexString.length ~/ 4, // Using ~/4 for UTF-16 (each char is 4 hex digits)
    (i) {
      var charCode = int.parse(hexString.substring(i * 4, (i * 4) + 4), radix: 16);
      return String.fromCharCode(charCode);
    },
  ).join().replaceAll('\u0000', '');
}

Alternatively, you can use the dart:convert package.

import 'dart:convert';
import 'dart:typed_data';

void main() {
  var hexString = "004D006F00640065006C0020004D006F00640065006C0020004D006F00640065";

  print(hexToAscii(hexString)); // Output should be "Model Model Model"
  print(hexToAscii(hexString).length); // Output should be 15
}

String hexToAscii(String hexString) {
  Uint8List bytes = hexStringToBytes(hexString);
  String asciiString = utf8.decode(bytes, allowMalformed: true);
  return asciiString.replaceAll('\u0000', '');
}

Uint8List hexStringToBytes(String hexString) {
  List<int> bytes = [];
  for (int i = 0; i < hexString.length; i += 4) {
    String byteString = hexString.substring(i, i + 4);
    int byte = int.parse(byteString, radix: 16);
    bytes.add(byte >> 8);
    bytes.add(byte & 0xFF);
  }
  return Uint8List.fromList(bytes);
}

Sign up to request clarification or add additional context in comments.

2 Comments

why to reinvent the wheel? it is as simple as this: import 'dart:convert'; import 'package:convert/convert.dart'; void main() { final codec = utf8.fuse(hex); final s1 = '5‰'; final inHex = codec.encode(s1); final s2 = codec.decode(inHex); print('s1: $s1 -> inHex: $inHex -> s2: $s2'); print('s1 == s2: ${s1 == s2}'); } - the "key" is here the codec: final codec = utf8.fuse(hex);
@Microcad your welcome, as you can see there is no need for any custom parsing - just use existing codecs

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.