Hex转ASCII后TextField长度翻倍问题求助
问题描述
将十六进制(Hex)值转换为ASCII后传入TextField,发现文本长度出现翻倍情况。预期两个TextField的总字符数为16,但实际显示为32。相关代码如下:
转换代码
String hexToAscii(String hexString) => List.generate( hexString.length ~/ 2, (i) => String.fromCharCode( int.parse(hexString.substring(i * 2, (i * 2) + 2), radix: 16)), ).join();
TextField构建代码
final modelController = TextEditingController(); modelController.text = hexToAscii(tempData[0]); // 传入转换后的数据,替换hexToAscii方法后问题依旧 _buildExpandableContent(int selectedENPIndex) { List<Widget> columnContent = []; for (int i = 0; i < namePlates[selectedENPIndex].contents.length; i++) { TextEditingController dynamicController = TextEditingController(); var allowedCharacters = namePlates[selectedENPIndex].acceptingString[i]; var allowedRegEx = RegExp(escape(allowedCharacters)); 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, cursorColor: _selectedTheme.primaryColorDark, 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; }
Dart Pad测试代码
void main() { var hexString = "004D006F00640065006C0020004D006F00640065006C0020004D006F00640065"; print(hexToAscii(hexString)); // 输出为 Model Model Mode print(hexToAscii(hexString).length); // 输出为32,预期应为16 } String hexToAscii(String hexString) => List.generate( hexString.length ~/ 2, (i) => String.fromCharCode( int.parse(hexString.substring(i * 2, (i * 2) + 2), radix: 16)), ).join();
原因解析
你的十六进制字符串采用的是UTF-16LE(小端序)编码,而非ASCII编码。观察测试用的hexString:004D006F00640065...,每4位十六进制(2字节)对应一个实际字符,其中低字节是字符的ASCII值,高字节为00。
但当前的转换代码是将每2位十六进制单独转成一个ASCII字符,这就把高字节的00转成了不可见的空字符(U+0000)。这些空字符肉眼无法察觉,但会被计入文本长度,最终导致实际长度翻倍。
解决方案
需要将十六进制字符串按UTF-16LE解码,而非ASCII解码。修改转换代码如下:
import 'dart:convert'; String hexToUtf16le(String hexString) { final bytes = List<int>.generate( hexString.length ~/ 2, (i) => int.parse(hexString.substring(i * 2, i * 2 + 2), radix: 16), ); return utf16le.decode(bytes); }
替换原有的hexToAscii方法后,测试代码的输出长度会变为16,符合预期。
内容的提问来源于stack exchange,提问作者Microcad
相关产品推荐
相关产品推荐

