![](/img/trans.png)
[英]How to decode Unicode escape sequences like “\u00ed” to proper UTF-8 encoded characters?
[英]Is it possible to decode bytes to UTF-8, converting errors to escape sequences in Rust?
在Rust中,通过这样做可以从字节中获取UTF-8:
if let Ok(s) = str::from_utf8(some_u8_slice) {
println!("example {}", s);
}
这可能有效,也可能没有,但Python有能力处理错误,例如:
s = some_bytes.decode(encoding='utf-8', errors='surrogateescape');
在此示例中,参数surrogateescape
将无效的utf-8序列转换为转义码,因此它们不是忽略或替换无法解码的文本,而是用字节文字表达式替换,该表达式是有效的utf-8
。 请参阅: Python文档了解详细信息。
Rust是否有办法从字节中获取UTF-8字符串,从而逃避错误而不是完全失败?
是的,通过String::from_utf8_lossy
:
fn main() {
let text = [104, 101, 0xFF, 108, 111];
let s = String::from_utf8_lossy(&text);
println!("{}", s); // he�lo
}
如果您需要对进程进行更多控制,可以使用std::str::from_utf8
,如另一个答案所示 。 但是,没有理由按照它的建议对字节进行双重验证。
一个快速被黑客攻击的例子:
use std::str;
fn example(mut bytes: &[u8]) -> String {
let mut output = String::new();
loop {
match str::from_utf8(bytes) {
Ok(s) => {
// The entire rest of the string was valid UTF-8, we are done
output.push_str(s);
return output;
}
Err(e) => {
let (good, bad) = bytes.split_at(e.valid_up_to());
if !good.is_empty() {
let s = unsafe {
// This is safe because we have already validated this
// UTF-8 data via the call to `str::from_utf8`; there's
// no need to check it a second time
str::from_utf8_unchecked(good)
};
output.push_str(s);
}
if bad.is_empty() {
// No more data left
return output;
}
// Do whatever type of recovery you need to here
output.push_str("<badbyte>");
// Skip the bad byte and try again
bytes = &bad[1..];
}
}
}
}
fn main() {
let r = example(&[104, 101, 0xFF, 108, 111]);
println!("{}", r); // he<badbyte>lo
}
您可以扩展它以获取值来替换坏字节,使用闭包来处理坏字节等。例如:
fn example(mut bytes: &[u8], handler: impl Fn(&mut String, &[u8])) -> String {
// ...
handler(&mut output, bad);
// ...
}
let r = example(&[104, 101, 0xFF, 108, 111], |output, bytes| {
use std::fmt::Write;
write!(output, "\\U{{{}}}", bytes[0]).unwrap()
});
println!("{}", r); // he\U{255}lo
也可以看看:
你可以:
通过使用严格的UTF-8解码自己构造它,该解码返回指示解码失败的位置的错误,然后您可以逃脱。 但这样做效率很低,因为您将对每次失败的尝试进行两次解码。
尝试提供更多可定制字符集解码器的第三方包装箱 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.