2014-10-03 32 views
1

我在理解Rust中特徵的概念時遇到了一些問題。我試圖編碼一個簡單的十六進制值轉換爲Base64,但沒有運氣,這裏是我的代碼(有串爲Base64也是一個例子)如何將十六進制值轉換爲Rust中的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 

弗拉基米爾提供的解決方案適用於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>轉換爲字符串,然後使用as_bytes()得到緩衝區,到目前爲止還是沒有運氣。

+0

的'ToBase64'特質的唯一實施者是'&[U8]'(HTTP:/ /doc.rust-lang.org/serialize/base64/trait.ToBase64.html),因此在使用'to_base64()'之前,您需要將該數字轉換爲它。 – snf 2014-10-03 19:37:44

+0

謝謝@snf,剛剛更新到這個 '讓十六進制= 0x49276d2;' '讓整數=(十六進制)U8;!' '調用println( 「十六進制爲base64 = {}」,integer.to_base64(配置));' 但仍然沒有運氣 – 2014-10-03 19:44:57

+0

我沒有得到你想要做的,你想base64_encode「0x49276d2」或「\ x04 \ x92 \ x76 \ xd2」或其他? – snf 2014-10-04 00:53:19

回答

3

現在是2017年,並且rustc-serialize現在也已被棄用(請參閱here)。新的大型序列化庫叫做serde,但我認爲這對這個問題有點沉重。

這裏有一個快速的解決方案,手動從十六進制的String轉換爲Vec<u8>,然後使用this轉換爲base64編碼String

我不相信這個for循環是最好的解決方案,將hex的String轉換爲Vec<u8>,但我對Rust很新,這就是我的全部。意見/改進表示讚賞。

(嘿,等一下,我認識到這些編碼字符串,你在幹什麼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 
}  
1

我不確定你是什麼意思 - 將十六進制值轉換爲base64(fww沒有十六進制值這種東西 - 它只是另一種形式相同的文字數)。假設你要轉換從而彌補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值轉換成字節的小片endian格式。然後像往常一樣轉換爲base64。

如果您需要大端代表性,您需要將buf[i]更改爲buf[buf.len()-1-i]

+0

謝謝:)。確切地說,我只想了解如何在Rust中邁出第一步。謝謝你的解決方案它肯定適用於0x值(正如我所問)。現在我試圖用一個字符串來表示一個十六進制值,這需要我將它轉換爲一個字節向量(請參閱上面的更新)。 – 2014-10-04 07:57:06

+0

你認爲修改參數是個好主意 - 'buf [i] ='?相反,必須有另一個變量'let buf1 = buf; buf1 [i] = ...' – 2014-10-27 06:16:54

+0

@AlexanderSupertramp,爲什麼?我看不到這個臨時變量的原因。 – 2014-10-27 06:18:29

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是一種類型,它是OkErr,通常從無法計算結果的方法返回。在上述情況下,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)); 

請參閱documentation for Result其他方法。

+0

非常感謝你Robinst!因此,如果我理解正確,Rust最好的做法是在一個'包'中返回一個結果和錯誤,然後必須解包才能得到實際結果(或者在出錯時發生錯誤?) – 2014-10-04 09:19:26

+1

是的,我添加了更多解釋在答案中。其他語言有時會使用這種異常或多個返回值。 Rust有一個很好的方法,允許調用者以某種方式處理它。 – robinst 2014-10-04 09:34:46

+0

請注意,base64轉換函數已移至外部箱子:https://github.com/rust-lang/rustc-serialize – gsingh2011 2015-01-28 16:07:12

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

相關問題