Phi*_*lip 22 ruby encryption encryption-symmetric
我需要对一些文本字符串进行简单加密.我想创建优惠券代码并使它们看起来很酷,因此随后创建的代码应该看起来非常不同.(除了看起来很酷,猜测代码也不容易.)但我希望能够再次解密它们.因此算法必须是可逆的.
我已经尝试了一些移动位的东西,所以它们看起来有点随机.但是两个后续代码(只有一点不同)当然看起来非常相似.
有什么建议?我想在不使用外部宝石的情况下这样做.
菲利普
Jos*_*eek 45
您可以使用OpenSSL :: Cypher
# for more info, see http://ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/Cipher.html
require 'openssl'
require 'digest/sha1'
# create the cipher for encrypting
cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
cipher.encrypt
# you will need to store these for later, in order to decrypt your data
key = Digest::SHA1.hexdigest("yourpass")
iv = cipher.random_iv
# load them into the cipher
cipher.key = key
cipher.iv = iv
# encrypt the message
encrypted = cipher.update('This is a secure message, meet at the clock-tower at dawn.')
encrypted << cipher.final
puts "encrypted: #{encrypted}\n"
# now we create a sipher for decrypting
cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
cipher.decrypt
cipher.key = key
cipher.iv = iv
# and decrypt it
decrypted = cipher.update(encrypted)
decrypted << cipher.final
puts "decrypted: #{decrypted}\n"
Run Code Online (Sandbox Code Playgroud)
但是中间形式不适合印刷
如果您认为如果中间形式长度相同会很好,您可能只使用一个char到另一个char的简单映射.
您可以轻松地强行关键,但它似乎与您的要求一致.
class Cipher
def initialize(shuffled)
normal = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a + [' ']
@map = normal.zip(shuffled).inject(:encrypt => {} , :decrypt => {}) do |hash,(a,b)|
hash[:encrypt][a] = b
hash[:decrypt][b] = a
hash
end
end
def encrypt(str)
str.split(//).map { |char| @map[:encrypt][char] }.join
end
def decrypt(str)
str.split(//).map { |char| @map[:decrypt][char] }.join
end
end
# pass the shuffled version to the cipher
cipher = Cipher.new ["K", "D", "w", "X", "H", "3", "e", "1", "S", "B", "g", "a", "y", "v", "I", "6", "u", "W", "C", "0", "9", "b", "z", "T", "A", "q", "U", "4", "O", "o", "E", "N", "r", "n", "m", "d", "k", "x", "P", "t", "R", "s", "J", "L", "f", "h", "Z", "j", "Y", "5", "7", "l", "p", "c", "2", "8", "M", "V", "G", "i", " ", "Q", "F"]
msg = "howdy pardner"
crypted = cipher.encrypt msg
crypted # => "1IzXAF6KWXvHW"
decrypted = cipher.decrypt crypted
decrypted # => "howdy pardner"
Run Code Online (Sandbox Code Playgroud)
Ari*_*Ari 17
如果您不需要真正的加密,则可以使用简单的密码.(当您不需要安全性或加密短随机/一次性字符串时,可以使用此方法.)
ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
#generated with ALPHABET.split('').shuffle.join
ENCODING = "MOhqm0PnycUZeLdK8YvDCgNfb7FJtiHT52BrxoAkas9RWlXpEujSGI64VzQ31w"
def encode(text)
text.tr(ALPHABET, ENCODING)
end
def decode(text)
text.tr(ENCODING, ALPHABET)
end
Run Code Online (Sandbox Code Playgroud)
对于基本的编码/解码目的,我猜ruby的内置Base64库可以很方便:
2.2.1 :001 > require 'base64'
=> true
2.2.1 :002 > str = "abc@example.com"
=> "abc@example.com"
2.2.1 :003 > Base64.encode64(str)
=> "YWJjQGV4YW1wbGUuY29t\n"
Run Code Online (Sandbox Code Playgroud)
它还具有urlsafe版本方法,以防在网址中使用编码字符串.
参考:http://ruby-doc.org/stdlib-2.3.0/libdoc/base64/rdoc/Base64.html
加密和解密的可选方法
gem 'activesupport'
require 'active_support'
key = SecureRandom.random_bytes(32)
crypt = ActiveSupport::MessageEncryptor.new(key)
encrypted_data = crypt.encrypt_and_sign("your password")
password = crypt.decrypt_and_verify(encrypted_data)
Run Code Online (Sandbox Code Playgroud)
该解决方案是从头开始,但基于此:https ://math.stackexchange.com/questions/9508/looking-for-a-bijective-discrete-function-that-behaves-as-chaotically-as-possib
最简单的方法是使用a * x + b (mod 2^n)
显然,这不是真正的加密,只有当您想在不使用太多代码的情况下创建连续的优惠券代码时才有用。
所以要实现这个,你首先需要选择a、b和n。(a 必须是奇数)例如a=17,b=37和n=27。我们还需要在“mod 2^n”上找到“ a^(-1)”。可以使用 ExtendedGcd 函数在https://www.wolframalpha.com上执行此操作:
所以 的倒数a是 因此15790321。把所有这些放在一起:
A=17
B=37
A_INV=15790321
def encrypt(x)
(A*x+B)%(2**27)
end
def decrypt(y)
((y-B)*A_INV)%(2**27)
end
Run Code Online (Sandbox Code Playgroud)
现在你可以这样做:
irb(main):038:0> encrypt(4)
=> 105
irb(main):039:0> decrypt(105)
=> 4
Run Code Online (Sandbox Code Playgroud)
显然我们希望优惠券代码看起来很酷。因此还需要 2 件额外的事情:从 4000 左右开始序列,因此代码更长。还将它们转换为字母数字,这对于 Ruby 来说也很简单:
irb(main):050:0> decrypt("1ghx".to_i(36))
=> 4000
irb(main):051:0> encrypt(4000).to_s(36)
=> "1ghx"
Run Code Online (Sandbox Code Playgroud)
一个很好的附加属性是,连续的数字足够不同,以至于猜测实际上是不可能的。当然,我们假设用户不是加密货币分析师,如果有人确实猜到了有效数字,那也不是世界末日::-)
irb(main):053:0> encrypt(4001).to_s(36)
=> "1gie"
irb(main):054:0> decrypt("1gie".to_i(36))
=> 4001
Run Code Online (Sandbox Code Playgroud)
让我们尝试通过从 到 计数来天真地“破解”1gie它1gif:
irb(main):059:0* decrypt("1gif".to_i(36))
=> 15794322
Run Code Online (Sandbox Code Playgroud)
这完全超出了范围,反正优惠券也只有 2000 张左右,而不是一百万张。:-) 另外,如果我没记错的话,可以对参数进行一些实验,这样后续的数字看起来会更加混乱。
(对于较长的代码,请选择较大的值n,反之亦然。基数36意味着6每个字符 (" ") 都需要位Math.log(36, 2)。因此n=27最多允许 5 个字符。)
| 归档时间: |
|
| 查看次数: |
27224 次 |
| 最近记录: |