我有一个字符串 - 母板的序列号(只有数字和字母).如何加密/解密它并具有正常视图:仅从A到Z的字母和从0到9的数字.用户必须向我发送字符串,我必须回复.
我可以加密,但不可读的字符.
谢谢!
Moh*_*enB 15
简单的Enc/Dec支持Unicode,Enc输出只有十六进制字符:
const CKEY1 = 53761;
CKEY2 = 32618;
function EncryptStr(const S :WideString; Key: Word): String;
var i :Integer;
RStr :RawByteString;
RStrB :TBytes Absolute RStr;
begin
Result:= '';
RStr:= UTF8Encode(S);
for i := 0 to Length(RStr)-1 do begin
RStrB[i] := RStrB[i] xor (Key shr 8);
Key := (RStrB[i] + Key) * CKEY1 + CKEY2;
end;
for i := 0 to Length(RStr)-1 do begin
Result:= Result + IntToHex(RStrB[i], 2);
end;
end;
function DecryptStr(const S: String; Key: Word): String;
var i, tmpKey :Integer;
RStr :RawByteString;
RStrB :TBytes Absolute RStr;
tmpStr :string;
begin
tmpStr:= UpperCase(S);
SetLength(RStr, Length(tmpStr) div 2);
i:= 1;
try
while (i < Length(tmpStr)) do begin
RStrB[i div 2]:= StrToInt('$' + tmpStr[i] + tmpStr[i+1]);
Inc(i, 2);
end;
except
Result:= '';
Exit;
end;
for i := 0 to Length(RStr)-1 do begin
tmpKey:= RStrB[i];
RStrB[i] := RStrB[i] xor (Key shr 8);
Key := (tmpKey + Key) * CKEY1 + CKEY2;
end;
Result:= UTF8Decode(RStr);
end;
Run Code Online (Sandbox Code Playgroud)
示例:
procedure TForm1.btn1Click(Sender: TObject);
begin
txt2.Text:= EncryptStr(txt1.Text, 223);
lbl1.Caption:= DecryptStr(txt2.Text, 223);
end;
Run Code Online (Sandbox Code Playgroud)
RRU*_*RUZ 14
最好的方法是加密然后编码字符串.
检查这个使用JWSCL库加密字符串的示例和Indy在base64中编码和解码.
{$APPTYPE CONSOLE}
uses
ExceptionLog,
Classes,
JwaWinType,
JwaWinCrypt,
IdCoderMIME,
SysUtils;
function CryptString(Const Input: string; password : AnsiString; Encrypt: Boolean) : string;
const
BufferSize=1024*1024;
var
StreamSource : TStringStream;
StreamDest : TStringStream;
CRYPTPROV : HCRYPTPROV;
CRYPTHASH : HCRYPTHASH;
CRYPTKEY : HCRYPTKEY;
Buffer : LPBYTE;
BytesIn : DWORD;
Final : Boolean;
Encoder : TIdEncoderMIME;
Decoder : TIdDecoderMIME;
DestStream : TStringStream;
begin
CryptAcquireContext(CRYPTPROV, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
try
//create a valid key based in the password
if not CryptCreateHash(CRYPTPROV, CALG_SHA1, 0, 0, CRYPTHASH) then RaiseLastOSError;
try
if not CryptHashData(CRYPTHASH, @Password[1], Length(Password), 0) then RaiseLastOSError;
if not CryptDeriveKey(CRYPTPROV, CALG_RC4, CRYPTHASH, 0, CRYPTKEY) then RaiseLastOSError;
finally
CryptDestroyHash(CRYPTHASH);
end;
StreamSource := TStringStream.Create(Input);
StreamSource.Position:=0;
StreamDest := TStringStream.Create;
try
GetMem(Buffer, BufferSize);
try
if not Encrypt then
begin
//decode the string using base64
Decoder := TIdDecoderMIME.Create(nil);
try
DestStream := TStringStream.Create;
try
StreamDest.Position:=0;
Decoder.DecodeBegin(DestStream);
Decoder.Decode(StreamSource);
Decoder.DecodeEnd;
StreamSource.Clear;
DestStream.Position:=0;
StreamSource.CopyFrom(DestStream,DestStream.Size);
StreamSource.Position:=0;
finally
DestStream.Free;
end;
finally
Decoder.Free;
end;
end;
repeat
BytesIn := StreamSource.Read(Buffer^, BufferSize);
Final := (StreamSource.Position >= StreamSource.Size);
if Encrypt then
begin
if not CryptEncrypt(CRYPTKEY, 0, Final, 0, Buffer, BytesIn, BytesIn) then RaiseLastOSError;
end
else
if not CryptDecrypt(CRYPTKEY, 0, Final, 0, Buffer, BytesIn) then RaiseLastOSError;
StreamDest.Write(Buffer^, BytesIn);
until Final;
//encode the string using base64
if Encrypt then
begin
Encoder := TIdEncoderMIME.Create(nil);
try
DestStream:=TStringStream.Create;
try
StreamDest.Position:=0;
Encoder.Encode(StreamDest,DestStream);
Result := DestStream.DataString;
finally
DestStream.Free;
end;
finally
Encoder.Free;
end;
end
else
Result:= StreamDest.DataString;
finally
FreeMem(Buffer, BufferSize);
end;
finally
StreamSource.Free;
StreamDest.Free;
end;
finally
CryptReleaseContext(CRYPTPROV, 0);
end;
end;
var
plaintext : string;
Encrypted : string;
begin
try
plaintext:='this is a plain text'; Writeln('Plain Text '+plaintext);
Encrypted:=CryptString(plaintext,'...ThiS Is A PaSsWord...',True);
Writeln('Encrypted/Encoded string '+Encrypted);
plaintext:=CryptString(Encrypted,'...ThiS Is A PaSsWord...',False);
Writeln('Original string '+plaintext);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
Run Code Online (Sandbox Code Playgroud)
这是一种众所周知的ROT13地穴:
// will crypt A..Z, a..z, 0..9 characters by rotating
function Crypt(const s: string): string;
var i: integer;
begin
result := s;
for i := 1 to length(s) do
case ord(s[i]) of
ord('A')..ord('M'),ord('a')..ord('m'): result[i] := chr(ord(s[i])+13);
ord('N')..ord('Z'),ord('n')..ord('z'): result[i] := chr(ord(s[i])-13);
ord('0')..ord('4'): result[i] := chr(ord(s[i])+5);
ord('5')..ord('9'): result[i] := chr(ord(s[i])-5);
end;
end;
Run Code Online (Sandbox Code Playgroud)
除A..Z,a..z,0..9以外的任何字符都将保持不变.