You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 04:23:13