【问题标题】:Obfuscate string in R在R中混淆字符串
【发布时间】:2016-08-22 10:37:01
【问题描述】:

我有一个存储在纯文本文件中的密码。我想以某种方式混淆它,以防有人在看我的显示器。

理想情况下,我想用另一个默认字符串(例如“123”)对密码进行加密,并获得密码的混淆版本。然后,当我在代码中需要密码时,我想用相同的字符串“123”解密密码。混淆密码和普通密码的长度不同也很好。

所以,逻辑应该是:

encrypt(password, "123") -> obf_string
decrypt(obf_string, "123") -> password

我该怎么做?

附:我知道无论如何它都不安全,但这就是我现在想要的。

【问题讨论】:

标签: r encryption


【解决方案1】:

一种快速的混淆方法是通过随机数生成,这是我的尝试:

encrypt <- function(password, string){
        set.seed(password)
        encr <- round(runif(nchar(string), 0, 9))
        y <- as.integer(substring(string, seq(nchar(string)), seq(nchar(string)))) + encr
        return(y)
}

decrypt <- function(password, string){
        set.seed(password)
        encr <- round(runif(nchar(string), 0, 9))
        y <- paste0(string - encr, collapse="")
        return(y)
}

您的字符串是例如1984。您只需要选择一个密码,例如2016.

> encrypt(2016, "1984")
[1]  3 10 16  5

您将它们提供给encrypt(),该函数将返回一个与您的字符串大小相同的数字向量。要取回字符串,请使用 decrypt() 以及您的密码和向量:

> decrypt(2016, c(3,10,16,5))
[1] "1984"

一个不那么天真的替代方案,进一步允许文本连接,是通过base64 编码/解码,使用base64enc 包:

install.packages("base64enc")
library(base64enc)
base64encode(c(2,0,0,6))
base64decode("AgAABg==")

【讨论】:

  • 好主意!加密时是否可以消除安装额外的包以立即获取字符串?
  • 我看到set.seed 只解释整数,而不是字符串。有什么办法改吗?
  • @000andy8484 Base64 只是一种编码,几乎不安全。
  • 正如我所说,我需要混淆。我不在乎安全。
  • 我不明白,肯定在字符串向量上运行 as.integer 只会返回警告和 NA 向量?
【解决方案2】:

跟进@zach cmets,如果发生攻击,此过程将不安全。如果您想混淆一个字符串(例如,来自路过并看着屏幕的人),这非常有用,这个问题并不暗示安全性。

我在上一个答案中报告的函数的这个版本也接受带有数字和字母的字符串:

obfuscate <- function(password, string){
        set.seed(password)
        vec <- substring(string, seq(nchar(string)), seq(nchar(string)))
        encr <- y <- vector("list",length(vec))
        letters <- rep(letters,2)   # prolongue letters sequence
        for (i in 1:length(vec)){
                ifelse(is.numeric(vec[i]),             # extracting encryption numbers 
                       encr[[i]] <- round(runif(1, 0, 9)),   # if numeric
                       encr[[i]] <- round(runif(1, 0, 26)))  # if letters

                ifelse( !is.na(as.numeric(vec[i])) ,   # encrypting
                        y[[i]] <- as.numeric(vec[i]) + encr[[i]],                    # if numeric
                        y[[i]] <- letters[which(letters==vec[i])[1] + encr[[i]]] )  # if letters
        }
        return(unlist(y))
}

reveal <- function(password, y){
        set.seed(password)
        for (i in 1:length(y)){ 
                ifelse(is.numeric(y[i]),             # extracting encryption numbers 
                       encr[[i]] <- round(runif(1, 0, 9)),   # if numeric
                       encr[[i]] <- round(runif(1, 0, 26)))  # if letters
                ifelse( !is.na(as.numeric(y[i])) ,   # encrypting
                        y[[i]] <- as.numeric(y[i]) - encr[[i]],                   # if numeric
                        y[[i]] <- letters[which(letters==y[i])[1] - encr[[i]]] )  # if letters
        }
        return(paste0(unlist(y), collapse=""))
}

这是一个例子:

> obfuscate(2016,"a6b8")
[1] "f"  "10" "x"  "11"
Warning messages:
1: In ifelse(!is.na(as.numeric(vec[i])), y[[i]] <- as.numeric(vec[i]) +  :
  NAs introduced by coercion
2: In ifelse(!is.na(as.numeric(vec[i])), y[[i]] <- as.numeric(vec[i]) +  :
  NAs introduced by coercion

请注意,警告的数量等于非数字字符的数量。正如in this SO question 所解释的,这可以通过suppressWarnings() 抑制。我的偏好是总是表达 R 警告。

> reveal(2016,c("f","10","x","11"))
[1] "a6b8"
Warning messages:
1: In ifelse(!is.na(as.numeric(y[i])), y[[i]] <- as.numeric(y[i]) -  :
  NAs introduced by coercion
2: In ifelse(!is.na(as.numeric(y[i])), y[[i]] <- as.numeric(y[i]) -  :
  NAs introduced by coercion

【讨论】:

  • 虽然发明加密很有趣,但再次使用它是个坏主意:"Schneier's Law":任何人,从最无知的业余爱好者到最优秀的密码学家,都可以创建他自己无法创建的算法休息。此外,无法保证set.seed 在系统之间或软件版本之间是相同的。
  • 我们明白了@zaph 的意思,但 Sergey 需要“以某种方式混淆”一个字符串,而不是重新创建谜机器。此特定问题不涉及安全性。
  • 您将函数命名为 encryptdecrypt。由于它使用密钥,它似乎确实有资格作为加密。另外,不知道r,一般来说警告信息不是什么好事。
  • @zach 我在编辑后的答案中回复了你的 cmets。
  • @Sergey 我更新了允许字符串的功能,请您跟进或接受吗?
猜你喜欢
  • 2010-11-02
  • 2017-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
  • 2013-11-28
相关资源
最近更新 更多