我有一個字符串 - 一個母板的序列號(只有數字和字母)。如何加密/解密,並具有普通視圖:只能從A到Z的字母以及從0到9的數字。用戶必須向我發送字符串,我必須迴應。德爾福:簡單的字符串加密
我可以加密但不可讀的字符。
謝謝!
我有一個字符串 - 一個母板的序列號(只有數字和字母)。如何加密/解密,並具有普通視圖:只能從A到Z的字母以及從0到9的數字。用戶必須向我發送字符串,我必須迴應。德爾福:簡單的字符串加密
我可以加密但不可讀的字符。
謝謝!
最好的方法是加密然後編碼字符串。
檢查此示例,該示例使用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.
這是某種衆所周知的ROT13 crypt的:不是A到Z,a到z其他
// 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;
任何字符,0..9將保持不變。
是不是有點太簡單? – Ampere
@Allforfree這顯然是簡單的混淆,而不是加密加密。將AES用於更強大的部分。但是你需要使用一個經過驗證的庫。見例如[此方法](https://synopse.info/files/html/api-1.18/SynCrypto.html#TAESABSTRACT_SIMPLEENCRYPT)用於對稱加密,[this one](https://synopse.info/files/html/api -1.18/SynEcc.html#ECDH_SHARED_SECRET)用於密鑰的非對稱計算。 –
簡單的Enc /月與支持Unicode,按照電子海圖產量只有十六進制字符:
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;
例子:
procedure TForm1.btn1Click(Sender: TObject);
begin
txt2.Text:= EncryptStr(txt1.Text, 223);
lbl1.Caption:= DecryptStr(txt2.Text, 223);
end;
請澄清你的問題。它看起來像是在詢問一個加密方案,它會爲您提供一個人性化的「ASCII」字符串。如果是這樣,那麼使用任何ol'加密方案,但Base64對字符串進行編碼。 –
對不起!我需要一個人類可見的字符串 – maxfax