如何将十六进制值转换为Rust中的Base64

时间:2014-10-03 19:25:59

标签: hex base64 rust

我在理解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}}获得缓冲区,到目前为止仍然没有运气。

4 个答案:

答案 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

OkErrunwrap的类型,通常从无法计算结果的方法返回。在上述情况下,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]