一种简单的加解密算法

  此算法源码最初由 Borland Delphi 编写,原作者似乎是 Allen Bauer,代码如下。

const
   cMulKey = 52845;
   cAddKey = 11719;function Decrypt(const S: String; Key: Word): String;
var I: byte; begin SetLength(Result, Length(S)); for I := 1 to Length(S) do begin Result[I] := char(byte(S[I]) xor (Key shr 8)); Key := (byte(S[I]) + Key) * cMulKey + cAddKey; end; end; function Encrypt(const S: String; Key: Word): String; Var I: byte; begin SetLength(Result, Length(S)); for I := 1 to Length(S) do begin Result[I] := char(byte(S[I]) xor (Key shr 8)); Key := (byte(Result[I]) + Key) * cMulKey + cAddKey; end; end;

  本质上,它只是简单的位运算而已(于是加解密速度较快),但加密强度并不低,所以可用在譬如密码加密等方面。

  于是我编写了 Golang 版本的实现(Encrypt/Decrypt 甚至完全可以直接改写原切片而无需使用额外的字节数组),代码已托管至 Github

// Copyright 2017 ecofast. All rights reserved.
// Use of this source code is governed by a BSD-style license.

// Package borcrypto was translated from the public code of Delphi from Borland,
// which is really quite simple but very high to try hack.
// They are suitable for passwords and similar situations.
package borcrypto

// You can modify mulKey and addKey freely within 65535(MaxUInt16)
const (
	mulKey = 52845
	addKey = 11719
)

// Avoid use key less than 256 for safety
func Encrypt(plain []byte, key uint16) []byte {
	ret := make([]byte, len(plain))
	for i, c := range plain {
		b := c ^ byte(key>>8)
		ret[i] = b
		key = (uint16(b)+key)*mulKey + addKey
	}
	return ret[:]
}

func Decrypt(cipher []byte, key uint16) []byte {
	ret := make([]byte, len(cipher))
	for i, c := range cipher {
		b := c ^ byte(key>>8)
		ret[i] = b
		key = (uint16(c)+key)*mulKey + addKey
	}
	return ret[:]
}

func EncryptStr(plainText string, key uint16) string {
	bs := Encrypt([]byte(plainText), key)
	return string(bs)
}

func DecryptStr(cipherText string, key uint16) string {
	bs := Decrypt([]byte(cipherText), key)
	return string(bs)
}

  然后也顺手写了份 C# 版本的实现。

public static class EnDeCoder
{
    private const ushort C1 = 52845;
    private const ushort C2 = 11719;        

    public static ushort EnDeKey = 0;

    public static byte[] EncryptBytes(byte[] plainBytes)
    {
        ushort key = EnDeKey;
        byte[] ret = new byte[plainBytes.Length];
        for (int i = 0; i < plainBytes.Length; i++)
        {
            byte c = plainBytes[i];
            byte k = (byte)(key >> 8);
            byte b = (byte)(c ^ k);
            key = (ushort)(((ushort)b + key) * C1 + C2);
            ret[i] = b;
        }
        return ret;
    }

    public static byte[] DecryptBytes(byte[] cipherBytes)
    {
        ushort key = EnDeKey;            
        byte[] ret = new byte[cipherBytes.Length];
        for (int i = 0; i < cipherBytes.Length; i++)
        {
            byte c = cipherBytes[i];
            byte k = (byte)(key >> 8);
            byte b = (byte)(c ^ k);
            key = (ushort)(((ushort)c + key) * C1 + C2);
            ret[i] = b;
        }            
        return ret;
    }
}

 

  2017/11/30:增加 Lua 版本实现:

local bit = require "bit32"

local _M = {}

local mulKey = 52845
local addKey = 11719

function _M.encrypt(str, enDeKey)
    local ret = ""
    local key = enDeKey
    for i = 1, #str do
        local c = string.byte(str, i)
        local k = bit.rshift(key, 8) & 0xFF
        local b = bit.bxor(c, k) & 0xFF
        key = ((b + key) * mulKey + addKey) & 0xFFFF        
        ret = ret..string.char(b)
    end
    return ret
end

function _M.decrypt(str, enDeKey)
    local ret = ""
    local key = enDeKey
    for i = 1, #str do
        local c = string.byte(str, i)
        local k = bit.rshift(key, 8) & 0xFF
        local b = bit.bxor(c, k) & 0xFF
        key = ((c + key) * mulKey + addKey) & 0xFFFF        
        ret = ret..string.char(b)
    end
    return ret
end

return _M

 

posted @ 2017-06-23 17:10  ecofast  阅读(864)  评论(0编辑  收藏  举报