我正在尝试创建一个R函数,它将接受种子和密钥长度来生成RC4密钥流。
以下是我到目前为止所掌握的:
library(numbers)
library(seqinr)
library(compositions)
rc4_genkey <- function(seed,keylength){
keystream <- vector(mode="integer", length=keylength)
# initialized S vector
s <- vector(mode="integer", length=255)
for(i in 1:255){
s[i + 1] = i+1
}
# initialize k vector with seed
key <- utf8ToInt(seed)
n <- length(key)
k <- vector(mode="integer", length=256)
for (i in 1:255){
k[i + 1] = key[mod(i+1, n)+1]
}
# Rc4 algorithm randomize 2 with 256 iterations
for (i in 1:255){
j <- (mod(j + s[i+1] + k[i+1], 256))
swap(s[i + 1], s[j])
}
# generate keystream of keystream length
for(i in 0:length(keystream)){
i <- mod((i + 1),256)
j <- mod((j + s[i]), 256)
swap(s[i+1],s[j+1])
t <- mod((s[i] + s[j]),256)
k[i] <- s[t]
keystream[i] <- k[i]
}
}
Now every time I run the function, it keeps telling me
"s[i + 1] <- s[j + 1] : replacement has length zero"希望能得到一些帮助来解决这个问题,以便运行正确的rc4加密
发布于 2020-03-06 17:24:14
我认为您在这里犯了很多错误: rc4是一个对称密码,所以您的rc4函数应该接受消息和密钥(而不是密钥长度),并返回一个字节流。
我猜您已经尝试将这个函数从低级的零索引语言转换为R。例如,您创建的状态向量s (在rc4中应该从0到255开始)应该是s <- 0:255的,而不是用循环编写的。
我之前写了一个rc4的C++实现,所以我在这里为你把它翻译成R。
如果结果中有非Ascii元素,此函数将返回一个原始向量,否则返回一个字符串,因此在大多数情况下,加密的消息将是原始格式,而未加密的消息将是字符串。不过,将其修改为只接受和返回原始向量是非常容易的。
rc4 <- function(message, key)
{
if(is.raw(message)) message <- as.integer(message)
if(is.character(message)) message <- utf8ToInt(message)
key <- utf8ToInt(key)
key_length <- length(key)
message_length <- length(message)
s <- 0:255
a <- b <- x <- y <- 0
if(key_length == 0) stop("No key given")
if(message_length == 0) return("")
for (i in seq_along(s))
{
b <- (key[a + 1] + s[i] + b) %% 256
tmp <- s[i]
s[i] <- s[b + 1]
s[b + 1] <- tmp
a <- (a + 1) %% key_length;
}
for (k in seq(message_length))
{
x1 <- x <- (x + 1) %% 256
y1 <- y <- (s[x + 1] + y) %% 256
tmp <- s[x1]
s[x1] <- s[y1]
tmp <- s[y1]
message[k] = bitwXor(message[k], s[(s[x1 + 1] + s[y1 + 1]) %% 256]);
}
if(any(message < 9 | message > 127)) return(as.raw(message))
return(intToUtf8(message))
}因此,让我们看看它是否有效:
encrypted_message <- rc4("hello", "world")
encrypted_message
#> [1] b7 31 74 99 98对于相同的密钥,它应该是可逆的:
rc4(encrypted_message, "world")
#> [1] "hello"https://stackoverflow.com/questions/60560412
复制相似问题