使用Dart将Uint8List转换为String

Man*_*ere 9 arrays string dart

cipher.process返回Uint8List,它是无符号整数列表(0-255).我需要将此Uint8List转换为一个字符串,我可以轻松地将其转换回相同的Uint8List.

    var cipherText = cipher.process( inputAsUint8List );        
    return ASCII.decode(cipherText);
Run Code Online (Sandbox Code Playgroud)

ASCII.decode抛出一个错误,因为一些整数> 127.

Gün*_*uer 17

我想这应该这样做:

String s = new String.fromCharCodes(inputAsUint8List);
var outputAsUint8List = new Uint8List.fromList(s.codeUnits);
Run Code Online (Sandbox Code Playgroud)

  • 这不适用于使用超过 2 个字节的 UTF8 字符,最好使用 dart:convert UTF8.encode()/decode()。 (6认同)
  • `cipher.process` 的输出是纯字节,因此您可以为它们选择任何有效的解释。使用 `UTF8.decode` 可能会中断,因为字节不是有效的 UTF-8,但 `String.fromCharCodes` 会将字节视为 Latin-1,它总是有效的。另一种可能性是将字节转换为 Uint16List,在每个字符中存储两个字节(但如果有奇数个字节,这会变得复杂)。 (2认同)
  • 如果输出只是普通字节,那么将它们显示为 base64 或十六进制可能是有意义的。 (2认同)

小智 15

Uint8List x;
Utf8Decoder().convert(x);
Run Code Online (Sandbox Code Playgroud)


Gre*_*owe 7

回答具体问题.我没有使用过cipher.process,也找不到文档.但是如果它只是返回原始字节,那么这些最好编码为十六进制或base64.

看看CryptoUtils.bytesToBase64CryptoUtils.bytesToHex.

要回答标题中的一般问题,如果Uint8List包含UTF8文本,则使用dart:convert库中的UTF8.decode().请参阅api文档.

import 'dart:convert';

main() {
  var encoded = UTF8.encode("Îñ?érñå?îöñå?îžå?î?ñ");
  var decoded = UTF8.decode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6,
                           0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]);
}
Run Code Online (Sandbox Code Playgroud)

String.fromCharCodes()将UTF-16代码单元列表作为输入.

另请参阅LATIN1,当输入<0xFF时,其行为与String.fromCharCodes相同.


Psy*_*hoX 6

Dart 使用 UTF-16 来存储Strings。目前,在 Dart 中,没有简单的方法可以轻松地将其转换为字节和向后转换。因此,您可以使用原始的计算转换StringUint8List和倒退。

飞镖代码:

import 'dart:typed_data';

void main() {
  // Source
  String source = 'Hello! Cze??! ??! ??????????! ?! !';
  print(source.length.toString() + ': "' + source + '" (' + source.runes.length.toString() + ')');

  // String (Dart uses UTF-16) to bytes
  var list = new List<int>();
  source.runes.forEach((rune) {
    if (rune >= 0x10000) {
      rune -= 0x10000;
      int firstWord = (rune >> 10) + 0xD800;
      list.add(firstWord >> 8);
      list.add(firstWord & 0xFF);
      int secondWord = (rune & 0x3FF) + 0xDC00;
      list.add(secondWord >> 8);
      list.add(secondWord & 0xFF);
    }
    else {
        list.add(rune >> 8);
        list.add(rune & 0xFF);
    }
  });
  Uint8List bytes = Uint8List.fromList(list);

  // Here you have `Uint8List` available

  // Bytes to UTF-16 string
  StringBuffer buffer = new StringBuffer();
  for (int i = 0; i < bytes.length;) {
    int firstWord = (bytes[i] << 8) + bytes[i + 1];
    if (0xD800 <= firstWord && firstWord <= 0xDBFF) {
      int secondWord = (bytes[i + 2] << 8) + bytes[i + 3];
      buffer.writeCharCode(((firstWord - 0xD800) << 10) + (secondWord - 0xDC00) + 0x10000);
      i += 4;
    }
    else {
        buffer.writeCharCode(firstWord);
      i += 2;
    }
  }

  // Outcome
  String outcome = buffer.toString();  
  print(outcome.length.toString() + ': "' + outcome + '" (' + outcome.runes.length.toString() + ')');
}
Run Code Online (Sandbox Code Playgroud)

结果:

52: "Hello! Cze??! ??! ??????????! ?! !" (43)
52: "Hello! Cze??! ??! ??????????! ?! !" (43)
Run Code Online (Sandbox Code Playgroud)

在线运行