Rust UTF-8错误,线程“ main”惊恐地被称为“ Result :: unwrap()”

时间:2018-11-15 18:11:39

标签: utf-8 rust

我正在研究cryptopals challenge set 1 challenge 3

  

十六进制编码的字符串:

     
1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736
     

...已针对单个字符进行XOR。找到密钥,解密消息。

     

您可以手动执行此操作。但是请不要:编写代码为您做到这一点。

     

如何?设计一些“计分”英文明文的方法。字符频率是一个很好的指标。评估每个输出并选择得分最高的输出。

我已经对此进行了编程:

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

我不知道是什么问题。

2 个答案:

答案 0 :(得分:0)

我通过更改此方法解决了

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);

}

答案 1 :(得分:0)

您应该检查所获得的字符串是否为有效的UTF-8字符串。 Ext.define('Fiddle.view.ActionFormTree', { extend: 'Ext.form.Panel', alias: 'widget.actionformtree', xtype: 'actionform',//mainform, initComponent: function(){ var me = this; Ext.apply(me,{ items: [{ xtype: 'form', border: false, anchor: '100%', height: 100, layout: { type: 'vbox', align: 'middle', pack: 'center' }, items: [{ xtype: 'textfield', name: 'text', fieldLabel: 'Наименование', itemId: 'name_field', }, { xtype: 'textfield', name: 'code', fieldLabel: 'Код', itemId: 'code_field', }] }], buttons: [{ text: 'Save Changes', scope: me, handler: function (button) { //Эта панель со значениями полей form = me.down('form'); var mainpanel = me.up('#maincontainer'); var treeform = mainpanel.down('usertree'); var sel = treeform.getSelectionModel().getSelection()[0]; store = treeform.getStore(); console.log(treeform) store.suspendAutoSync() var child = sel.set({ text: 'Измененное', leaf: true }); sel.expand() store.resumeAutoSync(); //var currRecord = form.getRecord(); //if (currRecord) { // form.updateRecord(); // form.reset(); //} } }] }); me.callParent(arguments); } }); 将为您检查并返回String::from_utf8Ok(s)。 然后,您应该在返回值上进行匹配,并打印解码后的字符串或报告失败。这样的事情可以解决问题。

Err(_)