Delphi: simple string encryption

后端 未结 4 724
伪装坚强ぢ
伪装坚强ぢ 2020-12-14 23:23

I have a string - a serial number of a mother board (only numbers and letters). How to encrypt/decrypt it and have a normal view: letters only from A to Z and numbers from 0

相关标签:
4条回答
  • 2020-12-14 23:56

    Simple Enc/Dec with support Unicode , Enc output is only hexadecimal characters :

    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;
    

    Example :

    procedure TForm1.btn1Click(Sender: TObject);
    begin
      txt2.Text:= EncryptStr(txt1.Text, 223);
      lbl1.Caption:= DecryptStr(txt2.Text, 223);
    end;
    
    0 讨论(0)
  • 2020-12-14 23:58

    I use this very simple trick found on https://edn.embarcadero.com/article/28325 that is good for its simplicity:

    I use it to store non critical encrypted passwords in a database. My goal is to put a layer of obfuscation (and minimize the computation needed for decrypting), not to do serious encryption, for admin password for example i use AES:

    // this function both  encryptes and decryptes
    // EnDecrypt(EnDeCrypt(astring)) = astring
    function EnDeCrypt(const Value : String) : String;
    var
      CharIndex : integer;
    begin
      Result := Value;
      for CharIndex := 1 to Length(Value) do
        Result[CharIndex] := chr(not(ord(Value[CharIndex])));
    end;
    
    0 讨论(0)
  • 2020-12-15 00:05

    This is some kind of the well-known ROT13 crypt:

    // 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;
    

    Any characters other than A..Z, a..z, 0..9 will stay unchanged.

    0 讨论(0)
  • 2020-12-15 00:06

    The best way is encrypt and then encode the string.

    Check this sample which uses the JWSCL library to encrypt a string and Indy to encode and decode in 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.
    
    0 讨论(0)
提交回复
热议问题