我正在研究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
我不知道是什么问题。
答案 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_utf8
或Ok(s)
。
然后,您应该在返回值上进行匹配,并打印解码后的字符串或报告失败。这样的事情可以解决问题。
Err(_)