{***************************************************************************** The DEC team (see file NOTICE.txt) licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. A copy of this licence is found in the root directory of this project in the file LICENCE.txt or alternatively at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. *****************************************************************************} unit DECCipherFormats; interface uses {$IFDEF FPC} SysUtils, Classes, {$ELSE} System.SysUtils, System.Classes, {$ENDIF} DECCipherBase, DECCipherModes, DECUtil, DECFormatBase, DECCipherInterface; type /// /// Class in which the various encode/decode variants provided have been /// moved in order to keep the base cipher class small and clean. /// TDECFormattedCipher = class(TDECCipherModes, IDECCipher) private /// /// Encrypts or decrypts the data contained in a given stream /// /// /// Source stream containing the data to encrypt or to decrypt /// /// /// Destination stream, where the encrypted or decrypted data shall be put in /// /// /// Number of bytes of Source to be encrypted or decrypted /// /// /// Callback which either encrypts or decrypts the stream, depending on /// which one is being passed /// /// /// optional callback for reporting progress of the operation /// procedure DoEncodeDecodeStream(const Source, Dest: TStream; DataSize: Int64; const CipherProc: TDECCipherCodeEvent; const OnProgress: TDECProgressEvent); /// /// Encrypts or decrypts a file and stores the result in another file /// /// /// Path and name of the file to encrypt /// /// /// Path and name of the file the encrypted data shall be stored in /// /// /// This method does the actual encrypting or decrypting of the data. /// Usually the Encode or Decode method is being passed here which is /// declared in TDECCipherBase as virtual abstract method and /// implemented in the individual cipher class inheriting from this one /// /// /// Optional event which can be passed to get information about the /// progress of the encryption operation /// procedure DoEncodeDecodeFile(const SourceFileName, DestFileName: string; const Proc: TDECCipherCodeEvent; const OnProgress: TDECProgressEvent); public /// /// Encrypts the contents of a given byte array /// /// /// Byte array with data to be encrypted. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm used, /// otherwise a EDECCipherException exception will be raised! /// /// /// Byte array with encrypted data /// function EncodeBytes(const Source: TBytes): TBytes; /// /// Decrypts the contents of a given byte array /// /// /// Byte array with data to be decrypted. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm used, /// otherwise a EDECCipherException exception will be raised! /// /// /// Byte array with decrypted data /// function DecodeBytes(const Source: TBytes): TBytes; /// /// Encrypts the data contained in a given stream /// /// /// Source stream containing the data to encrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm used, /// otherwise a EDECCipherException exception will be raised! /// /// /// Destination stream, where the encrypted data shall be put in /// /// /// Number of bytes of Source to be encrypted /// /// /// optional callback for reporting progress of the operation /// procedure EncodeStream(const Source, Dest: TStream; DataSize: Int64; const OnProgress: TDECProgressEvent = nil); /// /// Decrypts the data contained in a given stream /// /// /// Source stream containing the data to decrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm used, /// otherwise a EDECCipherException exception will be raised! /// /// /// Destination stream, where the decrypted data shall be put in /// /// /// Number of bytes of Source to be decrypted /// /// /// optional callback for reporting progress of the operation /// procedure DecodeStream(const Source, Dest: TStream; DataSize: Int64; const OnProgress: TDECProgressEvent = nil); /// /// Reads the contents of one file, encrypts it and stores it in another file /// /// /// Path and name of the file to encrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Path and name of the file the encrypted data shall be stored in /// /// /// Optional event which can be passed to get information about the /// progress of the encryption operation /// procedure EncodeFile(const SourceFileName, DestFileName: string; const OnProgress: TDECProgressEvent = nil); /// /// Reads the contents of one file, decrypts it and stores it in another file /// /// /// Path and name of the file to decrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Path and name of the file the decrypted data shall be stored in /// /// /// Optional event which can be passed to get information about the /// progress of the decryption operation /// procedure DecodeFile(const SourceFileName, DestFileName: string; const OnProgress: TDECProgressEvent = nil); /// /// Encrypts the contents of the passed unicode string /// /// /// String to encrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Encoded will be the encrypted data, not the /// source data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Encrypted string as a byte array /// function EncodeStringToBytes(const Source: string; Format: TDECFormatClass = nil): TBytes; overload; /// /// Encrypts the contents of the passed RawByteString /// /// /// String to encrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Encoded will be the encrypted data, not the /// source data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Encrypted string as a byte array /// function EncodeStringToBytes(const Source: RawByteString; Format: TDECFormatClass = nil): TBytes; overload; /// /// Encrypts the contents of the passed unicode string /// /// /// String to encrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Encoded will be the encrypted data, not the /// source data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Encrypted string /// /// /// The use of this method is only recommended if a formatting is passed /// which will result in an 7-bit ASCII compatible string as we cannot /// ensure that Unicode string processing will not alter/interpret some /// byte combinations in a destructive way, making the encrypted string /// un-decryptable. /// function EncodeStringToString(const Source: string; Format: TDECFormatClass = nil): string; overload; /// /// Encrypts the contents of the passed unicode string /// /// /// String to encrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Encoded will be the encrypted data, not the /// source data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Encrypted string /// /// /// The use of this method is only recommended if a formatting is passed /// which will result in an 7-bit ASCII compatible string as we cannot /// ensure that string processing will not alter/interpret some /// byte combinations in a destructive way, making the encrypted string /// un-decryptable. /// function EncodeStringToString(const Source: RawByteString; Format: TDECFormatClass = nil): RawByteString; overload; /// /// Decrypts the contents of the passed encrypted unicode string /// /// /// String to decrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Decoded will be the still encrypted data, not the /// encrypted data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Decrypted string as a byte array /// function DecodeStringToBytes(const Source: string; Format: TDECFormatClass = nil): TBytes; overload; /// /// Decrypts the contents of the passed encrypted RawByteString /// /// /// String to decrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Decoded will be the still encrypted data, not the /// encrypted data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Decrypted string as a byte array /// function DecodeStringToBytes(const Source: RawByteString; Format: TDECFormatClass = nil): TBytes; overload; /// /// Decrypts the contents of the passed Unicode string /// /// /// String to decrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Decoded will be the encrypted data, not the /// decrypted data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Decrypted string /// /// /// The use of this method is only recommended if a formatting is passed /// which uses an 7-bit ASCII compatible string as input so that it /// didn't get altered by Unicode string processing in some hafrmful way /// function DecodeStringToString(const Source: string; Format: TDECFormatClass = nil): string; overload; /// /// Decrypts the contents of the passed RawByteString string /// /// /// String to decrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Decoded will be the encrypted data, not the /// decrypted data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Decrypted string /// /// /// The use of this method is only recommended if a formatting is passed /// which uses an 7-bit ASCII compatible string as input so that it /// didn't get altered by string processing in some hafrmful way /// function DecodeStringToString(const Source: RawByteString; Format: TDECFormatClass = nil): RawByteString; overload; {$IFDEF ANSISTRINGSUPPORTED} /// /// Encrypts the contents of the passed Ansistring /// /// /// String to encrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Encoded will be the encrypted data, not the /// source data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Encrypted string as a byte array /// function EncodeStringToBytes(const Source: AnsiString; Format: TDECFormatClass = nil): TBytes; overload; /// /// Encrypts the contents of the passed Ansistring /// /// /// String to encrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Encoded will be the encrypted data, not the /// source data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Encrypted string as an AnsiString /// /// /// The use of this method is only recommended if a formatting is passed /// which will result in an 7-bit ASCII compatible string as we cannot /// ensure that string processing will not alter/interpret some /// byte combinations in a destructive way, making the encrypted string /// un-decryptable. /// function EncodeStringToString(const Source: AnsiString; Format: TDECFormatClass = nil): AnsiString; overload; /// /// Decrypts the contents of the passed encrypted Ansistring /// /// /// String to decrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Decoded will be the still encrypted data, not the /// encrypted data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Decrypted string as a byte array /// function DecodeStringToBytes(const Source: AnsiString; Format: TDECFormatClass = nil): TBytes; overload; /// /// Decrypts the contents of the passed AnsiString string /// /// /// String to decrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Decoded will be the encrypted data, not the /// decrypted data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Decrypted string /// /// /// The use of this method is only recommended if a formatting is passed /// which uses an 7-bit ASCII compatible string as input so that it /// didn't get altered by string processing in some hafrmful way /// function DecodeStringToString(const Source: AnsiString; Format: TDECFormatClass = nil): AnsiString; overload; {$ENDIF} {$IFNDEF NEXTGEN} /// /// Encrypts the contents of the passed Widestring /// /// /// String to encrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Encoded will be the encrypted data, not the /// source data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Encrypted string as a byte array /// function EncodeStringToBytes(const Source: WideString; Format: TDECFormatClass = nil): TBytes; overload; /// /// Encrypts the contents of the passed Widestring /// /// /// String to encrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Encoded will be the encrypted data, not the /// source data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Encrypted string as an WideString /// /// /// The use of this method is only recommended if a formatting is passed /// which will result in an 7-bit ASCII compatible string as we cannot /// ensure that string processing will not alter/interpret some /// byte combinations in a destructive way, making the encrypted string /// un-decryptable. /// function EncodeStringToString(const Source: WideString; Format: TDECFormatClass = nil): WideString; overload; /// /// Decrypts the contents of the passed encrypted Widestring /// /// /// String to decrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Decoded will be the still encrypted data, not the /// encrypted data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Decrypted string as a byte array /// function DecodeStringToBytes(const Source: WideString; Format: TDECFormatClass = nil): TBytes; overload; /// /// Decrypts the contents of the passed WideString string /// /// /// String to decrypt. When block chaining mode ECBx /// is used (not recommended!), the size of the data passed via this /// parameter needs to be a multiple of the block size of the algorithm /// used, otherwise a EDECCipherException exception will be raised! /// /// /// Optional parameter. One can pass a class reference of one of the /// concrete data formatting classes here which will be internally used /// to convert the data. Decoded will be the encrypted data, not the /// decrypted data. Formattings can be used to convert data into a format /// suitable for the transport medium the data shall be transported with. /// /// /// Decrypted string /// /// /// The use of this method is only recommended if a formatting is passed /// which uses an 7-bit ASCII compatible string as input so that it /// didn't get altered by string processing in some hafrmful way /// function DecodeStringToString(const Source: WideString; Format: TDECFormatClass = nil): WideString; overload; {$ENDIF} end; implementation uses DECBaseClass; function TDECFormattedCipher.EncodeBytes(const Source: TBytes): TBytes; begin SetLength(Result, Length(Source)); if Length(Result) > 0 then Encode(Source[0], Result[0], Length(Source)); end; function TDECFormattedCipher.DecodeBytes(const Source: TBytes): TBytes; begin Result := Source; if Length(Result) > 0 then Decode(Result[0], Result[0], Length(Source)); end; procedure TDECFormattedCipher.DoEncodeDecodeStream(const Source, Dest: TStream; DataSize: Int64; const CipherProc: TDECCipherCodeEvent; const OnProgress: TDECProgressEvent); var Buffer: TBytes; BufferSize, Bytes: Integer; Max, StartPos, Pos: Int64; begin Pos := Source.Position; if DataSize < 0 then DataSize := Source.Size - Pos; Max := Pos + DataSize; StartPos := Pos; if DataSize > 0 then try if Assigned(OnProgress) then OnProgress(Max, 0, Started); if StreamBufferSize <= 0 then StreamBufferSize := 8192; BufferSize := StreamBufferSize mod Context.BlockSize; if BufferSize = 0 then BufferSize := StreamBufferSize else BufferSize := StreamBufferSize + Context.BlockSize - BufferSize; if DataSize > BufferSize then SetLength(Buffer, BufferSize) else SetLength(Buffer, DataSize); while DataSize > 0 do begin Bytes := BufferSize; if Bytes > DataSize then Bytes := DataSize; Source.ReadBuffer(Buffer[0], Bytes); // The real encryption or decryption routine CipherProc(Buffer[0], Buffer[0], Bytes); Dest.WriteBuffer(Buffer[0], Bytes); Dec(DataSize, Bytes); Inc(Pos, Bytes); if Assigned(OnProgress) then OnProgress(Max, Pos - StartPos, Processing); end; finally ProtectBytes(Buffer); if Assigned(OnProgress) then OnProgress(Max, Max, Finished); end; end; procedure TDECFormattedCipher.EncodeStream(const Source, Dest: TStream; DataSize: Int64; const OnProgress: TDECProgressEvent); begin DoEncodeDecodeStream(Source, Dest, DataSize, Encode, OnProgress); end; procedure TDECFormattedCipher.DecodeStream(const Source, Dest: TStream; DataSize: Int64; const OnProgress: TDECProgressEvent); begin DoEncodeDecodeStream(Source, Dest, DataSize, Decode, OnProgress); end; procedure TDECFormattedCipher.DoEncodeDecodeFile(const SourceFileName, DestFileName: string; const Proc: TDECCipherCodeEvent; const OnProgress: TDECProgressEvent); var S, D: TStream; begin Assert(SourceFileName <> DestFileName, 'Source and Dest file name may not be equal'); S := TFileStream.Create(SourceFileName, fmOpenRead or fmShareDenyNone); try D := TFileStream.Create(DestFileName, fmCreate); try DoEncodeDecodeStream(S, D, S.Size, Proc, OnProgress); finally D.Free; end; finally S.Free; end; end; procedure TDECFormattedCipher.EncodeFile(const SourceFileName, DestFileName: string; const OnProgress: TDECProgressEvent); begin DoEncodeDecodeFile(SourceFileName, DestFileName, Encode, OnProgress); end; procedure TDECFormattedCipher.DecodeFile(const SourceFileName, DestFileName: string; const OnProgress: TDECProgressEvent); begin DoEncodeDecodeFile(SourceFileName, DestFileName, Decode, OnProgress); end; function TDECFormattedCipher.EncodeStringToBytes(const Source: string; Format: TDECFormatClass = nil): TBytes; var Len: Integer; begin if Length(Source) > 0 then begin {$IF CompilerVersion >= 24.0} Len := Length(Source) * SizeOf(Source[low(Source)]); SetLength(Result, Len); Encode(Source[low(Source)], Result[0], Len); {$ELSE} Len := Length(Source) * SizeOf(Source[1]); SetLength(Result, Len); Encode(Source[1], Result[0], Len); {$IFEND} Result := ValidFormat(Format).Encode(Result); end else SetLength(Result, 0); end; function TDECFormattedCipher.EncodeStringToBytes(const Source: RawByteString; Format: TDECFormatClass): TBytes; var Len: Integer; begin if Length(Source) > 0 then begin {$IF CompilerVersion >= 24.0} Len := Length(Source) * SizeOf(Source[low(Source)]); SetLength(Result, Len); Encode(Source[low(Source)], Result[0], Len); {$ELSE} Len := Length(Source) * SizeOf(Source[1]); SetLength(Result, Len); Encode(Source[1], Result[0], Len); {$IFEND} Result := ValidFormat(Format).Encode(Result); end else SetLength(Result, 0); end; function TDECFormattedCipher.DecodeStringToBytes(const Source: string; Format: TDECFormatClass): TBytes; var Len: Integer; Src: TBytes; begin if Length(Source) > 0 then begin Src := ValidFormat(Format).Decode(BytesOf(Source)); Len := Length(Src); Result := Src; Decode(Result[0], Result[0], Len); end else SetLength(Result, 0); end; function TDECFormattedCipher.DecodeStringToBytes(const Source: RawByteString; Format: TDECFormatClass): TBytes; var Len: Integer; Src: TBytes; begin if Length(Source) > 0 then begin Src := ValidFormat(Format).Decode(BytesOf(Source)); Len := Length(Src); Result := Src; Decode(Result[0], Result[0], Len); end else SetLength(Result, 0); end; {$IFDEF ANSISTRINGSUPPORTED} function TDECFormattedCipher.EncodeStringToBytes(const Source: AnsiString; Format: TDECFormatClass): TBytes; var Len: Integer; begin if Length(Source) > 0 then begin Len := Length(Source) * SizeOf(Source[1]); SetLength(Result, Len); Encode(Source[1], Result[0], Len); Result := ValidFormat(Format).Encode(Result); end else SetLength(Result, 0); end; {$ENDIF} {$IFDEF ANSISTRINGSUPPORTED} function TDECFormattedCipher.DecodeStringToBytes(const Source: AnsiString; Format: TDECFormatClass): TBytes; var Len: Integer; Src: TBytes; begin if Length(Source) > 0 then begin Src := ValidFormat(Format).Decode(SysUtils.BytesOf(Source)); Len := Length(Src); SetLength(Result, Len); Decode(Src[0], Result[0], Len); end else SetLength(Result, 0); end; {$ENDIF} {$IFNDEF NEXTGEN} function TDECFormattedCipher.EncodeStringToBytes(const Source: WideString; Format: TDECFormatClass): TBytes; var Len: Integer; begin if Length(Source) > 0 then begin Len := Length(Source) * SizeOf(Source[1]); SetLength(Result, Len); Encode(Source[1], Result[0], Len); Result := ValidFormat(Format).Encode(Result); end else SetLength(Result, 0); end; function TDECFormattedCipher.EncodeStringToString(const Source: WideString; Format: TDECFormatClass): WideString; begin result := WideString(EncodeStringToString(string(Source), Format)); end; {$ENDIF} {$IFDEF ANSISTRINGSUPPORTED} function TDECFormattedCipher.EncodeStringToString(const Source: AnsiString; Format: TDECFormatClass): AnsiString; var Len : Integer; EncryptedBuffer : TBytes; Temp : TBytes; begin if Length(Source) > 0 then begin Len := Length(Source) * SizeOf(Source[1]); SetLength(EncryptedBuffer, Len); Encode(Source[1], EncryptedBuffer[0], Len); Temp := ValidFormat(Format).Encode(EncryptedBuffer); SetLength(Result, length(Temp)); Move(Temp[0], Result[1], length(Temp)); end else SetLength(Result, 0); end; {$ENDIF} function TDECFormattedCipher.EncodeStringToString(const Source: string; Format: TDECFormatClass): string; var SourceSize : Integer; EncryptedBuffer : TBytes; begin if Length(Source) > 0 then begin {$IF CompilerVersion >= 24.0} SourceSize := Length(Source) * SizeOf(Source[low(Source)]); SetLength(EncryptedBuffer, SourceSize); Encode(Source[low(Source)], EncryptedBuffer[0], SourceSize); {$ELSE} SourceSize := Length(Source) * SizeOf(Source[1]); SetLength(EncryptedBuffer, SourceSize); Encode(Source[1], EncryptedBuffer[0], SourceSize); {$IFEND} Result := StringOf(ValidFormat(Format).Encode(EncryptedBuffer)); end else Result := ''; end; function TDECFormattedCipher.EncodeStringToString(const Source: RawByteString; Format: TDECFormatClass): RawByteString; var SourceSize : Integer; EncryptedBuffer : TBytes; Temp : TBytes; begin if Length(Source) > 0 then begin {$IF CompilerVersion >= 24.0} SourceSize := Length(Source) * SizeOf(Source[low(Source)]); SetLength(EncryptedBuffer, SourceSize); Encode(Source[low(Source)], EncryptedBuffer[0], SourceSize); {$ELSE} SourceSize := Length(Source) * SizeOf(Source[1]); SetLength(EncryptedBuffer, SourceSize); Encode(Source[1], EncryptedBuffer[0], SourceSize); {$IFEND} Temp := ValidFormat(Format).Encode(EncryptedBuffer); SetLength(Result, length(Temp)); {$IF CompilerVersion >= 24.0} Move(Temp[0], Result[low(Result)], length(Temp)) {$ELSE} Move(Temp[0], Result[1], length(Temp)) {$IFEND} end else Result := ''; end; {$IFNDEF NEXTGEN} function TDECFormattedCipher.DecodeStringToBytes(const Source: WideString; Format: TDECFormatClass): TBytes; var Len: Integer; Src: TBytes; begin if Length(Source) > 0 then begin Src := ValidFormat(Format).Decode(BytesOf(Source)); Len := Length(Src); SetLength(Result, Len); Decode(Src[0], Result[0], Len); end else SetLength(Result, 0); end; {$ENDIF} {$IFDEF ANSISTRINGSUPPORTED} function TDECFormattedCipher.DecodeStringToString(const Source: AnsiString; Format: TDECFormatClass): AnsiString; var Len : Integer; Src : TBytes; Tmp : TBytes; begin if Length(Source) > 0 then begin Src := ValidFormat(Format).Decode(SysUtils.BytesOf(Source)); Len := Length(Src); SetLength(Tmp, Len); Decode(Src[0], Tmp[0], Len); SetLength(Result, length(Tmp)); {$IF CompilerVersion >= 24.0} Move(Tmp[0], Result[low(Result)], length(Tmp)) {$ELSE} Move(Tmp[0], Result[1], length(Tmp)) {$IFEND} end else SetLength(Result, 0); end; {$ENDIF} {$IFNDEF NEXTGEN} function TDECFormattedCipher.DecodeStringToString(const Source: WideString; Format: TDECFormatClass): WideString; begin Result := WideString(DecodeStringToString(string(Source), Format)); end; {$ENDIF} function TDECFormattedCipher.DecodeStringToString(const Source: RawByteString; Format: TDECFormatClass): RawByteString; var Len : Integer; Src : TBytes; Tmp : TBytes; begin if Length(Source) > 0 then begin Src := ValidFormat(Format).Decode(BytesOf(Source)); Len := Length(Src); SetLength(Tmp, Len); Decode(Src[0], Tmp[0], Len); SetLength(Result, length(Tmp)); {$IF CompilerVersion >= 24.0} Move(Tmp[0], Result[low(Result)], length(Tmp)) {$ELSE} Move(Tmp[0], Result[1], length(Tmp)) {$IFEND} end else SetLength(Result, 0); end; function TDECFormattedCipher.DecodeStringToString(const Source: string; Format: TDECFormatClass): string; var Len : Integer; Src : TBytes; Tmp : TBytes; begin if Length(Source) > 0 then begin Src := ValidFormat(Format).Decode(BytesOf(Source)); Len := Length(Src); SetLength(Tmp, Len); Decode(Src[0], Tmp[0], Len); Result := WideStringOf(Tmp); end else SetLength(Result, 0); end; end.