[英]Rust UTF-8 error, thread 'main' panicked at 'called `Result::unwrap()
我正在处理密码挑战集 1 挑战 3 :
十六进制编码的字符串:
1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736
... 已对单个字符进行异或运算。 找到密钥,解密消息。
您可以手动执行此操作。 但不要:编写代码来为你做这件事。
如何? 设计一些方法来“评分”一段英文明文。 字符频率是一个很好的指标。 评估每个输出并选择得分最高的输出。
我已经编程了这个:
extern crate num_traits;
use num_traits::pow;
use std::io;
fn main() {
let mut hex_string = String::new();
let mut bin_string = String::new();
let mut vec_bin: Vec<String> = Vec::new();
let mut vec_plain: Vec<String> = Vec::new();
println!("Please enter the string: ");
io::stdin()
.read_line(&mut hex_string)
.expect("Failed to read line");
bin_string = string_to_hex(hex_string.trim());
for i in 0..256 {
let mut tmp = bin_string.clone();
vec_bin.push(xor(tmp, i));
}
for s in vec_bin {
let mut vec_utf8: Vec<u8> = Vec::new();
for i in 0..(s.len() / 8) {
vec_utf8.push(bits_to_int(s[(i * 8)..((i * 8) + 8)].to_string()));
}
vec_plain.push(String::from_utf8(vec_utf8).unwrap());
}
for s in vec_plain {
println!("{}", s);
}
}
fn string_to_hex(text: &str) -> String {
let mut hex_string = String::new();
for c in text.chars() {
hex_string.push_str(&hex_to_bits(c));
}
hex_string
}
fn hex_to_bits(c: char) -> String {
let mut result = String::new();
let x = c.to_digit(16).unwrap();
let mut tmp = x;
while tmp != 0 {
result = (tmp % 2).to_string() + &result;
tmp = tmp / 2;
}
while result.len() < 4 {
result = "0".to_string() + &result;
}
result
}
fn xor(s: String, u: u16) -> String {
let mut result = String::new();
let bin = dec_to_bin(u);
for i in 0..(s.len() / 8) {
let mut tmp = bin.clone();
result = result + &single_byte_xor(s[(i * 8)..((i * 8) + 8)].to_string(), tmp);
}
result
}
fn dec_to_bin(u: u16) -> String {
let mut result = String::new();
let mut tmp = u;
while tmp != 0 {
result = (tmp % 2).to_string() + &result;
tmp = tmp / 2;
}
while result.len() < 8 {
result = "0".to_string() + &result;
}
result
}
fn single_byte_xor(s: String, u: String) -> String {
let mut result = String::new();
for i in 0..s.len() {
if &s[i..(i + 1)] == "1" && &u[i..(i + 1)] == "1" {
result = result + &"0".to_string();
} else if &s[i..(i + 1)] == "1" || &u[i..(i + 1)] == "1" {
result = result + &"1".to_string();
} else {
result = result + &"0".to_string();
}
}
result
}
fn bits_to_int(s: String) -> u8 {
let mut result: u8 = 0;
let mut counter = 0;
for c in s.chars().rev() {
let x = c.to_digit(10).unwrap();
if x == 1 {
result += pow(2u8, counter);
}
counter += 1;
}
result
}
当我运行程序时,我收到此错误:
Please enter the string:
1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: FromUtf8Error { bytes: [155, 183, 183, 179, 177, 182, 191, 248, 149, 155, 255, 171, 248, 180, 177, 179, 189, 248, 185, 248, 168, 183, 173, 182, 188, 248, 183, 190, 248, 186, 185, 187, 183, 182], error: Utf8Error { valid_up_to: 0, error_len: Some(1) } }', /checkout/src/libcore/result.rs:916:5
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::print
at /checkout/src/libstd/sys_common/backtrace.rs:68
at /checkout/src/libstd/sys_common/backtrace.rs:57
2: std::panicking::default_hook::{{closure}}
at /checkout/src/libstd/panicking.rs:381
3: std::panicking::default_hook
at /checkout/src/libstd/panicking.rs:397
4: std::panicking::rust_panic_with_hook
at /checkout/src/libstd/panicking.rs:577
5: std::panicking::begin_panic
at /checkout/src/libstd/panicking.rs:538
6: std::panicking::begin_panic_fmt
at /checkout/src/libstd/panicking.rs:522
7: rust_begin_unwind
at /checkout/src/libstd/panicking.rs:498
8: core::panicking::panic_fmt
at /checkout/src/libcore/panicking.rs:71
9: core::result::unwrap_failed
at /checkout/src/libcore/macros.rs:23
10: <core::result::Result<T, E>>::unwrap
at /checkout/src/libcore/result.rs:782
11: nr3::main
at src/main.rs:24
12: std::rt::lang_start::{{closure}}
at /checkout/src/libstd/rt.rs:74
13: std::panicking::try::do_call
at /checkout/src/libstd/rt.rs:59
at /checkout/src/libstd/panicking.rs:480
14: __rust_maybe_catch_panic
at /checkout/src/libpanic_unwind/lib.rs:101
15: std::rt::lang_start_internal
at /checkout/src/libstd/panicking.rs:459
at /checkout/src/libstd/panic.rs:365
at /checkout/src/libstd/rt.rs:58
16: std::rt::lang_start
at /checkout/src/libstd/rt.rs:74
17: main
18: __libc_start_main
19: _start
我不知道是什么问题。
您应该检查您得到的字符串是否是有效的 UTF-8 字符串。 String::from_utf8
将为您检查并返回Ok(s)
或Err(_)
。 然后,您应该匹配返回值并打印解码后的字符串或报告失败。 像这样的事情可以解决问题。
use std::io;
fn main() {
let mut hex_string = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736";
let raw:Vec<u8> = hex_string_to_raw(hex_string);
for i in 0..255 {
// Get XOR'd version
let mut vec_utf8:Vec<u8> = raw.iter().map(|v| v ^ i ).collect();
// Try to decode it
let s = String::from_utf8(vec_utf8);
match s {
Err(_) => { println!("Failed to decode using {}", i); }
Ok(s) => { println!("Decoded with {} to '{}'", i, s); }
}
}
}
fn hex_string_to_raw(hex: &str) -> Vec<u8> {
let chars:Vec<char> = hex.chars().collect();
let mut raw:Vec<u8> = vec![];
for cs in chars.chunks(2) {
let c0:char = cs[0];
let c1:char = cs[1];
raw.push( (c0.to_digit(16).unwrap()*16 + c1.to_digit(16).unwrap()) as u8);
}
raw
}
我通过改变这个来解决它
for s in vec_bin {
let mut vec_utf8: Vec<u8> = Vec::new();
for i in 0..(s.len()/8) {
vec_utf8.push(bits_to_int(s[(i*8)..((i*8)+8)].to_string()));
}
vec_plain.push(String::from_utf8(vec_utf8).unwrap());
}
对此
for s in vec_bin {
let mut vec_utf8: Vec<u8> = Vec::new();
for i in 0..(s.len()/8) {
vec_utf8.push(bits_to_int(s[(i*8)..((i*8)+8)].to_string()));
}
let mut tmp = String::new();
tmp.push_str(&String::from_utf8_lossy(&vec_utf8));
vec_plain.push(tmp);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.