2014-12-03 78 views
3

在R,什麼是一種有效的方式,以十六進制編碼的字符串轉換,如"40414243"爲其等效的字符例如一字符串"@ABC"解碼以十六進制表示

例如,該代碼相當於:

library(stringr) 

FromHexString <- function (hex.string) { 
    result <- "" 
    length <- str_length(hex.string) 
    for (i in seq(1, length, by=2)) { 
    hex.value <- str_sub(hex.string, i, i + 1) 
    char.code <- strtoi(hex.value, 16) 
    char <- rawToChar(as.raw(char.code)) 
    result <- paste(result, char, sep="") 
    char 
    } 
    result 
} 

主要生產:

> FromHexString("40414243") 
[1] "@ABC" 

雖然上面的代碼工作,這不是有效的,在所有的,使用了大量的字符串連接的。

所以問題是如何編寫一個慣用的,高效的R函數來做這個操作

編輯:我的樣品僅適用於ASCII編碼,而不是UTF-8編碼的字節數組。

回答

4

測試,如果這是更有效的(對於更長的字符串):

string <- "40414243" 

intToUtf8(
    strtoi(
    do.call(
     paste0, 
     as.data.frame(
     matrix(
      strsplit(string, split = "")[[1]], 
      ncol=2, 
      byrow=TRUE), 
     stringsAsFactors=FALSE)), 
    base=16L) 
) 
#[1] "@ABC" 

否則,你可以找一個C/C++實現。

+0

(+1)雖然我認爲你應該把它轉換成一個功能,否則它是很難用它適當 – 2014-12-03 13:28:30

+0

Dang-你打我由90秒*和*寫了一個更清潔的實現! – 2014-12-03 13:28:38

+0

@DavidArenburg當然,這裏的答案很多。它留給讀者作爲練習。 – Roland 2014-12-03 13:29:56

1

修改代碼,以便它使用lookup tablesR here一個例子。您的查找表將有255個值。將它們放入矢量中,並從該矢量中獲取它們的值。

不可:沒有其他的解決辦法會打這一個,如果你需要做大量的轉換。

1

如果你不想使用查找表(或者僅僅是想codegolfing :-)),考慮寫的像一個矢量版本:

bar <- unlist(strsplit(foo,'')) #separates input into individual elements 
items <- sapply(1:(length(bar)/2),function(j)paste0(bar[(2*j-1):(2*j)],sep='',collapse='')) 

隨後與strtoi或什麼的。

但更容易(我希望...)是

sapply(1:(nchar(foo)/2) function(j) substr(foo,(2*j-1),(2*j))) 
+0

使用'sapply'!=矢量化。 – Roland 2014-12-03 13:28:47

+0

@Roland我的草率語法 - 我的意思是寫一個用'sapply'執行的任務的矢量化版本。 – 2014-12-03 13:29:54

+0

謝謝。在擺弄你的答案之後,這個工作:intToUtf8(strtoi(sapply(1:(nchar(string)/ 2),function(j)paste0(unlist(strsplit(string,''))[(2 * j-1 ):(2 * j)],sep ='',collapse ='')),base = 16))'。 – 2014-12-03 14:24:46