一种简单的加解密算法

Posted ecofast

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一种简单的加解密算法相关的知识,希望对你有一定的参考价值。

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

const
   cMulKey = 52845;
   cAddKey = 11719;
   cKey    = 1234;

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 UInt16 C1 = 52845;
        private const UInt16 C2 = 11719;        

        public static UInt16 EnDeKey = 0;

        public static byte[] EncryptBytes(byte[] plainBytes)
        {
            UInt16 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 = (UInt16)(((UInt16)b + key) * C1 + C2);
                ret[i] = b;
            }
            return ret;
        }

        public static byte[] DecryptBytes(byte[] cipherBytes)
        {
            UInt16 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 = (UInt16)(((UInt16)c + key) * C1 + C2);
                ret[i] = b;
            }            
            return ret;
        }
    }

 

以上是关于一种简单的加解密算法的主要内容,如果未能解决你的问题,请参考以下文章

MD5+DES在C#.NET与Java/Android中的加解密使用

简单的加密算法——维吉尼亚密码

保存密文图像在对此图像利用解密算法进行解密能不能行得通

凯撒密码实现英文短句的加解密

java des 默认采用啥加密模式

eos中签名验签流程和eosjs中的加解密原理