我在理解Rust中的特征概念时遇到了一些问题。我试图将一个简单的十六进制值编码为Base64,但没有运气,这是我的代码(也有一个字符串到Base64的例子)
extern crate serialize;
use serialize::base64::{ToBase64, STANDARD};
use serialize::hex::{FromHex, ToHex};
fn main () {
let stringOfText = "This is a String";
let mut config = STANDARD;
println!("String to base64 = {}", stringOfText.as_bytes().to_base64(config));
// Can't figure out this
Vladimir提供的解决方案适用于0x标记的十六进制值。现在我想要转换以字符串表示的十六进制值:
extern crate serialize;
use serialize::base64::{ToBase64, STANDARD};
use serialize::hex::{FromHex, ToHex};
fn main () {
let stringOfText = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";
let mut config = STANDARD;
println!("String to base64 = {}", stringOfText.from_hex().from_utf8_owned().as_bytes().to_base64(config));
// result should be: SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t
}
from_hex()
给了我一个Vec<u8>
,.to_base64()
期待缓冲区为u8,
我首先考虑将Vec<u8>
转换为字符串,然后使用{ {1}}获得缓冲区,到目前为止仍然没有运气。
答案 0 :(得分:6)
Rust目前正在发展,已接受的答案不再适用。具体来说,extern crate
语句不允许引用参数,并且rustc-serialize包的名称现在为rustc_serialize
。
以下代码正确base64对字符串进行编码,产生的结果与接受的答案相同(rustc 1.3.0):
extern crate rustc_serialize as serialize;
use serialize::base64::{self, ToBase64};
use serialize::hex::FromHex;
fn main() {
let input = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";
let result = input.from_hex().unwrap().to_base64(base64::STANDARD);
println!("{}", result);
}
结果:
SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t
答案 1 :(得分:4)
有关更新的问题,请尝试以下操作:
extern crate "rustc-serialize" as serialize;
use serialize::base64::{self, ToBase64};
use serialize::hex::FromHex;
fn main() {
let input = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";
let result = input.from_hex().unwrap().as_slice().to_base64(base64::STANDARD);
println!("{}", result);
}
(请注意,序列化现在位于外部包装箱中,请参阅rustc-serialize。感谢gsingh2011。)
from_hex
会返回Result<Vec<u8>, FromHexError>
,该Vec<u8>
会被解包到&[u8]
,然后用as_slice()
作为Result
。
Ok
是Err
或unwrap
的类型,通常从无法计算结果的方法返回。在上述情况下,Ok
用于获取Ok
值。如果结果不是match input.from_hex() {
Ok(result) => println!("Yay: {}", result.as_slice().to_base64(base64::STANDARD)),
Err(error) => println!("Nay: {}", error)
}
,则会失败(通过从字符串中删除其中一个字母来尝试)。
根据您的程序执行的操作,应使用匹配显式处理错误情况:
unwrap_or
或者,如果您只想继续使用默认值,则可以使用println!("{}", input.from_hex().unwrap_or(vec!()).as_slice().to_base64(base64::STANDARD));
:
{{1}}
有关其他方法,请参阅documentation for Result。
答案 2 :(得分:4)
现在是2017年,现在也不推荐使用rustc-serialize(请参阅here)。新的大型序列化库名为serde,但我认为这个问题有点重。
这是一个快速解决方案,可以手动从String
十六进制转换为Vec<u8>
,然后使用this转换为base64编码的String
。
我不相信这个for循环是将String
十六进制转换为Vec<u8>
的最佳解决方案,但我对Rust来说相当新,这就是我和#39;得到了。赞赏评论/改进。
(嘿,等一下,我知道这些编码的字符串,你在做cryptopals吗?)
extern crate base64;
use std::u8;
use self::base64::{encode};
pub fn hex_to_base64(hex: String) -> String {
// Make vector of bytes from octets
let mut bytes = Vec::new();
for i in 0..(hex.len()/2) {
let res = u8::from_str_radix(&hex[2*i .. 2*i+2], 16);
match res {
Ok(v) => bytes.push(v),
Err(e) => println!("Problem with hex: {}", e),
};
};
encode(&bytes) // now convert from Vec<u8> to b64-encoded String
}
答案 3 :(得分:1)
我不确定你是什么意思 - 将十六进制值转换为base64(fwiw没有十六进制值这样的东西 - 它只是同一个字面数的另一种形式)。假设您要转换构成int
值的字节,您可以执行以下操作:
extern crate serialize;
use std::mem;
use serialize::base64::{mod, ToBase64};
fn decompose_int(n: int, buf: &mut [u8]) {
assert!(mem::size_of::<int>() == buf.len());
for i in range(0, buf.len()) {
buf[i] = ((n >> i*8) & 0xFF) as u8;
}
}
fn main() {
let mut bytes = [0u8, ..8];
let x = 0x1122334455667788;
decompose_int(x, &mut bytes);
println!("{}", bytes.to_base64(base64::STANDARD));
}
(试试here)
此处decompose_int
函数将int
值序列化为小端格式的字节片。然后像往常一样将此切片转换为base64。
如果您需要大端代表,则需要将buf[i]
更改为buf[buf.len()-1-i]
。