From 9a605f18515228989cbe9f8435d422439b649675 Mon Sep 17 00:00:00 2001 From: freitasjca Date: Mon, 9 Mar 2026 12:44:51 +0000 Subject: [PATCH 01/10] chore: add Boss package manifest Adds boss.json to make this library installable via boss install github.com/freitasjca/Delphi-Cross-Socket Zero source changes. browsingpath includes both Net/ and Utils/ because Net units depend on Utils units at compile time. --- boss.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 boss.json diff --git a/boss.json b/boss.json new file mode 100644 index 0000000..654b250 --- /dev/null +++ b/boss.json @@ -0,0 +1,11 @@ +{ + "name": "delphi-cross-socket", + "description": "Delphi cross-platform async socket library...", + "version": "1.0.0", + "homepage": "https://github.com/freitasjca/Delphi-Cross-Socket", + "license": "MIT", + "mainsrc": "Net/", + "browsingpath": "Net/;Utils/", + "projects": [], + "dependencies": {} +} \ No newline at end of file From 7ede4963abb2bf67af8ba499859f884208353dd3 Mon Sep 17 00:00:00 2001 From: freitasjca Date: Mon, 9 Mar 2026 14:39:19 +0000 Subject: [PATCH 02/10] Update description --- boss.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boss.json b/boss.json index 654b250..3afba61 100644 --- a/boss.json +++ b/boss.json @@ -1,6 +1,6 @@ { "name": "delphi-cross-socket", - "description": "Delphi cross-platform async socket library...", + "description": "Delphi cross-platform async socket library (IOCP/epoll/kqueue) with HTTP server and OpenSSL 3.x support. Fork of winddriver/Delphi-Cross-Socket — adds Boss package manifest only. Zero source changes.", "version": "1.0.0", "homepage": "https://github.com/freitasjca/Delphi-Cross-Socket", "license": "MIT", From 8cc15ee049810d331d9b5a8a91ab0e4ecc283b5c Mon Sep 17 00:00:00 2001 From: freitasjca Date: Fri, 13 Mar 2026 19:31:45 +0000 Subject: [PATCH 03/10] Add CrossSocket patches --- Net/Net.CrossSslSocket.Base.pas | 75 +++++++++++++++++++++++++++++++++ Utils/Utils.SyncObjs.pas | 6 ++- boss.json | 2 +- 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/Net/Net.CrossSslSocket.Base.pas b/Net/Net.CrossSslSocket.Base.pas index 0b1c52f..22187f5 100644 --- a/Net/Net.CrossSslSocket.Base.pas +++ b/Net/Net.CrossSslSocket.Base.pas @@ -105,6 +105,44 @@ interface /// procedure SetPrivateKeyFile(const APKeyFile: string); + // ── mTLS (mutual TLS / client-certificate authentication) ──────────────── + // [MTLS-1] Load the CA certificate used to verify client certificates. + // Call before Listen/Start. Required when VerifyPeer = True. + // The concrete implementation (TCrossOpenSslSocket) calls + // SSL_CTX_add_client_CA + X509_STORE_add_cert on its private FContext. + + /// + /// 从内存加载CA证书 (mTLS: 客户端证书验证) + /// + procedure SetCACertificate(const ACACertBuf: Pointer; + const ACACertBufSize: Integer); overload; + + /// + /// 从字节数组加载CA证书 + /// + procedure SetCACertificate(const ACACertBytes: TBytes); overload; + + /// + /// 从字符串加载CA证书 + /// + procedure SetCACertificate(const ACACertStr: string); overload; + + /// + /// 从文件加载CA证书 + /// + procedure SetCACertificateFile(const ACACertFile: string); + + // [MTLS-2] Enable or disable client-certificate verification. + // SSL_VERIFY_NONE (False) = server-only TLS — no client cert required. + // SSL_VERIFY_PEER (True) = server requests client cert. + // Combined with SSL_VERIFY_FAIL_IF_NO_PEER_CERT so that a missing or + // invalid certificate aborts the handshake rather than continuing. + + /// + /// 启用/禁用客户端证书验证 (mTLS) + /// + procedure SetVerifyPeer(const AVerify: Boolean); + /// /// 是否已启用 SSL /// @@ -140,6 +178,24 @@ TCrossSslSocketBase = class(TCrossSocket, ICrossSslSocket) procedure SetPrivateKey(const APKeyStr: string); overload; virtual; procedure SetPrivateKeyFile(const APKeyFile: string); virtual; + // ── mTLS ───────────────────────────────────────────────────────────────── + // [MTLS-1] SetCACertificate — abstract; implemented by TCrossOpenSslSocket. + // Calls SSL_CTX_add_client_CA(FContext, LCACert) to add the CA to the + // list of acceptable client CAs sent in the TLS handshake, and + // X509_STORE_add_cert(SSL_CTX_get_cert_store(FContext), LCACert) so + // OpenSSL can verify the client certificate against the CA chain. + procedure SetCACertificate(const ACACertBuf: Pointer; + const ACACertBufSize: Integer); overload; virtual; abstract; + procedure SetCACertificate(const ACACertBytes: TBytes); overload; virtual; + procedure SetCACertificate(const ACACertStr: string); overload; virtual; + procedure SetCACertificateFile(const ACACertFile: string); virtual; + + // [MTLS-2] SetVerifyPeer — abstract; implemented by TCrossOpenSslSocket. + // AVerify = True → SSL_CTX_set_verify(FContext, + // SSL_VERIFY_PEER or SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nil) + // AVerify = False → SSL_CTX_set_verify(FContext, SSL_VERIFY_NONE, nil) + procedure SetVerifyPeer(const AVerify: Boolean); virtual; abstract; + property Ssl: Boolean read GetSsl; end; @@ -190,6 +246,25 @@ procedure TCrossSslSocketBase.SetPrivateKeyFile(const APKeyFile: string); SetPrivateKey(TFileUtils.ReadAllBytes(APKeyFile)); end; +// ── mTLS convenience overloads ──────────────────────────────────────────────── +// These follow the same pattern as SetCertificate/SetPrivateKey: +// convert to bytes/pointer and delegate to the abstract primitive. + +procedure TCrossSslSocketBase.SetCACertificate(const ACACertBytes: TBytes); +begin + SetCACertificate(Pointer(ACACertBytes), Length(ACACertBytes)); +end; + +procedure TCrossSslSocketBase.SetCACertificate(const ACACertStr: string); +begin + SetCACertificate(TEncoding.ANSI.GetBytes(ACACertStr)); +end; + +procedure TCrossSslSocketBase.SetCACertificateFile(const ACACertFile: string); +begin + SetCACertificate(TFileUtils.ReadAllBytes(ACACertFile)); +end; + { TCrossSslConnectionBase } function TCrossSslConnectionBase.GetSsl: Boolean; diff --git a/Utils/Utils.SyncObjs.pas b/Utils/Utils.SyncObjs.pas index c3ff1a0..3a6ad48 100644 --- a/Utils/Utils.SyncObjs.pas +++ b/Utils/Utils.SyncObjs.pas @@ -866,7 +866,11 @@ function TSpinEvent.WaitFor(const ATimeout: Cardinal): TWaitResult; LSpinCount: Integer; LState: Integer; begin +{$IF CompilerVersion >= 35.0} LStartTick := TThread.GetTickCount64; +{$ELSE} + LStartTick := GetTickCount64; +{$IFEND} LSpinCount := 0; while True do @@ -890,7 +894,7 @@ function TSpinEvent.WaitFor(const ATimeout: Cardinal): TWaitResult; // 超时检查移到前面,避免不必要的Sleep if (ATimeout <> INFINITE) then begin - if (TThread.GetTickCount64 - LStartTick >= ATimeout) then + if ({$IF CompilerVersion >= 35.0}TThread.GetTickCount64{$ELSE}GetTickCount64{$IFEND} - LStartTick >= ATimeout) then Exit(TWaitResult.wrTimeout); end; diff --git a/boss.json b/boss.json index 3afba61..52ec717 100644 --- a/boss.json +++ b/boss.json @@ -5,7 +5,7 @@ "homepage": "https://github.com/freitasjca/Delphi-Cross-Socket", "license": "MIT", "mainsrc": "Net/", - "browsingpath": "Net/;Utils/", + "browsingpath": "Net/;Utils/;DelphiToFPC;CnPack/Common/;CnPack/Crypto", "projects": [], "dependencies": {} } \ No newline at end of file From cd7b46319e0a8653a85a9becac7a18076c183859 Mon Sep 17 00:00:00 2001 From: freitasjca Date: Fri, 13 Mar 2026 19:46:49 +0000 Subject: [PATCH 04/10] Add dependent CnPack files --- CnPack/Common/CnPack.inc | 3623 ++++++++++++++++ CnPack/Crypto/CnAES.dcu | Bin 0 -> 122925 bytes CnPack/Crypto/CnAES.pas | 7569 ++++++++++++++++++++++++++++++++++ CnPack/Crypto/CnBase64.dcu | Bin 0 -> 7426 bytes CnPack/Crypto/CnBase64.pas | 547 +++ CnPack/Crypto/CnConsts.dcu | Bin 0 -> 14305 bytes CnPack/Crypto/CnConsts.pas | 250 ++ CnPack/Crypto/CnDES.dcu | Bin 0 -> 30941 bytes CnPack/Crypto/CnDES.pas | 1973 +++++++++ CnPack/Crypto/CnFloat.dcu | Bin 0 -> 15913 bytes CnPack/Crypto/CnFloat.pas | 1354 ++++++ CnPack/Crypto/CnKDF.dcu | Bin 0 -> 13854 bytes CnPack/Crypto/CnKDF.pas | 807 ++++ CnPack/Crypto/CnMD5.dcu | Bin 0 -> 15598 bytes CnPack/Crypto/CnMD5.pas | 884 ++++ CnPack/Crypto/CnNative.dcu | Bin 0 -> 48972 bytes CnPack/Crypto/CnNative.pas | 4904 ++++++++++++++++++++++ CnPack/Crypto/CnPemUtils.dcu | Bin 0 -> 16968 bytes CnPack/Crypto/CnPemUtils.pas | 1219 ++++++ CnPack/Crypto/CnRandom.dcu | Bin 0 -> 5673 bytes CnPack/Crypto/CnRandom.pas | 415 ++ CnPack/Crypto/CnSHA1.dcu | Bin 0 -> 10859 bytes CnPack/Crypto/CnSHA1.pas | 737 ++++ CnPack/Crypto/CnSHA2.dcu | Bin 0 -> 30907 bytes CnPack/Crypto/CnSHA2.pas | 2337 +++++++++++ CnPack/Crypto/CnSHA3.dcu | Bin 0 -> 31943 bytes CnPack/Crypto/CnSHA3.pas | 2700 ++++++++++++ CnPack/Crypto/CnSM3.dcu | Bin 0 -> 14942 bytes CnPack/Crypto/CnSM3.pas | 829 ++++ 29 files changed, 30148 insertions(+) create mode 100644 CnPack/Common/CnPack.inc create mode 100644 CnPack/Crypto/CnAES.dcu create mode 100644 CnPack/Crypto/CnAES.pas create mode 100644 CnPack/Crypto/CnBase64.dcu create mode 100644 CnPack/Crypto/CnBase64.pas create mode 100644 CnPack/Crypto/CnConsts.dcu create mode 100644 CnPack/Crypto/CnConsts.pas create mode 100644 CnPack/Crypto/CnDES.dcu create mode 100644 CnPack/Crypto/CnDES.pas create mode 100644 CnPack/Crypto/CnFloat.dcu create mode 100644 CnPack/Crypto/CnFloat.pas create mode 100644 CnPack/Crypto/CnKDF.dcu create mode 100644 CnPack/Crypto/CnKDF.pas create mode 100644 CnPack/Crypto/CnMD5.dcu create mode 100644 CnPack/Crypto/CnMD5.pas create mode 100644 CnPack/Crypto/CnNative.dcu create mode 100644 CnPack/Crypto/CnNative.pas create mode 100644 CnPack/Crypto/CnPemUtils.dcu create mode 100644 CnPack/Crypto/CnPemUtils.pas create mode 100644 CnPack/Crypto/CnRandom.dcu create mode 100644 CnPack/Crypto/CnRandom.pas create mode 100644 CnPack/Crypto/CnSHA1.dcu create mode 100644 CnPack/Crypto/CnSHA1.pas create mode 100644 CnPack/Crypto/CnSHA2.dcu create mode 100644 CnPack/Crypto/CnSHA2.pas create mode 100644 CnPack/Crypto/CnSHA3.dcu create mode 100644 CnPack/Crypto/CnSHA3.pas create mode 100644 CnPack/Crypto/CnSM3.dcu create mode 100644 CnPack/Crypto/CnSM3.pas diff --git a/CnPack/Common/CnPack.inc b/CnPack/Common/CnPack.inc new file mode 100644 index 0000000..cad0164 --- /dev/null +++ b/CnPack/Common/CnPack.inc @@ -0,0 +1,3623 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +{******************************************************************************} +{ } +{ עõԪΪָͱ汾Ϣļ } +{ õԪݲֲο JCL GExperts } +{ } +{******************************************************************************} + +//============================================================================== +// ѡ +//============================================================================== + +{$IFDEF FPC} + // Free Pascal Compiler 3.x Up Definitions + {$DEFINE SUPPORT_PASCAL} // Pascal + {$DEFINE SUPPORT_UINT64} // UInt64 + {$DEFINE SUPPORT_32_AND_64} // ֧ 32 64 λ NativeInt + {$DEFINE SUPPORT_ENCODING} // Unicode ַ֧ Encoding ת + {$DEFINE SUPPORT_INLINE} // ֧ inline + + {$DEFINE OBJECT_HAS_TOSTRING} // TObject.ToString + {$DEFINE TBYTES_DEFINED} + + // CPU FPC ӳ䵽 Delphi + {$IFDEF CPU386} // Intel 32 CPU + {$DEFINE CPU32BITS} + {$DEFINE CPUX86} + {$asmMode intel} + {$ENDIF} + {$IFDEF CPUi386} + {$DEFINE CPU32BITS} + {$DEFINE CPUX86} + {$asmMode intel} + {$ENDIF} + + {$IFDEF CPUAMD64} // Intel 64 CPU + {$DEFINE CPU64BITS} + {$DEFINE CPUX64} + {$asmMode intel} + {$ENDIF} + {$IFDEF CPUX86_64} + {$DEFINE CPU64BITS} + {$DEFINE CPUX64} + {$asmMode intel} + {$ENDIF} + {$IFDEF CPUIA64} + {$DEFINE CPU64BITS} + {$DEFINE CPUX64} + {$asmMode intel} + {$ENDIF} + + {$IFDEF CPUARM} // ARM 32 bit processor + {$DEFINE CPU32BITS} + {$DEFINE CPUARM} + {$DEFINE CPUARM32} + {$ENDIF} + + {$IFDEF CPUAARCH64} // ARM 64 bit processor + {$DEFINE CPU64BITS} + {$DEFINE CPUARM} + {$DEFINE CPUARM64} + {$ENDIF} + + {$mode Delphi} // Delphi Compatibility, not DelphiUnicodeעԴظ + + // ر Range Check Overflow Check + {$R- No Range checking} + {$OVERFLOWCHECKS OFF} + +{$ELSE FPC} // Below is for Delphi Compiler + +//{$DEFINE PERSONAL_EDITION} +{$DEFINE ENTERPRISE_EDITION} + +{$IFNDEF PERSONAL_EDITION} + {$DEFINE SUPPORT_DB} + {$DEFINE SUPPORT_ADO} +{$ENDIF} + +//============================================================================== +// 汾Ϣ +//============================================================================== + +{$IFDEF VER360} + {$DEFINE COMPILER29} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI29} + {$DEFINE DELPHI120_ATHENS} + {$DEFINE BCB28} + {$DEFINE BCB120_ATHENS} + {$DEFINE BDS23} +{$ENDIF} + +{$IFDEF VER350} + {$DEFINE COMPILER28} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI28} + {$DEFINE DELPHI110_ALEXANDRIA} + {$DEFINE BCB28} + {$DEFINE BCB110_ALEXANDRIA} + {$DEFINE BDS22} +{$ENDIF} + +{$IFDEF VER340} + {$DEFINE COMPILER27} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI27} + {$DEFINE DELPHI104_SYDNEY} + {$DEFINE BCB27} + {$DEFINE BCB104_SYDNEY} + {$DEFINE BDS21} +{$ENDIF} + +{$IFDEF VER330} + {$DEFINE COMPILER26} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI26} + {$DEFINE DELPHI103_RIO} + {$DEFINE BCB26} + {$DEFINE BCB103_RIO} + {$DEFINE BDS20} +{$ENDIF} + +{$IFDEF VER320} + {$DEFINE COMPILER25} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI25} + {$DEFINE DELPHI102_TOKYO} + {$DEFINE BCB25} + {$DEFINE BCB102_TOKYO} + {$DEFINE BDS19} +{$ENDIF} + +{$IFDEF VER310} + {$DEFINE COMPILER24} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI24} + {$DEFINE DELPHI101_BERLIN} + {$DEFINE BCB24} + {$DEFINE BCB101_BERLIN} + {$DEFINE BDS18} +{$ENDIF} + +{$IFDEF VER300} + {$DEFINE COMPILER23} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI23} + {$DEFINE DELPHI10_SEATTLE} + {$DEFINE BCB23} + {$DEFINE BCB10_SEATTLE} + {$DEFINE BDS17} +{$ENDIF} + +{$IFDEF VER290} + {$DEFINE COMPILER22} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI22} + {$DEFINE DELPHIXE8} + {$DEFINE BCB22} + {$DEFINE BCBXE8} + {$DEFINE BDS16} +{$ENDIF} + +{$IFDEF VER280} + {$DEFINE COMPILER21} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI21} + {$DEFINE DELPHIXE7} + {$DEFINE BCB21} + {$DEFINE BCBXE7} + {$DEFINE BDS15} +{$ENDIF} + +{$IFDEF VER270} + {$DEFINE COMPILER20} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI20} + {$DEFINE DELPHIXE6} + {$DEFINE BCB20} + {$DEFINE BCBXE6} + {$DEFINE BDS14} +{$ENDIF} + +{$IFDEF VER260} + {$DEFINE COMPILER19} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI19} + {$DEFINE DELPHIXE5} + {$DEFINE BCB19} + {$DEFINE BCBXE5} + {$DEFINE BDS12} +{$ENDIF} + +{$IFDEF VER250} + {$DEFINE COMPILER18} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI18} + {$DEFINE DELPHIXE4} + {$DEFINE BCB18} + {$DEFINE BCBXE4} + {$DEFINE BDS11} +{$ENDIF} + +{$IFDEF VER240} + {$DEFINE COMPILER17} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI17} + {$DEFINE DELPHIXE3} + {$DEFINE DELPHI2013} + {$DEFINE BCB17} + {$DEFINE BCBXE3} + {$DEFINE BCB2013} + {$DEFINE BDS10} + {$DEFINE BDS2013} +{$ENDIF} + +{$IFDEF VER230} + {$DEFINE COMPILER16} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI16} + {$DEFINE DELPHIXE2} + {$DEFINE DELPHI2012} + {$DEFINE BCB16} + {$DEFINE BCBXE2} + {$DEFINE BCB2012} + {$DEFINE BDS9} + {$DEFINE BDS2012} +{$ENDIF} + +{$IFDEF VER220} + {$DEFINE COMPILER15} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI15} + {$DEFINE DELPHIXE} + {$DEFINE DELPHI2011} + {$DEFINE BCB15} + {$DEFINE BCBXE} + {$DEFINE BCB2011} + {$DEFINE BDS8} + {$DEFINE BDS2011} +{$ENDIF} + +{$IFDEF VER210} + {$DEFINE COMPILER14} + {$DEFINE VCL71} + {$DEFINE DELPHI14} + {$DEFINE DELPHI2010} + {$DEFINE BCB14} + {$DEFINE BCB2010} + {$DEFINE BDS7} + {$DEFINE BDS2010} +{$ENDIF} + +{$IFDEF VER200} + {$DEFINE COMPILER12} + {$DEFINE VCL71} + {$DEFINE DELPHI12} + {$DEFINE DELPHI2009} + {$DEFINE BCB12} + {$DEFINE BCB2009} + {$DEFINE BDS6} + {$DEFINE BDS2009} +{$ENDIF} + +{$IFDEF VER185} + {$DEFINE COMPILER11} + {$DEFINE VCL71} + {$DEFINE DELPHI11} + {$DEFINE DELPHI2007} + {$DEFINE BCB11} + {$DEFINE BCB2007} + {$DEFINE BDS5} + {$DEFINE BDS2007} + {$UNDEF VER180} +{$ENDIF} + +{$IFDEF VER180} + {$DEFINE COMPILER10} + {$DEFINE VCL71} + {$DEFINE DELPHI10} + {$DEFINE DELPHI2006} + {$DEFINE BCB10} + {$DEFINE BCB2006} + {$DEFINE BDS4} + {$DEFINE BDS2006} +{$ENDIF} + +{$IFDEF VER170} + {$DEFINE COMPILER9} + {$DEFINE VCL71} + {$DEFINE DELPHI9} + {$DEFINE DELPHI2005} + {$DEFINE BDS3} + {$DEFINE BDS2005} +{$ENDIF} + +{$IFDEF VER160} + {$DEFINE COMPILER8} + {$DEFINE VCL71} + {$DEFINE DELPHI8} + {$DEFINE BDS2} +{$ENDIF} + +{$IFDEF VER150} + {$DEFINE COMPILER7} + {$IFDEF LINUX} + {$DEFINE CLX10} + {$ELSE} + {$DEFINE VCL70} + {$DEFINE CLX10} + {$IFDEF BCB} + {$DEFINE BCB7} + {$ELSE} + {$DEFINE DELPHI7} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER140} + {$DEFINE COMPILER6} + {$IFDEF LINUX} + {$DEFINE CLX10} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IFDEF CompilerVersion} + {$IF System.RTLVersion = 14.1} + {$DEFINE KYLIX2} + {$IFEND} + {$IF System.RTLVersion = 14.5} + {$DEFINE KYLIX3} + {$IFEND} + {$ELSE} + {$DEFINE KYLIX1} + {$ENDIF} + {$ENDIF} + {$ELSE} + {$DEFINE VCL60} + {$DEFINE CLX10} + {$IFDEF BCB} + {$DEFINE BCB6} + {$ELSE} + {$DEFINE DELPHI6} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER130} + {$DEFINE COMPILER5} + {$DEFINE VCL50} + {$IFDEF BCB} + {$DEFINE BCB5} + {$ELSE} + {$DEFINE DELPHI5} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER125} + {$DEFINE COMPILER4} + {$DEFINE VCL40} + {$DEFINE BCB4} +{$ENDIF} + +{$IFDEF VER120} + {$DEFINE COMPILER4} + {$DEFINE VCL40} + {$DEFINE DELPHI4} +{$ENDIF} + +{$IFDEF VER110} + {$DEFINE COMPILER35} + {$DEFINE VCL30} + {$DEFINE BCB3} +{$ENDIF} + +{$IFDEF VER100} + {$DEFINE COMPILER3} + {$DEFINE VCL30} + {$DEFINE DELPHI3} +{$ENDIF} + +{$IFDEF VER93} + {$DEFINE COMPILER2} + {$DEFINE VCL20} + {$DEFINE BCB1} +{$ENDIF} + +{$IFDEF VER90} + {$DEFINE COMPILER2} + {$DEFINE VCL20} + {$DEFINE DELPHI2} +{$ENDIF} + +{$IFDEF VER80} + {$DEFINE COMPILER1} + {$DEFINE VCL10} + {$DEFINE DELPHI1} +{$ENDIF} + +// DELPHIX_UP from DELPHIX mappings + +{$IFDEF DELPHI29} + {$DEFINE DELPHI} + {$DEFINE DELPHI29_UP} + {$DEFINE DELPHI28_UP} + {$DEFINE DELPHI27_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI120_ATHENS} + {$DEFINE DELPHI120_ATHENS_UP} + {$DEFINE DELPHI110_ALEXANDRIA_UP} + {$DEFINE DELPHI104_SYDNEY_UP} + {$DEFINE DELPHI103_RIO_UP} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI28} + {$DEFINE DELPHI} + {$DEFINE DELPHI28_UP} + {$DEFINE DELPHI27_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI110_ALEXANDRIA} + {$DEFINE DELPHI110_ALEXANDRIA_UP} + {$DEFINE DELPHI104_SYDNEY_UP} + {$DEFINE DELPHI103_RIO_UP} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI27} + {$DEFINE DELPHI} + {$DEFINE DELPHI27_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI104_SYDNEY} + {$DEFINE DELPHI104_SYDNEY_UP} + {$DEFINE DELPHI103_RIO_UP} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI26} + {$DEFINE DELPHI} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI103_RIO} + {$DEFINE DELPHI103_RIO_UP} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI25} + {$DEFINE DELPHI} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI102_TOKYO} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI24} + {$DEFINE DELPHI} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI101_BERLIN} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI23} + {$DEFINE DELPHI} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI10_SEATTLE} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI22} + {$DEFINE DELPHI} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE8} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI21} + {$DEFINE DELPHI} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE7} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI20} + {$DEFINE DELPHI} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE6} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI19} + {$DEFINE DELPHI} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE5} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI18} + {$DEFINE DELPHI} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE4} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI17} + {$DEFINE DELPHI} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE3} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} +{$ENDIF} + +{$IFDEF DELPHI2013} + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI16} + {$DEFINE DELPHI} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE2} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} +{$ENDIF} + +{$IFDEF DELPHI2012} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI15} + {$DEFINE DELPHI} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE} + {$DEFINE DELPHIXE_UP} +{$ENDIF} + +{$IFDEF DELPHI2011} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI14} + {$DEFINE DELPHI} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2010} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI12} + {$DEFINE DELPHI} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2009} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI11} + {$DEFINE DELPHI} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2007} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI10} + {$DEFINE DELPHI} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2006} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI9} + {$DEFINE DELPHI} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2005} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI8} + {$DEFINE DELPHI} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI7} + {$DEFINE DELPHI} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI6} + {$DEFINE DELPHI} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI5} + {$DEFINE DELPHI} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI4} + {$DEFINE DELPHI} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI3} + {$DEFINE DELPHI} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2} + {$DEFINE DELPHI} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI1} + {$DEFINE DELPHI} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +// BCBX_UP from BCBX mappings + +{$IFDEF BCB29} + {$DEFINE BCB} + {$DEFINE BCB29_UP} + {$DEFINE BCB28_UP} + {$DEFINE BCB27_UP} + {$DEFINE BCB26_UP} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB120_ATHENS} + {$DEFINE BCB120_ATHENS_UP} + {$DEFINE BCB110_ALEXANDRIA_UP} + {$DEFINE BCB104_SYDNEY_UP} + {$DEFINE BCB103_RIO_UP} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB28} + {$DEFINE BCB} + {$DEFINE BCB28_UP} + {$DEFINE BCB27_UP} + {$DEFINE BCB26_UP} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB110_ALEXANDRIA} + {$DEFINE BCB110_ALEXANDRIA_UP} + {$DEFINE BCB104_SYDNEY_UP} + {$DEFINE BCB103_RIO_UP} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB27} + {$DEFINE BCB} + {$DEFINE BCB27_UP} + {$DEFINE BCB26_UP} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB104_SYDNEY} + {$DEFINE BCB104_SYDNEY_UP} + {$DEFINE BCB103_RIO_UP} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB26} + {$DEFINE BCB} + {$DEFINE BCB26_UP} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB103_RIO} + {$DEFINE BCB103_RIO_UP} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB25} + {$DEFINE BCB} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB102_TOKYO} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + + +{$IFDEF BCB24} + {$DEFINE BCB} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB101_BERLIN} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB23} + {$DEFINE BCB} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB10_SEATTLE} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB22} + {$DEFINE BCB} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE8} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB21} + {$DEFINE BCB} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE7} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB20} + {$DEFINE BCB} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE6} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB19} + {$DEFINE BCB} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE5} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB18} + {$DEFINE BCB} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE4} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB17} + {$DEFINE BCB} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE3} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} +{$ENDIF} + +{$IFDEF BCB2013} + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB16} + {$DEFINE BCB} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE2} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} +{$ENDIF} + +{$IFDEF BCB2012} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB15} + {$DEFINE BCB} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE} + {$DEFINE BCBXE_UP} +{$ENDIF} + +{$IFDEF BCB2011} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB14} + {$DEFINE BCB} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB2010} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB12} + {$DEFINE BCB} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB2009} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB11} + {$DEFINE BCB} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB2007} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB10} + {$DEFINE BCB} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB2006} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB7} + {$DEFINE BCB} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB6} + {$DEFINE BCB} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB5} + {$DEFINE BCB} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB4} + {$DEFINE BCB} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB3} + {$DEFINE BCB} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB1} + {$DEFINE BCB} + {$DEFINE BCB1_UP} +{$ENDIF} + +// KYLIXX_UP from KYLIXX mappings + +{$IFDEF KYLIX3} + {$DEFINE KYLIX} + {$DEFINE KYLIX3_UP} + {$DEFINE KYLIX2_UP} + {$DEFINE KYLIX1_UP} +{$ENDIF} + +{$IFDEF KYLIX2} + {$DEFINE KYLIX} + {$DEFINE KYLIX2_UP} + {$DEFINE KYLIX1_UP} +{$ENDIF} + +{$IFDEF KYLIX1} + {$DEFINE KYLIX} + {$DEFINE KYLIX1_UP} +{$ENDIF} + +// BDSXX_UP from BDSXX mappings + +{$IFDEF BDS23} // 12.0 ATHENS + {$DEFINE BDS} + {$DEFINE BDS23_UP} + {$DEFINE BDS22_UP} + {$DEFINE BDS21_UP} + {$DEFINE BDS20_UP} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS22} // 11.0 ALEXANDRIA + {$DEFINE BDS} + {$DEFINE BDS22_UP} + {$DEFINE BDS21_UP} + {$DEFINE BDS20_UP} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS21} // 10.4 SYDNEY + {$DEFINE BDS} + {$DEFINE BDS21_UP} + {$DEFINE BDS20_UP} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS20} // 10.3 RIO + {$DEFINE BDS} + {$DEFINE BDS20_UP} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS19} // 10.2 Tokyo + {$DEFINE BDS} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS18} // 10.1 Berlin + {$DEFINE BDS} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS17} // 10 Seattle + {$DEFINE BDS} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS16} + {$DEFINE BDS} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS15} + {$DEFINE BDS} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS14} + {$DEFINE BDS} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS12} + {$DEFINE BDS} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS11} + {$DEFINE BDS} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS10} + {$DEFINE BDS} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2013} + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS9} + {$DEFINE BDS} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2012} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS8} + {$DEFINE BDS} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2011} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS7} + {$DEFINE BDS} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2010} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS6} + {$DEFINE BDS} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2009} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS5} + {$DEFINE BDS} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2007} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS4} + {$DEFINE BDS} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2006} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS3} + {$DEFINE BDS} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2005} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS2} + {$DEFINE BDS} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS1} + {$DEFINE BDS} + {$DEFINE BDS1_UP} +{$ENDIF} + +// COMPILERX_UP from COMPILERX mappings + +{$IFDEF COMPILER29} // 12.0 ATHENS + {$DEFINE COMPILER29_UP} + {$DEFINE COMPILER28_UP} + {$DEFINE COMPILER27_UP} + {$DEFINE COMPILER26_UP} + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER28} // 11.0 ALEXANDRIA + {$DEFINE COMPILER28_UP} + {$DEFINE COMPILER27_UP} + {$DEFINE COMPILER26_UP} + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER27} // 10.4 SYDNEY + {$DEFINE COMPILER27_UP} + {$DEFINE COMPILER26_UP} + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER26} // 10.3 RIO + {$DEFINE COMPILER26_UP} + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER25} // 10.2 Tokyo + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER24} // 10.1 Berlin + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER23} // 10 Seattle + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER22} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER21} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER20} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER19} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER18} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER17} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER16} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER15} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER14} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER12} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER11} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER10} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER9} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER8} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER7} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER6} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER5} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER4} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER35} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER3} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER2} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER1} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +// VCLXX_UP from VCLXX mappings + +{$IFDEF UCL10} + {$DEFINE UCL10_UP} +{$ENDIF} + +{$IFDEF VCL71} + {$DEFINE VCL71_UP} + {$DEFINE VCL70_UP} + {$DEFINE VCL60_UP} + {$DEFINE VCL50_UP} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL70} + {$DEFINE VCL70_UP} + {$DEFINE VCL60_UP} + {$DEFINE VCL50_UP} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL60} + {$DEFINE VCL60_UP} + {$DEFINE VCL50_UP} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL50} + {$DEFINE VCL50_UP} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL40} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL30} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL20} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL10} + {$DEFINE VCL10_UP} +{$ENDIF} + +// CLXXX_UP from CLXXX mappings + +{$IFDEF CLX10} + {$DEFINE CLX10_UP} +{$ENDIF} + +//============================================================================== +// ƽ̨ض +//============================================================================== + +{$IFDEF COMPILER1} + {$DEFINE WIN16} + {$DEFINE MSWINDOWS} +{$ENDIF} + +{$IFDEF BDS} + {$DEFINE DOTNET} +{$ENDIF} + +{$IFDEF WIN32} + {$DEFINE MSWINDOWS} +{$ENDIF} + +{$IFDEF LINUX} + {$DEFINE UNIX} + {$DEFINE COMPLIB_CLX} +{$ENDIF} + +{$IFNDEF COMPLIB_CLX} + {$DEFINE COMPLIB_VCL} +{$ENDIF} + +//============================================================================== +// ӳ汾ϢѺõָ +//============================================================================== + +{$IFDEF DELPHI} + {$DEFINE SUPPORT_PASCAL} +{$ENDIF} + +{$IFDEF BCB} + {$DEFINE SUPPORT_PASCAL} + {$DEFINE SUPPORT_CPLUSPLUS} +{$ENDIF} + +{$IFDEF DELPHI120_ATHENS_UP} + {$DEFINE LIST_INDEX_NATIVEINT} // Athens 12 TList use NativeInt for Index and Count instead of Integer + {$DEFINE IDE_HAS_TABMENU_COPY_PATH} // Athens 12 editor tab menu has item to copy path or filename + {$DEFINE IDE_HAS_DBCLICK_HIGHLIGHT} // Athens 12 editor double click selection highlight + {$DEFINE OTA_CODEEDITOR_SERVICE} // 11.3 ToolsAPI.Editor ӿڣʱ޷ 11.0/1/2 ֻ֣ܼӵ 12 +{$ENDIF} + +{$IFDEF DELPHI110_ALEXANDRIA_UP} + {$DEFINE NO_OLDCREATEORDER} // Alexandria 11 removed OldCreateOrder + {$DEFINE IDE_SUPPORT_HDPI} // Alexandria 11 supports HDPI using TVirtualImageList, etc. + {$DEFINE IDE_HAS_AUTO_READONLY} // Alexandria 11 supports auto open VCL source readonly + {$DEFINE IDE_HAS_MEMORY_VISUALIZAER} // Alexandria 11 has Memory Visualizer for Debug + {$DEFINE TSTRINGS_SETTEXTSTR_CANNULL} // Alexandria 11 TStrings.SetTextStr Ignore #0 Terminated Char + {$DEFINE MEMORYSTREAM_CAPACITY_NATIVEINT} // Alexandria 11 TMemoryStream Capacity is NativeInt instead of Longint +{$ENDIF} + +{$IFDEF DELPHI104_SYDNEY_UP} + {$DEFINE IDE_SUPPORT_LSP} // Sydney 10.4 ֧ LSP Է + {$DEFINE IDE_HAS_ERRORINSIGHT} // Sydney 10.4.2 ֱ֧༭ ErrorInsight + {$DEFINE IDE_EDITOR_CUSTOM_COLUMN} // Sydney 10.4 ϱ༭ Gutter ֧Զ壬ûӿڲݣԼ + {$DEFINE IDE_SWITCH_BUG} // Sydney 10.4.2 ڴļʱĪл̨ Bug +{$ENDIF} + +{$IFDEF DELPHI103_RIO_UP} + {$DEFINE SUPPORT_MACOS64} // Rio 10.3.2 ֧ 64 λ MacOS +{$ENDIF} + +{$IFDEF DELPHI102_TOKYO_UP} + {$DEFINE SUPPORT_LINUX64} // Tokyo 10.2 ֧ Linux 64 λ Server + {$DEFINE IDE_SUPPORT_THEMING} // Tokyo 10.2.2 ֧ IDE л +{$ENDIF} + +{$IFDEF DELPHI101_BERLIN_UP} + {$DEFINE IDE_NEW_EMBEDDED_DESIGNER} // 101B Re-opens "Embedded Designer" Option and Gives a New Container. +{$ENDIF} + +{$IFDEF DELPHI10_SEATTLE_UP} + {$DEFINE IDE_HAS_OWN_STRUCTUAL_HIGHLIGHT} // 10S has own Structual Highlight + {$DEFINE IDE_HAS_HIDE_NONVISUAL} // 10S has "Hide Nonvisual" Feature. +{$ENDIF} + +{$IFDEF DELPHIXE8_UP} + {$DEFINE INIFILE_READWRITE_INTEGER} // XE8 IniFile ReadInteger WriteInteger ʼ LongInt Ϊ Integer + {$DEFINE IDE_INTEGRATE_CASTALIA} // XE8/10S and above integrate Castalia. +{$ENDIF} + +{$IFDEF COMPILER21_UP} // COMPILER21 = XE7 + {$DEFINE NOT_SUPPORT_BDE} // BDE +{$ENDIF} + +{$IFDEF DELPHIXE7_UP} + {$DEFINE SUPPORT_TBYTES_OPERATION} // XE7 TBytes ʼ֧ӡȲ + {$DEFINE FMX_CONTROL_HAS_SIZE} // XE7 FMX Control Size +{$ENDIF} + +{$IFDEF DELPHIXE6_UP} + {$DEFINE SUPPORT_JSON} // XE6 System.JSON ⣬ DBX/REST +{$ENDIF} + +{$IFDEF DELPHIXE5_UP} + {$DEFINE SUPPORT_MOBILE} // XE5 ʼ֧ƶ + {$DEFINE IDE_HAS_INSIGHT} // XE5 has IDE Insight Bar +{$ENDIF} + +{$IFDEF DELPHIXE4_UP} + {$IFNDEF DISABLE_FMX} + {$DEFINE SUPPORT_FMX_FRAME} // XE4 FMX Supports FMX Frame + {$ENDIF} +{$ELSE} + {$DEFINE MEMO_CARETPOS_BUG} // Memo CaretPos Get Negative Error Value for Large File under XE3 or below +{$ENDIF} + +{$IFDEF DELPHIXE3_UP} + {$DEFINE SUPPORT_ATOMIC} // XE3 has Atomic Routines + {$DEFINE TCONTROL_HAS_STYLEELEMENTS} // XE3 TControl has StyleElements Property + {$DEFINE IDE_NP_FMX_DESIGN_BUG} // XE3 FMX Designer Cut/Copy/Paste cause AV Bug for -np switch +{$ENDIF} + +{$IFDEF DELPHIXE2_UP} + {$DEFINE SUPPORT_WIN64} // XE2 Supports Win64 + {$DEFINE SUPPORT_MACOS32} // XE2 Supports MacOS 32 + {$DEFINE SUPPORT_UNITNAME_DOT} + {$DEFINE SUPPORT_ENHANCED_INDEXEDPROPERTY} // XE2 New RTTI Supports IndexedProperty + {$DEFINE SUPPORT_ZLIB_WINDOWBITS} // XE2 ZLib Supports WindowBits + {$DEFINE SUPPORT_GDIPLUS} // XE2 Supports GDI+ + {$DEFINE SUPPORT_INT64ARRAY} // XE2 Defined Int64Array + {$DEFINE SUPPORT_ALPHACOLOR} // XE2 System.UITypes Has TAlphaColors +{$ENDIF} + +{$IFDEF DELPHIXE_UP} + {$DEFINE TSTRINGS_HAS_WRITEBOM} // XE TStrings has WriteBOM property. + {$DEFINE IDE_HAS_DEBUGGERVISUALIZER} // XE ToolsAPI has Debugger Visualizer Interfaces. + {$DEFINE IDE_HAS_STRINGS_VISUALIZAER} // XE has TStrings Visualizer for Debug +{$ENDIF} + +{$IFDEF BDS2012_UP} // 2012 = XE2 + {$DEFINE SUPPORT_32_AND_64} // XE2 Support Win32 and Win64 + {$IFNDEF DISABLE_FMX} + {$DEFINE SUPPORT_FMX} + {$ENDIF} + {$DEFINE SUPPORT_CROSS_PLATFORM} // XE2 ֿ֧ƽ̨ + {$DEFINE VERSIONINFO_PER_CONFIGURATION} // Every Configuruation can have a Version Info. + {$DEFINE OTA_ENVOPTIONS_PLATFORM_BUG} + // A Bug Can't get Correct Env Option Values for Current Platform. + {$DEFINE LIST_NEW_POINTER} +{$ENDIF} + +{$IFDEF BDS2010_UP} + {$DEFINE SUPPORT_INTERFACE_AS_OBJECT} + {$DEFINE SUPPORT_ENHANCED_RTTI} // New enhanced RTTI. + {$DEFINE SUPPORT_EXTERNAL_DELAYED} // External functions can be declared as 'delayed'. + {$DEFINE SUPPORT_CLASS_CONSTRUCTOR} // 2010 and above Supports class constructor and destructor + {$DEFINE SUPPORT_CLASS_DESTRUCTOR} + {$DEFINE IMAGELIST_BEGINENDUPDATE} // 2010 ʼImageList й BeginUpdate EndUpdate + {$DEFINE OTA_DEBUG_HAS_EVENTS} // 2010 µ DebuggerService ProcessDebugEvents + {$DEFINE IDE_HAS_NEW_COMPONENT_PALETTE} // IDE has a new style Component Palette. + {$DEFINE IDE_HAS_EDITOR_SEARCHPANEL} // Editor has a Search Panel + {$DEFINE IDE_HAS_DATETIME_HINT} // TDate/TTime/TDateTime shows Normally in Debug Hint +{$ENDIF} + +{$IFDEF BDS2010} + // 2010 EditView CursorPos EditPosition.InsertText ƫ + {$DEFINE EDITVIEW_SETCURSORPOS_BUG} +{$ENDIF} + +{$IFDEF BDS2009_UP} + {$DEFINE UNICODE_STRING} + {$DEFINE SUPPORT_ATTRIBUTE} // ֧ Attribute + {$DEFINE SUPPORT_GENERIC} // ַ֧ + {$DEFINE SUPPORT_ANSISTRING_CODEPAGE} // AnsiString ָ֧ҳ + {$DEFINE SUPPORT_ENCODING} // Unicode with TEncoding + {$DEFINE SUPPORT_PUINT64} // Has Pointer of UInt64 + {$DEFINE OBJECT_HAS_TOSTRING} // TObject.ToString Function + {$DEFINE OBJECT_HAS_EQUAL} // TObject.Equal Function + {$DEFINE OBJECT_HAS_GETHASHCODE} // TObject.GetHashCode Function + {$DEFINE TGRAPHIC_SUPPORT_PARTIALTRANSPARENCY} // TGraphic ֧ Alpha ͨ͸ + {$DEFINE SUPPORT_OTA_PROJECT_CONFIGURATION} + + {$DEFINE IDE_MAINFORM_EAT_MOUSEWHEEL} + // MainForm of 2009 or Above will eat Message in MouseWheelHandler + {$DEFINE IDE_CODEINSIGHT_AUTOINVOKE} + // IDE Code Insight has Auto Invoke Option + {$DEFINE EDITVIEW_CONVERTPOS_BUG} + // 2009 or Above IEditView.ConvertPos Incorrect when Meeting Unicode Chars. + + {$IFNDEF DELPHIXE2_UP} // 2009/2010/XE has a Project Version Number Bug. + {$DEFINE PROJECT_VERSION_NUMBER_BUG} + {$ENDIF} + {$DEFINE OTA_DPKOPTION_SETVALUE_CORRUPT_BUG} + // A OpenTools API Bug IOTAProjectOptions.SetOptionValue under 2009 or above: + // Set an Option Value to DPK Project Options maybe cause DPK Source Corrupt. +{$ELSE} + {$DEFINE ZLIB_STREAM_NOSIZE} // 2007 µ Zlib Ľѹ֧ Size +{$ENDIF} + +{$IFDEF BDS2009} + // 2009 CreateParams пܵѭ + {$DEFINE CREATE_PARAMS_BUG} + // 2009 EditView CursorPos EditPosition.InsertText ƫ + {$DEFINE EDITVIEW_SETCURSORPOS_BUG} +{$ENDIF} + +{$IFDEF BDS2007_UP} + {$DEFINE IDE_CONF_MANAGER} + {$DEFINE TBYTES_DEFINED} // 2007 Defined TBytes = array of Byte; + {$DEFINE PROJECT_FILENAME_DPROJ} // Project File is .dproj +{$ENDIF} + +{$IFDEF BDS2007} + // RAD Studio 2007 ¿ AutoComplete ᵼĺ˸ + {$DEFINE COMBOBOX_CHS_BUG} +{$ENDIF} + +{$IFDEF BDS2006_UP} + {$DEFINE SUPPORT_CLASS_VAR} // 2006 and above Supports class var + {$DEFINE TCONTROL_HAS_MARGINS} // 2006 and above TControl has Margins + {$DEFINE TCONTROL_HAS_EXPLICIT_BOUNDS} // 2006 and above TControl has Explicit Bounds + {$DEFINE TCONTROL_HAS_MOUSEENTERLEAVE} // 2006 and above TControl has Mouse Enter/Leave Events + {$DEFINE OTA_CODE_TEMPLATE_API} // 2006 and above Provides CodeTemplateAPI. + {$DEFINE OTA_DEBUG_HAS_ERBUSY} // 2006 µ Evaluate зֵ erBusy + {$DEFINE IDE_HAS_GUIDE_LINE} // 2006 and above has Designer Guide Line + {$DEFINE IDE_SYNC_EDIT_BLOCK} // 2006 and above Editor Supports Sync Block Edit + {$DEFINE EDITOR_TAB_ONLYFROM_WINCONTROL} + // From BDS 2006 IDEGraident Editor Tab is Only From WinControl, not TabSet/TabControl +{$ENDIF} + +{$IFDEF BDS2005_UP} + {$DEFINE OTA_PALETTE_API} // 2005 and above Provides PaletteAPI. + {$DEFINE IDE_EDITOR_ELIDE} // 2005 ϱ༭֧۵ + {$DEFINE IDE_FILE_HISTORY} // 2005 ϰ汾洢ļʷ汾 +{$ENDIF} + +{$IFDEF BDS2006} + {$DEFINE PROJECT_FILENAME_BDSPROJ} // Project File is .bdsproj +{$ENDIF} + +{$IFDEF BDS2005} + {$DEFINE PROJECT_FILENAME_BDSPROJ} // Project File is .bdsproj +{$ENDIF} + +{$IFDEF BDS} // 2005 + {$DEFINE SUPPORT_PASCAL} + {$DEFINE SUPPORT_CSHARP} + {$DEFINE SUPPORT_INLINE} + {$DEFINE SUPPORT_UINT64} + {$DEFINE IDE_WIDECONTROL} // 2005 ϵı༭ڲǿַ UTF-8Ƿ Unicode + {$DEFINE IDE_EDITOR_SUPPORT_FOLDING} // 2005 ϵı༭֧۵ + {$DEFINE OTA_NEW_BREAKPOINT_NOBUG} // 2005 ϵ NewBreakpoint ܹ + {$DEFINE IDE_ACTION_UPDATE_DELAY} // IDE's Action Menu Update will Delay in 2005 or Up. + {$DEFINE SUPPORT_WIDECHAR_IDENTIFIER} + + {$IFNDEF COMPILER12_UP} + // 2005~2007 Compiler is Ansi but Editor String is UTF-8 + {$DEFINE IDE_STRING_ANSI_UTF8} + {$ENDIF} +{$ENDIF} + +{$IFDEF DELPHI7_UP} + {$DEFINE SUPPORT_FORMAT_SETTINGS} // Delphi 7 ʼ֧ FormatSettings + {$DEFINE IDE_MENUBAR_VERTICAL_POSITION_BUG} + // Delphi 7 ϵ MenuBar ֱϵĵλü׳Ͻ + {$DEFINE IDE_MENUBAR_VERTICAL_NOSCROLL_BUG} + // Delphi 7 ϵ MenuBar ֱʱ +{$ENDIF} + +{$IFDEF COMPILER6_UP} + {$DEFINE SUPPORT_DEPRECATED} +{$ENDIF} + +{$IFDEF COMPILER6_UP} + {$DEFINE SUPPORT_ENUMVALUES} + {$DEFINE SUPPORT_VARIANTS} + {$DEFINE SUPPORT_IFDIRECTIVE} +{$ENDIF} + +{$IFDEF DELPHI5_UP} + {$IFNDEF BDS2005_UP} + {$DEFINE PROJECT_FILENAME_DPR} // Delphi 5/6/7 Project File is .dpr + {$ENDIF} +{$ENDIF} + +{$IFDEF COMPILER5} + {$DEFINE TSTREAM_LONGINT} // D6 ϵ TStream Int64 +{$ENDIF} + +{$IFDEF BCB5} + {$DEFINE BCB5OR6} // һ BCB5OR6 Է BCB5 BCB6 ʹ +{$ENDIF} + +{$IFDEF BCB6} + {$DEFINE BCB5OR6} +{$ENDIF} + +{$IFDEF BCB5OR6} + {$DEFINE NO_ZLIB} +{$ENDIF} + +{$IFDEF DELPHI5} + {$DEFINE DELPHI5OR6} // һ DELPHI5OR6 Է DELPHI5 DELPHI6 ʹ +{$ENDIF} + +{$IFDEF DELPHI6} + {$DEFINE DELPHI5OR6} +{$ENDIF} + +{$IFDEF COMPILER4_UP} + {$DEFINE SUPPORT_INT64} + {$DEFINE SUPPORT_DYNAMICARRAYS} + {$DEFINE SUPPORT_DEFAULTPARAMS} + {$DEFINE SUPPORT_REINTRODUCE} + {$DEFINE SUPPORT_OVERLOAD} +{$ENDIF} + +{$IFDEF COMPILER35_UP} + {$DEFINE SUPPORT_EXTSYM} + {$DEFINE SUPPORT_NODEFINE} +{$ENDIF} + +{$IFDEF COMPILER3_UP} + {$DEFINE SUPPORT_WIDESTRING} + {$DEFINE SUPPORT_INTERFACE} +{$ENDIF} + +{$IFDEF WIN64} + {$DEFINE EXTENDED_SIZE_8} // Win64 Extended ͳ 8 ֽ +{$ENDIF} + +{$IFDEF CPUARM} + {$DEFINE EXTENDED_SIZE_8} // ARM ƽ̨ Extended ͳ 8 ֽ +{$ENDIF} + +{$IFDEF WIN32} + {$DEFINE EXTENDED_SIZE_10} // Win32 Extended ͳ 10 ֽ +{$ENDIF} + +{$IFDEF MACOS64} + {$DEFINE EXTENDED_SIZE_16} // MacOS64 Extended ͳ 16 ֽ +{$ENDIF} + +{$IFDEF LINUX64} + {$DEFINE EXTENDED_SIZE_16} // Linux64 Extended ͳ 16 ֽ +{$ENDIF} + +//============================================================================== +// PascalScript ĵ +//============================================================================== + +{.$DEFINE ALLDEBUG} // òƲҪȽ + +//============================================================================== +// ֶ +//============================================================================== + +{$DEFINE GB2312} +{.$DEFINE BIG5} +{.$DEFINE ENGLISH} + +//============================================================================== +// ıָ +//============================================================================== + +{$A+ Force alignment on word/dword boundaries} +{$S+ stack checking} + +{$B- Short evaluation of boolean values} +{$H+ Long string support} +{$V- No var string checking} +{$X+ Extended syntax} +{$P+ Open string parameters} +{$J+ Writeable typed constants} +{$R- No Range checking} +{$OVERFLOWCHECKS OFF} + +{$IFDEF COMPILER6_UP} + {$WARN SYMBOL_PLATFORM OFF} + {$WARN UNIT_PLATFORM OFF} + {$WARN SYMBOL_DEPRECATED OFF} + {$WARN UNIT_DEPRECATED OFF} +{$ENDIF} + +{$IFDEF COMPILER7_UP} + {$WARN UNSAFE_CAST OFF} + {$WARN UNSAFE_CODE OFF} + {$WARN UNSAFE_TYPE OFF} +{$ENDIF} + +{$IFDEF BCB} + {$OBJEXPORTALL ON} +{$ENDIF} + +{$DEFINE CN_USE_MSXML} + +{$ENDIF FPC} + diff --git a/CnPack/Crypto/CnAES.dcu b/CnPack/Crypto/CnAES.dcu new file mode 100644 index 0000000000000000000000000000000000000000..ebc666a410074a233b156bd06d693c171451fb02 GIT binary patch literal 122925 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 +================================================================================ +* ƣ +* ԪƣAES ԳƼӽ㷨ʵֵԪ +* ԪߣCnPack (master@cnpack.org) +* EldoS, Alexander Ionov ĵԪֲ书ܣԭаȨϢ +* עԪʵ AES 128/192/256 ԳƼӽ㷨ֿС̶ 16 ֽڣģʽ +* Ķ뷽ʽĩβ 0Ԫڲ֧ PKCS ȿ뷽ʽҪⲿ +* CnPemUtils.pas Ԫе PKCS ϵкԼӽݽж⴦ +* +* ߰汾 Delphi 뾡ʹ AnsiString 汾ĺʮƳ⣩ +* ⲻַӰӽܽ +* +* 䣺============= Java Ĭϵ AES Ӧ˴ AES256 ============ +* ⣬C++Builder 5/6 ¶ overload ĺʴжϴӶ +* ҵΣʱԪ˴ overload Delphi ´ڣ +* ٷװ˲ֲͬĺ֧ C++Builder 5/6 ±С +* +* ECB/CBC ǿģʽҪ롣CFB/OFB/CTR ĵģʽ뵽顣 +* +* ⣬CTR ģʽ RFC 3686 淶紫ݵ 4 ֽ Nonce8 ֽ +* ʼ4 ֽֽļƴ 16 ֽڵijʼ +* AES 㣬ӽܾΪĶ +* +* ƽ̨Delphi5 + Win 7 +* ޸ļ¼2024.07.25 V1.3 +* CTR ģʽ֧֣ѭ RFC 3686 淶 +* 2024.05.26 V1.2 +* 䲿֧ C++Builder ĺ +* 2022.06.21 V1.1 +* 뼸ֽ鵽ʮַ֮ļӽܺ +* 2021.12.11 V1.2 +* CFB/OFB ģʽ֧ +* 2019.04.15 V1.1 +* ֧ Win32/Win64/MacOS +* 2015.01.21 V1.0 +* Ԫ +================================================================================ +|} + +interface + +{$I CnPack.inc} + +uses + Classes, SysUtils, CnNative; + +const + CN_AES_BLOCKSIZE = 16; + {* AES ķܿСλ٣Ϊ 16 ֽ} + +type + TCnKeyBitType = (kbt128, kbt192, kbt256); + {* AES λ16 ֽڡ24 ֽں 32 ֽ} + + ECnAESException = class(Exception); + {* AES 쳣} + + TCnAESBuffer = array [0..15] of Byte; + {* AES ӽܿ 16 ֽ} + + TCnAESKey128 = array [0..15] of Byte; + {* AES128 Կṹ16 ֽ} + + TCnAESKey192 = array [0..23] of Byte; + {* AES192 Կṹ24 ֽ} + + TCnAESKey256 = array [0..31] of Byte; + {* AES256 Կṹ32 ֽ} + + TCnAESExpandedKey128 = array [0..43] of Cardinal; + {* AES128 չԿṹ} + + TCnAESExpandedKey192 = array [0..53] of Cardinal; + {* AES192 չԿṹ} + + TCnAESExpandedKey256 = array [0..63] of Cardinal; + {* AES256 չԿṹ} + + PCnAESBuffer = ^TCnAESBuffer; + PCnAESKey128 = ^TCnAESKey128; + PCnAESKey192 = ^TCnAESKey192; + PCnAESKey256 = ^TCnAESKey256; + PCnAESExpandedKey128 = ^TCnAESExpandedKey128; + PCnAESExpandedKey192 = ^TCnAESExpandedKey192; + PCnAESExpandedKey256 = ^TCnAESExpandedKey256; + + TCnAESCTRNonce = array[0..3] of Byte; + {* CTR ģʽµ Nonce ṹ4 ֽ} + TCnAESCTRIv = array[0..7] of Byte; + {* CTR ģʽµijʼṹ8 ֽ} + +// Key Expansion Routines for Encryption + +procedure ExpandAESKeyForEncryption128(const Key: TCnAESKey128; + var ExpandedKey: TCnAESExpandedKey128); +{* ڼܳչ AES128 Կ + + + const Key: TCnAESKey128 - չ AES128 Կ + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForEncryption192(const Key: TCnAESKey192; + var ExpandedKey: TCnAESExpandedKey192); +{* ڼܳչ AES192 Կ + + + const Key: TCnAESKey192 - չ AES192 Կ + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForEncryption256(const Key: TCnAESKey256; + var ExpandedKey: TCnAESExpandedKey256); +{* ڼܳչ AES256 Կ + + + const Key: TCnAESKey256 - չ AES256 Կ + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} + +// Block Encryption Routines ܣInBuf OutBuf ͬһ + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); overload; +{* AES128 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey128 - չ AES128 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); overload; +{* AES192 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey192 - չ AES192 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); overload; +{* AES256 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey256 - չ AES256 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +{* AES128 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey128 - չ AES128 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure EncryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +{* AES192 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey192 - չ AES192 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure EncryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +{* AES256 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey256 - չ AES256 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +// Stream Encryption Routines (ECB mode) ECB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); overload; +{* AES128 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); overload; +{* AES128 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); overload; +{* AES256 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); overload; +{* AES192 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); overload; +{* AES256 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); overload; +{* AES256 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +{* AES128 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +{* AES128 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES192StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +{* AES192 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +{* AES192 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES256StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +{* AES256 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +{* AES256 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + Dest: TStream - + + ֵޣ +} + +// Stream Encryption Routines (CBC mode) CBC + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES192StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES256StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Encryption Routines (CFB mode) CFB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Encryption Routines (OFB mode) OFB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES192StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - ?? + + ֵޣ +} +procedure EncryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES256StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Encryption Routines (CTR mode) CTR + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES128 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES128 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES192 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES192 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES256 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES256 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES128 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES128 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES192 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES192 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES256 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES256 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Key Transformation Routines for Decryption + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey128); overload; +{* ڽܳչ AES128 Կ + + + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey128; + var ExpandedKey: TCnAESExpandedKey128); overload; +{* ڽܳչ AES128 Կ + + + const Key: TCnAESKey128 - չ AES128 Կ + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey192); overload; +{* ڽܳչ AES192 Կ + + + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey192; + var ExpandedKey: TCnAESExpandedKey192); overload; +{* ڽܳչ AES192 Կ + + + const Key: TCnAESKey192 - չ AES192 Կ + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey256); overload; +{* ڽܳչ AES256 Կ + + + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey256; + var ExpandedKey: TCnAESExpandedKey256); overload; +{* ڽܳչ AES256 Կ + + + const Key: TCnAESKey256 - չ AES256 Կ + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure ExpandAESKeyForDecryption128(var ExpandedKey: TCnAESExpandedKey128); +{* ڽܳչ AES128 Կ + + + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption128Expanded(const Key: TCnAESKey128; + var ExpandedKey: TCnAESExpandedKey128); +{* ڽܳչ AES128 Կ + + + const Key: TCnAESKey128 - չ AES128 Կ + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption192(var ExpandedKey: TCnAESExpandedKey192); +{* ڽܳչ AES192 Կ + + + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption192Expanded(const Key: TCnAESKey192; + var ExpandedKey: TCnAESExpandedKey192); +{* ڽܳչ AES192 Կ + + + const Key: TCnAESKey192 - չ AES192 Կ + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption256(var ExpandedKey: TCnAESExpandedKey256); +{* ڽܳչ AES256 Կ + + + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption256Expanded(const Key: TCnAESKey256; + var ExpandedKey: TCnAESExpandedKey256); +{* ڽܳչ AES256 Կ + + + const Key: TCnAESKey256 - չ AES256 Կ + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} + +// Block Decryption Routines + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); overload; +{* AES128 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey128 - չ AES128 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); overload; +{* AES192 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey192 - չ AES192 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); overload; +{* AES256 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey256 - չ AES256 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +{* AES128 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey128 - չ AES128 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure DecryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +{* AES192 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey192 - չ AES192 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure DecryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +{* AES256 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey256 - չ AES256 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +// Stream Decryption Routines (ECB mode) ECB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); overload; +{* AES128 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); overload; +{* AES128 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); overload; +{* AES192 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); overload; +{* AES192 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); overload; +{* AES256 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); overload; +{* AES256 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +{* AES128 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +{* AES128 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAES192StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +{* AES192 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +{* AES192 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAES256StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +{* AES256 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +{* AES156 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + Dest: TStream - + + ֵޣ +} + +// Stream Decryption Routines (CBC mode) CBC + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Decryption Routines (CFB mode) CFB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Decryption Routines (OFB mode) OFB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Decryption Routines (CTR mode) CTR + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES128 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES128 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES192 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES192 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES256 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES256 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES128 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES128 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES192 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES192 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES256 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES256 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// ============== ַʮַ֮ļӽ =================== + +function AESEncryptEcbStrToHex(Value: AnsiString; Key: AnsiString; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES ECB ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptEcbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES ECB ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +function AESEncryptCbcStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CBC ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCbcStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CBC ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +function AESEncryptCfbStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CFB ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CFB ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +function AESEncryptOfbStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES OFB ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptOfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES OFB ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +function AESEncryptCtrStrToHex(Value: AnsiString; Key: AnsiString; + const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CTR ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const Iv: TCnAESCTRIv - 8 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCtrStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CTR ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const Iv: TCnAESCTRIv - 8 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +// ================= ֽֽ֮ļӽ ==================== + +function AESEncryptEcbBytes(Value: TBytes; Key: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES ECB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptEcbBytes(Value: TBytes; Key: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES ECB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCbcBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CBC ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptCbcBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CBC ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CFB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptCfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CFB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptOfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES OFB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptOfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES OFB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCtrBytes(Value: TBytes; Key: TBytes; Nonce: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CTR ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Nonce: TBytes - 4 ֽ Nonce 飬̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptCtrBytes(Value: TBytes; Key: TBytes; Nonce: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CTR ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Nonce: TBytes - 4 ֽ Nonce 飬̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +// ============== ֽʮַ֮ļӽ ================= + +function AESEncryptEcbBytesToHex(Value: TBytes; Key: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES ECB ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptEcbBytesFromHex(const HexStr: AnsiString; Key: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES ECB ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCbcBytesToHex(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CBC ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCbcBytesFromHex(const HexStr: AnsiString; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CBC ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCfbBytesToHex(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CFB ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCfbBytesFromHex(const HexStr: AnsiString; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CFB ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptOfbBytesToHex(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES OFB ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptOfbBytesFromHex(const HexStr: AnsiString; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES OFB ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCtrBytesToHex(Value: TBytes; Key: TBytes; Nonce: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CTR ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Nonce: TBytes - 4 ֽ Nonce ֽ飬̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCtrBytesFromHex(const HexStr: AnsiString; Key: TBytes; Nonce: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CTR ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Nonce: TBytes - 4 ֽ Nonce ֽ飬̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +implementation + +resourcestring + SCnErrorAESInvalidInBufSize = 'Invalid Buffer Size for Decryption'; + SCnErrorAESReadError = 'Stream Read Error'; + SCnErrorAESWriteError = 'Stream Write Error'; + +function Min(A, B: Integer): Integer; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + if A < B then + Result := A + else + Result := B; +end; + +const + Rcon: array [1..30] of Cardinal = ( + $00000001, $00000002, $00000004, $00000008, $00000010, $00000020, + $00000040, $00000080, $0000001B, $00000036, $0000006C, $000000D8, + $000000AB, $0000004D, $0000009A, $0000002F, $0000005E, $000000BC, + $00000063, $000000C6, $00000097, $00000035, $0000006A, $000000D4, + $000000B3, $0000007D, $000000FA, $000000EF, $000000C5, $00000091 + ); + + ForwardTable: array [0..255] of Cardinal = ( + $A56363C6, $847C7CF8, $997777EE, $8D7B7BF6, $0DF2F2FF, $BD6B6BD6, $B16F6FDE, $54C5C591, + $50303060, $03010102, $A96767CE, $7D2B2B56, $19FEFEE7, $62D7D7B5, $E6ABAB4D, $9A7676EC, + $45CACA8F, $9D82821F, $40C9C989, $877D7DFA, $15FAFAEF, $EB5959B2, $C947478E, $0BF0F0FB, + $ECADAD41, $67D4D4B3, $FDA2A25F, $EAAFAF45, $BF9C9C23, $F7A4A453, $967272E4, $5BC0C09B, + $C2B7B775, $1CFDFDE1, $AE93933D, $6A26264C, $5A36366C, $413F3F7E, $02F7F7F5, $4FCCCC83, + $5C343468, $F4A5A551, $34E5E5D1, $08F1F1F9, $937171E2, $73D8D8AB, $53313162, $3F15152A, + $0C040408, $52C7C795, $65232346, $5EC3C39D, $28181830, $A1969637, $0F05050A, $B59A9A2F, + $0907070E, $36121224, $9B80801B, $3DE2E2DF, $26EBEBCD, $6927274E, $CDB2B27F, $9F7575EA, + $1B090912, $9E83831D, $742C2C58, $2E1A1A34, $2D1B1B36, $B26E6EDC, $EE5A5AB4, $FBA0A05B, + $F65252A4, $4D3B3B76, $61D6D6B7, $CEB3B37D, $7B292952, $3EE3E3DD, $712F2F5E, $97848413, + $F55353A6, $68D1D1B9, $00000000, $2CEDEDC1, $60202040, $1FFCFCE3, $C8B1B179, $ED5B5BB6, + $BE6A6AD4, $46CBCB8D, $D9BEBE67, $4B393972, $DE4A4A94, $D44C4C98, $E85858B0, $4ACFCF85, + $6BD0D0BB, $2AEFEFC5, $E5AAAA4F, $16FBFBED, $C5434386, $D74D4D9A, $55333366, $94858511, + $CF45458A, $10F9F9E9, $06020204, $817F7FFE, $F05050A0, $443C3C78, $BA9F9F25, $E3A8A84B, + $F35151A2, $FEA3A35D, $C0404080, $8A8F8F05, $AD92923F, $BC9D9D21, $48383870, $04F5F5F1, + $DFBCBC63, $C1B6B677, $75DADAAF, $63212142, $30101020, $1AFFFFE5, $0EF3F3FD, $6DD2D2BF, + $4CCDCD81, $140C0C18, $35131326, $2FECECC3, $E15F5FBE, $A2979735, $CC444488, $3917172E, + $57C4C493, $F2A7A755, $827E7EFC, $473D3D7A, $AC6464C8, $E75D5DBA, $2B191932, $957373E6, + $A06060C0, $98818119, $D14F4F9E, $7FDCDCA3, $66222244, $7E2A2A54, $AB90903B, $8388880B, + $CA46468C, $29EEEEC7, $D3B8B86B, $3C141428, $79DEDEA7, $E25E5EBC, $1D0B0B16, $76DBDBAD, + $3BE0E0DB, $56323264, $4E3A3A74, $1E0A0A14, $DB494992, $0A06060C, $6C242448, $E45C5CB8, + $5DC2C29F, $6ED3D3BD, $EFACAC43, $A66262C4, $A8919139, $A4959531, $37E4E4D3, $8B7979F2, + $32E7E7D5, $43C8C88B, $5937376E, $B76D6DDA, $8C8D8D01, $64D5D5B1, $D24E4E9C, $E0A9A949, + $B46C6CD8, $FA5656AC, $07F4F4F3, $25EAEACF, $AF6565CA, $8E7A7AF4, $E9AEAE47, $18080810, + $D5BABA6F, $887878F0, $6F25254A, $722E2E5C, $241C1C38, $F1A6A657, $C7B4B473, $51C6C697, + $23E8E8CB, $7CDDDDA1, $9C7474E8, $211F1F3E, $DD4B4B96, $DCBDBD61, $868B8B0D, $858A8A0F, + $907070E0, $423E3E7C, $C4B5B571, $AA6666CC, $D8484890, $05030306, $01F6F6F7, $120E0E1C, + $A36161C2, $5F35356A, $F95757AE, $D0B9B969, $91868617, $58C1C199, $271D1D3A, $B99E9E27, + $38E1E1D9, $13F8F8EB, $B398982B, $33111122, $BB6969D2, $70D9D9A9, $898E8E07, $A7949433, + $B69B9B2D, $221E1E3C, $92878715, $20E9E9C9, $49CECE87, $FF5555AA, $78282850, $7ADFDFA5, + $8F8C8C03, $F8A1A159, $80898909, $170D0D1A, $DABFBF65, $31E6E6D7, $C6424284, $B86868D0, + $C3414182, $B0999929, $772D2D5A, $110F0F1E, $CBB0B07B, $FC5454A8, $D6BBBB6D, $3A16162C + ); + + LastForwardTable: array [0..255] of Cardinal = ( + $00000063, $0000007C, $00000077, $0000007B, $000000F2, $0000006B, $0000006F, $000000C5, + $00000030, $00000001, $00000067, $0000002B, $000000FE, $000000D7, $000000AB, $00000076, + $000000CA, $00000082, $000000C9, $0000007D, $000000FA, $00000059, $00000047, $000000F0, + $000000AD, $000000D4, $000000A2, $000000AF, $0000009C, $000000A4, $00000072, $000000C0, + $000000B7, $000000FD, $00000093, $00000026, $00000036, $0000003F, $000000F7, $000000CC, + $00000034, $000000A5, $000000E5, $000000F1, $00000071, $000000D8, $00000031, $00000015, + $00000004, $000000C7, $00000023, $000000C3, $00000018, $00000096, $00000005, $0000009A, + $00000007, $00000012, $00000080, $000000E2, $000000EB, $00000027, $000000B2, $00000075, + $00000009, $00000083, $0000002C, $0000001A, $0000001B, $0000006E, $0000005A, $000000A0, + $00000052, $0000003B, $000000D6, $000000B3, $00000029, $000000E3, $0000002F, $00000084, + $00000053, $000000D1, $00000000, $000000ED, $00000020, $000000FC, $000000B1, $0000005B, + $0000006A, $000000CB, $000000BE, $00000039, $0000004A, $0000004C, $00000058, $000000CF, + $000000D0, $000000EF, $000000AA, $000000FB, $00000043, $0000004D, $00000033, $00000085, + $00000045, $000000F9, $00000002, $0000007F, $00000050, $0000003C, $0000009F, $000000A8, + $00000051, $000000A3, $00000040, $0000008F, $00000092, $0000009D, $00000038, $000000F5, + $000000BC, $000000B6, $000000DA, $00000021, $00000010, $000000FF, $000000F3, $000000D2, + $000000CD, $0000000C, $00000013, $000000EC, $0000005F, $00000097, $00000044, $00000017, + $000000C4, $000000A7, $0000007E, $0000003D, $00000064, $0000005D, $00000019, $00000073, + $00000060, $00000081, $0000004F, $000000DC, $00000022, $0000002A, $00000090, $00000088, + $00000046, $000000EE, $000000B8, $00000014, $000000DE, $0000005E, $0000000B, $000000DB, + $000000E0, $00000032, $0000003A, $0000000A, $00000049, $00000006, $00000024, $0000005C, + $000000C2, $000000D3, $000000AC, $00000062, $00000091, $00000095, $000000E4, $00000079, + $000000E7, $000000C8, $00000037, $0000006D, $0000008D, $000000D5, $0000004E, $000000A9, + $0000006C, $00000056, $000000F4, $000000EA, $00000065, $0000007A, $000000AE, $00000008, + $000000BA, $00000078, $00000025, $0000002E, $0000001C, $000000A6, $000000B4, $000000C6, + $000000E8, $000000DD, $00000074, $0000001F, $0000004B, $000000BD, $0000008B, $0000008A, + $00000070, $0000003E, $000000B5, $00000066, $00000048, $00000003, $000000F6, $0000000E, + $00000061, $00000035, $00000057, $000000B9, $00000086, $000000C1, $0000001D, $0000009E, + $000000E1, $000000F8, $00000098, $00000011, $00000069, $000000D9, $0000008E, $00000094, + $0000009B, $0000001E, $00000087, $000000E9, $000000CE, $00000055, $00000028, $000000DF, + $0000008C, $000000A1, $00000089, $0000000D, $000000BF, $000000E6, $00000042, $00000068, + $00000041, $00000099, $0000002D, $0000000F, $000000B0, $00000054, $000000BB, $00000016 + ); + + InverseTable: array [0..255] of Cardinal = ( + $50A7F451, $5365417E, $C3A4171A, $965E273A, $CB6BAB3B, $F1459D1F, $AB58FAAC, $9303E34B, + $55FA3020, $F66D76AD, $9176CC88, $254C02F5, $FCD7E54F, $D7CB2AC5, $80443526, $8FA362B5, + $495AB1DE, $671BBA25, $980EEA45, $E1C0FE5D, $02752FC3, $12F04C81, $A397468D, $C6F9D36B, + $E75F8F03, $959C9215, $EB7A6DBF, $DA595295, $2D83BED4, $D3217458, $2969E049, $44C8C98E, + $6A89C275, $78798EF4, $6B3E5899, $DD71B927, $B64FE1BE, $17AD88F0, $66AC20C9, $B43ACE7D, + $184ADF63, $82311AE5, $60335197, $457F5362, $E07764B1, $84AE6BBB, $1CA081FE, $942B08F9, + $58684870, $19FD458F, $876CDE94, $B7F87B52, $23D373AB, $E2024B72, $578F1FE3, $2AAB5566, + $0728EBB2, $03C2B52F, $9A7BC586, $A50837D3, $F2872830, $B2A5BF23, $BA6A0302, $5C8216ED, + $2B1CCF8A, $92B479A7, $F0F207F3, $A1E2694E, $CDF4DA65, $D5BE0506, $1F6234D1, $8AFEA6C4, + $9D532E34, $A055F3A2, $32E18A05, $75EBF6A4, $39EC830B, $AAEF6040, $069F715E, $51106EBD, + $F98A213E, $3D06DD96, $AE053EDD, $46BDE64D, $B58D5491, $055DC471, $6FD40604, $FF155060, + $24FB9819, $97E9BDD6, $CC434089, $779ED967, $BD42E8B0, $888B8907, $385B19E7, $DBEEC879, + $470A7CA1, $E90F427C, $C91E84F8, $00000000, $83868009, $48ED2B32, $AC70111E, $4E725A6C, + $FBFF0EFD, $5638850F, $1ED5AE3D, $27392D36, $64D90F0A, $21A65C68, $D1545B9B, $3A2E3624, + $B1670A0C, $0FE75793, $D296EEB4, $9E919B1B, $4FC5C080, $A220DC61, $694B775A, $161A121C, + $0ABA93E2, $E52AA0C0, $43E0223C, $1D171B12, $0B0D090E, $ADC78BF2, $B9A8B62D, $C8A91E14, + $8519F157, $4C0775AF, $BBDD99EE, $FD607FA3, $9F2601F7, $BCF5725C, $C53B6644, $347EFB5B, + $7629438B, $DCC623CB, $68FCEDB6, $63F1E4B8, $CADC31D7, $10856342, $40229713, $2011C684, + $7D244A85, $F83DBBD2, $1132F9AE, $6DA129C7, $4B2F9E1D, $F330B2DC, $EC52860D, $D0E3C177, + $6C16B32B, $99B970A9, $FA489411, $2264E947, $C48CFCA8, $1A3FF0A0, $D82C7D56, $EF903322, + $C74E4987, $C1D138D9, $FEA2CA8C, $360BD498, $CF81F5A6, $28DE7AA5, $268EB7DA, $A4BFAD3F, + $E49D3A2C, $0D927850, $9BCC5F6A, $62467E54, $C2138DF6, $E8B8D890, $5EF7392E, $F5AFC382, + $BE805D9F, $7C93D069, $A92DD56F, $B31225CF, $3B99ACC8, $A77D1810, $6E639CE8, $7BBB3BDB, + $097826CD, $F418596E, $01B79AEC, $A89A4F83, $656E95E6, $7EE6FFAA, $08CFBC21, $E6E815EF, + $D99BE7BA, $CE366F4A, $D4099FEA, $D67CB029, $AFB2A431, $31233F2A, $3094A5C6, $C066A235, + $37BC4E74, $A6CA82FC, $B0D090E0, $15D8A733, $4A9804F1, $F7DAEC41, $0E50CD7F, $2FF69117, + $8DD64D76, $4DB0EF43, $544DAACC, $DF0496E4, $E3B5D19E, $1B886A4C, $B81F2CC1, $7F516546, + $04EA5E9D, $5D358C01, $737487FA, $2E410BFB, $5A1D67B3, $52D2DB92, $335610E9, $1347D66D, + $8C61D79A, $7A0CA137, $8E14F859, $893C13EB, $EE27A9CE, $35C961B7, $EDE51CE1, $3CB1477A, + $59DFD29C, $3F73F255, $79CE1418, $BF37C773, $EACDF753, $5BAAFD5F, $146F3DDF, $86DB4478, + $81F3AFCA, $3EC468B9, $2C342438, $5F40A3C2, $72C31D16, $0C25E2BC, $8B493C28, $41950DFF, + $7101A839, $DEB30C08, $9CE4B4D8, $90C15664, $6184CB7B, $70B632D5, $745C6C48, $4257B8D0 + ); + + LastInverseTable: array [0..255] of Cardinal = ( + $00000052, $00000009, $0000006A, $000000D5, $00000030, $00000036, $000000A5, $00000038, + $000000BF, $00000040, $000000A3, $0000009E, $00000081, $000000F3, $000000D7, $000000FB, + $0000007C, $000000E3, $00000039, $00000082, $0000009B, $0000002F, $000000FF, $00000087, + $00000034, $0000008E, $00000043, $00000044, $000000C4, $000000DE, $000000E9, $000000CB, + $00000054, $0000007B, $00000094, $00000032, $000000A6, $000000C2, $00000023, $0000003D, + $000000EE, $0000004C, $00000095, $0000000B, $00000042, $000000FA, $000000C3, $0000004E, + $00000008, $0000002E, $000000A1, $00000066, $00000028, $000000D9, $00000024, $000000B2, + $00000076, $0000005B, $000000A2, $00000049, $0000006D, $0000008B, $000000D1, $00000025, + $00000072, $000000F8, $000000F6, $00000064, $00000086, $00000068, $00000098, $00000016, + $000000D4, $000000A4, $0000005C, $000000CC, $0000005D, $00000065, $000000B6, $00000092, + $0000006C, $00000070, $00000048, $00000050, $000000FD, $000000ED, $000000B9, $000000DA, + $0000005E, $00000015, $00000046, $00000057, $000000A7, $0000008D, $0000009D, $00000084, + $00000090, $000000D8, $000000AB, $00000000, $0000008C, $000000BC, $000000D3, $0000000A, + $000000F7, $000000E4, $00000058, $00000005, $000000B8, $000000B3, $00000045, $00000006, + $000000D0, $0000002C, $0000001E, $0000008F, $000000CA, $0000003F, $0000000F, $00000002, + $000000C1, $000000AF, $000000BD, $00000003, $00000001, $00000013, $0000008A, $0000006B, + $0000003A, $00000091, $00000011, $00000041, $0000004F, $00000067, $000000DC, $000000EA, + $00000097, $000000F2, $000000CF, $000000CE, $000000F0, $000000B4, $000000E6, $00000073, + $00000096, $000000AC, $00000074, $00000022, $000000E7, $000000AD, $00000035, $00000085, + $000000E2, $000000F9, $00000037, $000000E8, $0000001C, $00000075, $000000DF, $0000006E, + $00000047, $000000F1, $0000001A, $00000071, $0000001D, $00000029, $000000C5, $00000089, + $0000006F, $000000B7, $00000062, $0000000E, $000000AA, $00000018, $000000BE, $0000001B, + $000000FC, $00000056, $0000003E, $0000004B, $000000C6, $000000D2, $00000079, $00000020, + $0000009A, $000000DB, $000000C0, $000000FE, $00000078, $000000CD, $0000005A, $000000F4, + $0000001F, $000000DD, $000000A8, $00000033, $00000088, $00000007, $000000C7, $00000031, + $000000B1, $00000012, $00000010, $00000059, $00000027, $00000080, $000000EC, $0000005F, + $00000060, $00000051, $0000007F, $000000A9, $00000019, $000000B5, $0000004A, $0000000D, + $0000002D, $000000E5, $0000007A, $0000009F, $00000093, $000000C9, $0000009C, $000000EF, + $000000A0, $000000E0, $0000003B, $0000004D, $000000AE, $0000002A, $000000F5, $000000B0, + $000000C8, $000000EB, $000000BB, $0000003C, $00000083, $00000053, $00000099, $00000061, + $00000017, $0000002B, $00000004, $0000007E, $000000BA, $00000077, $000000D6, $00000026, + $000000E1, $00000069, $00000014, $00000063, $00000055, $00000021, $0000000C, $0000007D + ); + +procedure ExpandAESKeyForEncryption128(const Key: TCnAESKey128; var ExpandedKey: + TCnAESExpandedKey128); +var + I, J: Integer; + T: Cardinal; + W0, W1, W2, W3: Cardinal; +begin + ExpandedKey[0] := PCardinal(@Key[0])^; + ExpandedKey[1] := PCardinal(@Key[4])^; + ExpandedKey[2] := PCardinal(@Key[8])^; + ExpandedKey[3] := PCardinal(@Key[12])^; + I := 0; J := 1; + repeat + T := (ExpandedKey[I + 3] shl 24) or (ExpandedKey[I + 3] shr 8); + W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)]; + W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)]; + ExpandedKey[I + 4] := ExpandedKey[I] xor + (W0 xor ((W1 shl 8) or (W1 shr 24)) xor + ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J]; + Inc(J); + ExpandedKey[I + 5] := ExpandedKey[I + 1] xor ExpandedKey[I + 4]; + ExpandedKey[I + 6] := ExpandedKey[I + 2] xor ExpandedKey[I + 5]; + ExpandedKey[I + 7] := ExpandedKey[I + 3] xor ExpandedKey[I + 6]; + Inc(I, 4); + until I >= 40; +end; + +procedure ExpandAESKeyForEncryption192(const Key: TCnAESKey192; var ExpandedKey: + TCnAESExpandedKey192); +var + I, J: Integer; + T: Cardinal; + W0, W1, W2, W3: Cardinal; +begin + ExpandedKey[0] := PCardinal(@Key[0])^; + ExpandedKey[1] := PCardinal(@Key[4])^; + ExpandedKey[2] := PCardinal(@Key[8])^; + ExpandedKey[3] := PCardinal(@Key[12])^; + ExpandedKey[4] := PCardinal(@Key[16])^; + ExpandedKey[5] := PCardinal(@Key[20])^; + I := 0; J := 1; + repeat + T := (ExpandedKey[I + 5] shl 24) or (ExpandedKey[I + 5] shr 8); + W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)]; + W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)]; + ExpandedKey[I + 6] := ExpandedKey[I] xor + (W0 xor ((W1 shl 8) or (W1 shr 24)) xor + ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J]; + Inc(J); + ExpandedKey[I + 7] := ExpandedKey[I + 1] xor ExpandedKey[I + 6]; + ExpandedKey[I + 8] := ExpandedKey[I + 2] xor ExpandedKey[I + 7]; + ExpandedKey[I + 9] := ExpandedKey[I + 3] xor ExpandedKey[I + 8]; + ExpandedKey[I + 10] := ExpandedKey[I + 4] xor ExpandedKey[I + 9]; + ExpandedKey[I + 11] := ExpandedKey[I + 5] xor ExpandedKey[I + 10]; + Inc(I, 6); + until I >= 46; +end; + +procedure ExpandAESKeyForEncryption256(const Key: TCnAESKey256; var ExpandedKey: + TCnAESExpandedKey256); +var + I, J: Integer; + T: Cardinal; + W0, W1, W2, W3: Cardinal; +begin + ExpandedKey[0] := PCardinal(@Key[0])^; + ExpandedKey[1] := PCardinal(@Key[4])^; + ExpandedKey[2] := PCardinal(@Key[8])^; + ExpandedKey[3] := PCardinal(@Key[12])^; + ExpandedKey[4] := PCardinal(@Key[16])^; + ExpandedKey[5] := PCardinal(@Key[20])^; + ExpandedKey[6] := PCardinal(@Key[24])^; + ExpandedKey[7] := PCardinal(@Key[28])^; + I := 0; J := 1; + repeat + T := (ExpandedKey[I + 7] shl 24) or (ExpandedKey[I + 7] shr 8); + W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)]; + W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)]; + ExpandedKey[I + 8] := ExpandedKey[I] xor + (W0 xor ((W1 shl 8) or (W1 shr 24)) xor + ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J]; + Inc(J); + ExpandedKey[I + 9] := ExpandedKey[I + 1] xor ExpandedKey[I + 8]; + ExpandedKey[I + 10] := ExpandedKey[I + 2] xor ExpandedKey[I + 9]; + ExpandedKey[I + 11] := ExpandedKey[I + 3] xor ExpandedKey[I + 10]; + W0 := LastForwardTable[Byte(ExpandedKey[I + 11])]; + W1 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 8)]; + W2 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 16)]; + W3 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 24)]; + ExpandedKey[I + 12] := ExpandedKey[I + 4] xor + (W0 xor ((W1 shl 8) or (W1 shr 24)) xor + ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))); + ExpandedKey[I + 13] := ExpandedKey[I + 5] xor ExpandedKey[I + 12]; + ExpandedKey[I + 14] := ExpandedKey[I + 6] xor ExpandedKey[I + 13]; + ExpandedKey[I + 15] := ExpandedKey[I + 7] xor ExpandedKey[I + 14]; + Inc(I, 8); + until I >= 52; +end; + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +begin + EncryptAES128(InBuf, Key, OutBuf); +end; + +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +begin + EncryptAES192(InBuf, Key, OutBuf); +end; + +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +begin + EncryptAES256(InBuf, Key, OutBuf); +end; + +{$ENDIF} + +procedure EncryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[0]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[1]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[2]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[3]; + + // performing transformation 9 times + // round 1 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // round 2 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 3 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 4 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 5 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 6 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 7 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 8 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 9 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // last round of transformations + W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)]; + W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)]; + W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)]; + W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)]; + W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +procedure EncryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[0]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[1]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[2]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[3]; + + // performing transformation 11 times + // round 1 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // round 2 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 3 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 4 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 5 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 6 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 7 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 8 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 9 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 10 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + // round 11 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; + // last round of transformations + W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)]; + W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[48]; + W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)]; + W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[49]; + W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)]; + W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[50]; + W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)]; + W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[51]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +procedure EncryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[0]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[1]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[2]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[3]; + + // performing transformation 13 times + // round 1 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // round 2 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 3 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 4 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 5 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 6 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 7 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 8 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 9 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 10 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + // round 11 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; + // round 12 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[48]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[49]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[50]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[51]; + // round 13 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[52]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[53]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[54]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[55]; + // last round of transformations + W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)]; + W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[56]; + W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)]; + W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[57]; + W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)]; + W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[58]; + W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)]; + W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[59]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey128); +begin + ExpandAESKeyForDecryption128(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey128; + var ExpandedKey: TCnAESExpandedKey128); +begin + ExpandAESKeyForDecryption128Expanded(Key, ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey192); +begin + ExpandAESKeyForDecryption192(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey192; + var ExpandedKey: TCnAESExpandedKey192); +begin + ExpandAESKeyForDecryption192Expanded(Key, ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey256); +begin + ExpandAESKeyForDecryption256(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey256; + var ExpandedKey: TCnAESExpandedKey256); +begin + ExpandAESKeyForDecryption256Expanded(Key, ExpandedKey); +end; + +{$ENDIF} + +procedure ExpandAESKeyForDecryption128(var ExpandedKey: TCnAESExpandedKey128); +var + I: Integer; + U, F2, F4, F8, F9: Cardinal; +begin + for I := 1 to 9 do + begin + F9 := ExpandedKey[I * 4]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 1]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 2]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 3]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + end; +end; + +procedure ExpandAESKeyForDecryption128Expanded(const Key: TCnAESKey128; var ExpandedKey: + TCnAESExpandedKey128); +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + ExpandAESKeyForDecryption128(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption192(var ExpandedKey: TCnAESExpandedKey192); +var + I: Integer; + U, F2, F4, F8, F9: Cardinal; +begin + for I := 1 to 11 do + begin + F9 := ExpandedKey[I * 4]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 1]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 2]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 3]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + end; +end; + +procedure ExpandAESKeyForDecryption192Expanded(const Key: TCnAESKey192; var ExpandedKey: + TCnAESExpandedKey192); +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + ExpandAESKeyForDecryption192(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption256(var ExpandedKey: TCnAESExpandedKey256); +var + I: Integer; + U, F2, F4, F8, F9: Cardinal; +begin + for I := 1 to 13 do + begin + F9 := ExpandedKey[I * 4]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 1]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 2]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 3]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + end; +end; + +procedure ExpandAESKeyForDecryption256Expanded(const Key: TCnAESKey256; var ExpandedKey: + TCnAESExpandedKey256); +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + ExpandAESKeyForDecryption256(ExpandedKey); +end; + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +begin + DecryptAES128(InBuf, Key, OutBuf); +end; + +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +begin + DecryptAES192(InBuf, Key, OutBuf); +end; + +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +begin + DecryptAES256(InBuf, Key, OutBuf); +end; + +{$ENDIF} + +procedure DecryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[40]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[41]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[42]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[43]; + + // performing transformations 9 times + // round 1 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 2 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 3 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 4 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 5 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 6 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 7 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 8 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 9 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // last round of transformations + W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)]; + W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[0]; + W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)]; + W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[1]; + W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)]; + W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[2]; + W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)]; + W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[3]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +procedure DecryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[48]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[49]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[50]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[51]; + + // performing transformations 11 times + // round 1 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; + // round 2 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + // round 3 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 4 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 5 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 6 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 7 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 8 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 9 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 10 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 11 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // last round of transformations + W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)]; + W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[0]; + W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)]; + W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[1]; + W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)]; + W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[2]; + W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)]; + W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[3]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +procedure DecryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[56]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[57]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[58]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[59]; + + // performing transformations 13 times + // round 1 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[52]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[53]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[54]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[55]; + // round 2 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[48]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[49]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[50]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[51]; + // round 3 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; + // round 4 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + // round 5 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 6 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 7 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 8 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 9 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 10 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 11 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 12 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 13 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // last round of transformations + W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)]; + W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[0]; + W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)]; + W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[1]; + W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)]; + W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[2]; + W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)]; + W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[3]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +// Stream Encryption Routines (ECB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +begin + EncryptAES128StreamECB(Source, Count, Key, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +begin + EncryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +begin + EncryptAES192StreamECB(Source, Count, Key, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +begin + EncryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +begin + EncryptAES256StreamECB(Source, Count, Key, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +begin + EncryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAES192StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAES256StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + EncryptAES128(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + EncryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + EncryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (ECB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +begin + DecryptAES128StreamECB(Source, Count, Key, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +begin + DecryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +begin + DecryptAES192StreamECB(Source, Count, Key, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +begin + DecryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +begin + DecryptAES256StreamECB(Source, Count, Key, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +begin + DecryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForDecryption128Expanded(Key, ExpandedKey); + DecryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + DecryptAES128(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +procedure DecryptAES192StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForDecryption192Expanded(Key, ExpandedKey); + DecryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + DecryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +procedure DecryptAES256StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForDecryption256Expanded(Key, ExpandedKey); + DecryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + DecryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +// Stream Encryption Routines (CBC mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES128StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES192StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES256StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); // Ҫÿһ鶼 + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; // ԭʼ IV + EncryptAES128(TempIn, ExpandedKey, TempOut); // ټ + Done := Dest.Write(TempOut, SizeOf(TempOut)); // д + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; // ݴԭʼ IV һʹ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES128(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (CBC mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES128StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES192StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES256StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForDecryption128Expanded(Key, ExpandedKey); + DecryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector1, Vector2: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + Vector1 := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + Vector2 := TempIn; + DecryptAES128(TempIn, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@Vector1[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@Vector1[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector1 := Vector2; + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +procedure DecryptAES192StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForDecryption192Expanded(Key, ExpandedKey); + DecryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector1, Vector2: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + Vector1 := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + Vector2 := TempIn; + DecryptAES192(TempIn, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@Vector1[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@Vector1[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector1 := Vector2; + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +procedure DecryptAES256StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForDecryption256Expanded(Key, ExpandedKey); + DecryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector1, Vector2: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); // CBC Ϊ AES ֿܲģԱ + Vector1 := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + Vector2 := TempIn; + DecryptAES256(TempIn, ExpandedKey, TempOut); // Ƚ + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; // ܺݺ Iv õ + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@Vector1[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@Vector1[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); // дȥ + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector1 := Vector2; // ȡ Iv Ϊһκͽ + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +// Stream Encryption Routines (CFB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES128StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES192StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES256StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); // Key ȼ Iv + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); // ĽдĽ + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; // Ľȡ Iv һּ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (CFB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES128StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES192StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES256StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + DecryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + // CFB Ϊ AES ֿܲĶ򣨳Ŀɶ + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); // + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); // Iv ȼܡעǼܣǽܣ + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); // дȥ + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempIn; // ȡ Iv Ϊһμ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then // һ鲻Ϊ + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, Count); // дȥ + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +procedure DecryptAES192StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + DecryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempIn; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, Count); + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +procedure DecryptAES256StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + DecryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempIn; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, Count); + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +// Stream Encryption Routines (OFB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES128StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES192StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES256StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); // Key ȼ Iv + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; // ܽȡ Iv һּܣעⲻ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (OFB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES128StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES192StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES256StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + DecryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + // OFB Ϊ AES ֿܲĶ򣨳Ŀɶ + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); // + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); // Iv ȼܡעǼܣǽܣ + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // дȥ + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempOut; // ȡ Iv Ϊһǰ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then // һ鲻Ϊ + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, Count); // дȥ + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +procedure DecryptAES192StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + DecryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +procedure DecryptAES256StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + DecryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +// Stream Encryption Routines (CTR mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES128StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES192StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES256StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done, Cnt, T: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Cnt := 1; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES128(Vector, ExpandedKey, TempOut); // Key ȼƴ Iv + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + + Inc(Cnt); // һ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done, Cnt, T: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Cnt := 1; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES192(Vector, ExpandedKey, TempOut); // Key ȼƴ Iv + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + + Inc(Cnt); // һ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done, Cnt, T: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Cnt := 1; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES256(Vector, ExpandedKey, TempOut); // Key ȼƴ Iv + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + + Inc(Cnt); // һ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (CTR mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES128StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES192StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES256StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + DecryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES192StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + DecryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES256StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + DecryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +// AES ECB ַתʮ +function AESEncryptEcbStrToHex(Value: AnsiString; Key: AnsiString; + KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamECB(SS, 0, AESKey128, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamECB(SS, 0, AESKey192, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamECB(SS, 0, AESKey256, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES ECB ʮַ +function AESDecryptEcbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamECB(SS, SS.Size - SS.Position, AESKey128, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamECB(SS, SS.Size - SS.Position, AESKey192, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamECB(SS, SS.Size - SS.Position, AESKey256, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CBC ַתʮ +function AESEncryptCbcStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCBC(SS, 0, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCBC(SS, 0, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCBC(SS, 0, AESKey256, Iv, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CBC ʮַ +function AESDecryptCbcStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCBC(SS, SS.Size - SS.Position, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCBC(SS, SS.Size - SS.Position, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCBC(SS, SS.Size - SS.Position, AESKey256, Iv, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CFB ģʽַתʮ +function AESEncryptCfbStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCFB(SS, 0, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCFB(SS, 0, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCFB(SS, 0, AESKey256, Iv, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CFB ʮַ +function AESDecryptCfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCFB(SS, SS.Size - SS.Position, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCFB(SS, SS.Size - SS.Position, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCFB(SS, SS.Size - SS.Position, AESKey256, Iv, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES OFB ģʽַתʮ +function AESEncryptOfbStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamOFB(SS, 0, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamOFB(SS, 0, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamOFB(SS, 0, AESKey256, Iv, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES OFB ʮַ +function AESDecryptOfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamOFB(SS, SS.Size - SS.Position, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamOFB(SS, SS.Size - SS.Position, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamOFB(SS, SS.Size - SS.Position, AESKey256, Iv, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CTR ģʽַתʮ +function AESEncryptCtrStrToHex(Value: AnsiString; Key: AnsiString; + const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCTR(SS, 0, AESKey128, Nonce, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCTR(SS, 0, AESKey192, Nonce, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCTR(SS, 0, AESKey256, Nonce, Iv, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CTR ʮַ +function AESDecryptCtrStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCTR(SS, SS.Size - SS.Position, AESKey128, Nonce, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCTR(SS, SS.Size - SS.Position, AESKey192, Nonce, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCTR(SS, SS.Size - SS.Position, AESKey256, Nonce, Iv, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES ECB ģʽֽ +function AESEncryptEcbBytes(Value, Key: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamECB(SS, 0, AESKey128, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamECB(SS, 0, AESKey192, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamECB(SS, 0, AESKey256, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES ECB ģʽֽ +function AESDecryptEcbBytes(Value, Key: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamECB(SS, SS.Size - SS.Position, AESKey128, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamECB(SS, SS.Size - SS.Position, AESKey192, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamECB(SS, SS.Size - SS.Position, AESKey256, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CBC ģʽֽ +function AESEncryptCbcBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCBC(SS, 0, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCBC(SS, 0, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCBC(SS, 0, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CBC ģʽֽ +function AESDecryptCbcBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCBC(SS, SS.Size - SS.Position, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCBC(SS, SS.Size - SS.Position, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCBC(SS, SS.Size - SS.Position, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CFB ģʽֽ +function AESEncryptCfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCFB(SS, 0, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCFB(SS, 0, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCFB(SS, 0, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CFB ģʽֽ +function AESDecryptCfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCFB(SS, SS.Size - SS.Position, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCFB(SS, SS.Size - SS.Position, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCFB(SS, SS.Size - SS.Position, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES OFB ģʽֽ +function AESEncryptOfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamOFB(SS, 0, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamOFB(SS, 0, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamOFB(SS, 0, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES OFB ģʽֽ +function AESDecryptOfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamOFB(SS, SS.Size - SS.Position, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamOFB(SS, SS.Size - SS.Position, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamOFB(SS, SS.Size - SS.Position, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CTR ģʽֽ +function AESEncryptCtrBytes(Value, Key, Nonce, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESCTRIv; + AESNonce: TCnAESCTRNonce; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + + FillChar(AESNonce, SizeOF(AESNonce), 0); + Move(PAnsiChar(Nonce)^, AESNonce, Min(SizeOf(AESNonce), Length(Nonce))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCTR(SS, 0, AESKey128, AESNonce, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCTR(SS, 0, AESKey192, AESNonce, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCTR(SS, 0, AESKey256, AESNonce, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CTR ģʽֽ +function AESDecryptCtrBytes(Value, Key, Nonce, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESCTRIv; + AESNonce: TCnAESCTRNonce; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + + FillChar(AESNonce, SizeOF(AESNonce), 0); + Move(PAnsiChar(Nonce)^, AESNonce, Min(SizeOf(AESNonce), Length(Nonce))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCTR(SS, SS.Size - SS.Position, AESKey128, AESNonce, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCTR(SS, SS.Size - SS.Position, AESKey192, AESNonce, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCTR(SS, SS.Size - SS.Position, AESKey256, AESNonce, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES ECB ģʽֽ鲢תʮ +function AESEncryptEcbBytesToHex(Value, Key: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptEcbBytes(Value, Key, KeyBit))); +end; + +// AES ECB ʮַֽ +function AESDecryptEcbBytesFromHex(const HexStr: AnsiString; Key: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptEcbBytes(HexToBytes(string(HexStr)), Key, KeyBit); +end; + +// AES CBC ģʽֽ鲢תʮ +function AESEncryptCbcBytesToHex(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptCbcBytes(Value, Key, Iv, KeyBit))); +end; + +// AES CBC ʮַֽ +function AESDecryptCbcBytesFromHex(const HexStr: AnsiString; Key, Iv: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptCbcBytes(HexToBytes(string(HexStr)), Key, Iv, KeyBit); +end; + +// AES CFB ģʽֽ鲢תʮ +function AESEncryptCfbBytesToHex(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptCfbBytes(Value, Key, Iv, KeyBit))); +end; + +// AES CFB ʮַֽ +function AESDecryptCfbBytesFromHex(const HexStr: AnsiString; Key, Iv: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptCfbBytes(HexToBytes(string(HexStr)), Key, Iv, KeyBit); +end; + +// AES OFB ģʽֽ鲢תʮ +function AESEncryptOfbBytesToHex(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptOfbBytes(Value, Key, Iv, KeyBit))); +end; + +// AES OFB ʮַֽ +function AESDecryptOfbBytesFromHex(const HexStr: AnsiString; Key, Iv: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptOfbBytes(HexToBytes(string(HexStr)), Key, Iv, KeyBit); +end; + +// AES CTR ģʽֽ鲢תʮ +function AESEncryptCtrBytesToHex(Value, Key, Nonce, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptCtrBytes(Value, Key, Nonce, Iv, KeyBit))); +end; + +// AES CTR ʮַֽ +function AESDecryptCtrBytesFromHex(const HexStr: AnsiString; Key, Nonce, Iv: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptCtrBytes(HexToBytes(string(HexStr)), Key, Nonce, Iv, KeyBit); +end; + +end. + diff --git a/CnPack/Crypto/CnBase64.dcu b/CnPack/Crypto/CnBase64.dcu new file mode 100644 index 0000000000000000000000000000000000000000..3b1d931f16324cb1df37a96014462e88b915a17e GIT binary patch literal 7426 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 U5XKli4!pF literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnBase64.pas b/CnPack/Crypto/CnBase64.pas new file mode 100644 index 0000000..cfe7dc1 --- /dev/null +++ b/CnPack/Crypto/CnBase64.pas @@ -0,0 +1,547 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +{ -----------------------------------------------------------------------------} +{ uTBase64 v1.0 - Simple Base64 encoding/decoding class } +{ Base64 described in RFC2045, Page 24, (w) 1996 Freed & Borenstein } +{ Delphi implementation (w) 1999 Dennis D. Spreen (dennis@spreendigital.de) } +{ This unit is freeware. Just drop me a line if this unit is useful for you. } +{ -----------------------------------------------------------------------------} + +unit CnBase64; +{* |
+================================================================================
+* ƣ
+* ԪƣBase64 㷨ʵֵԪ
+* ԪߣղSolin solin@21cn.com; http://www.ilovezhuzhu.net
+*           wr960204
+*           CnPack  (master@cnpack.org)
+*           ݻ Dennis D. Spreen  UTBASE64.pas дԭаȨϢ
+*     עԪʵ˱׼ Base64  Base64URL ı빦ܡ
+*           Base64URL ڱ׼ Base64ѷ + / 滻 - _  URL 
+*           Ѻãɾβ =
+*
+* ƽ̨PWin2003Std + Delphi 6.0
+* ݲԣδ
+*   õԪ豾ػ
+* ޸ļ¼2023.10.04 V1.6
+*               ɾʵ֡Base64Encode  Base64Decode ֧ Base64URL ı
+*           2019.12.12 V1.5
+*               ֧ TBytes
+*           2019.04.15 V1.4
+*               ֧ Win32/Win64/MacOS
+*           2018.06.22 V1.3
+*               ԭʼݿܰ #0 ԭʼβ #0 Ƴ
+*           2016.05.03 V1.2
+*               ַа #0 ʱܻᱻضϵ
+*           2006.10.25 V1.1
+*                wr960204 Ż汾
+*           2003.10.14 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, CnNative, CnConsts; + +const + ECN_BASE64_OK = ECN_OK; // תɹ + {* Base64 ϵд룺޴ֵΪ 0} + ECN_BASE64_ERROR_BASE = ECN_CUSTOM_ERROR_BASE + $500; + {* Base64 ϵдĻ׼ʼֵΪ ECN_CUSTOM_ERROR_BASE $500} + + ECN_BASE64_LENGTH = ECN_BASE64_ERROR_BASE + 1; + {* Base64 ֮ݳȷǷ} + +function Base64Encode(InputData: TStream; var OutputData: string; + URL: Boolean = False): Integer; overload; +{* Base64 Base64URL 룬ɹ ECN_BASE64_OK + + + InputData: TStream - + var OutputData: string - ַ + URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 + + ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Encode(const InputData: AnsiString; var OutputData: string; + URL: Boolean = False): Integer; overload; +{* ַ Base64 Base64URL 룬ɹ ECN_BASE64_OK + + + const InputData: AnsiString - ַ + var OutputData: string - ַ + URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 + + ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Encode(InputData: Pointer; DataByteLen: Integer; var OutputData: string; + URL: Boolean = False): Integer; overload; +{* ݿ Base64 Base64URL 룬ɹ ECN_BASE64_OK + + + InputData: Pointer - ݿַ + DataByteLen: Integer - ݿֽڳ + var OutputData: string - ַ + URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 + + ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Encode(InputData: TBytes; var OutputData: string; + URL: Boolean = False): Integer; overload; +{* ֽ Base64 Base64URL 룬ɹ ECN_BASE64_OK + + + InputData: TBytes - ֽ + var OutputData: string - ַ + URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 + + ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Decode(const InputData: string; OutputData: TStream; + FixZero: Boolean = True): Integer; overload; +{* ַ Base64 루 Base64URL 룩дɹ ECN_BASE64_OK + + + const InputData: string - ַ + OutputData: TStream - + FixZero: Boolean - Ƿȥβ #0 + + ֵInteger - ؽǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Decode(const InputData: string; var OutputData: AnsiString; + FixZero: Boolean = True): Integer; overload; +{* ַ Base64 루 Base64URL 룩дַɹ ECN_BASE64_OK + + + const InputData: string - ַ + var OutputData: AnsiString - ַ + FixZero: Boolean - Ƿȥβ #0 + + ֵInteger - ؽǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Decode(const InputData: string; OutputData: Pointer; + DataByteLen: Integer; FixZero: Boolean = True): Integer; overload; +{* ַ Base64 루 Base64URL 룩дڴɹ ECN_BASE64_OK + + + const InputData: string - ַ + OutputData: Pointer - ڴַ + DataByteLen: Integer - ڴֽڳȣӦΪ 1 + (Length(InputData) * 3 / 4) + FixZero: Boolean - Ƿȥβ #0 + + ֵInteger - OutputData nilĽֽڳȡؽǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Decode(const InputData: string; out OutputData: TBytes; + FixZero: Boolean = True): Integer; overload; +{* ַ Base64 루 Base64URL 룩дֽ顣ɹ ECN_BASE64_OK + + + const InputData: string - ַ + out OutputData: TBytes - ֽ + FixZero: Boolean - Ƿȥβ #0 + + ֵInteger - ؽǷɹɹ򷵻 ECN_BASE64_OK +} + +implementation + +var + FilterDecodeInput: Boolean = True; + +//------------------------------------------------------------------------------ +// IJο +//------------------------------------------------------------------------------ + + EnCodeTab: array[0..64] of AnsiChar = + ( + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/', + '='); + + EnCodeTabURL: array[0..64] of AnsiChar = + ( + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '-', '_', + '='); + +//------------------------------------------------------------------------------ +// IJο +//------------------------------------------------------------------------------ + + { Base64 ֱַӸ㣬Ҳȡ} + DecodeTable: array[#0..#127] of Byte = + ( + Byte('='), 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, + 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, + 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 62, 00, 62, 00, 63, // ĵһ 62 63 + / - 62 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 00, 00, 00, 00, 00, 00, + 00, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 00, 00, 00, 00, 63, // _ 63 + 00, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 00, 00, 00, 00, 00 + ); + +function Base64Encode(InputData: TStream; var OutputData: string; URL: Boolean): Integer; +var + Mem: TMemoryStream; +begin + Mem := TMemoryStream.Create; + try + Mem.CopyFrom(InputData, InputData.Size); + Result := Base64Encode(Mem.Memory, Mem.Size, OutputData, URL); + finally + Mem.Free; + end; +end; + +// Ϊ wr960204 ĽĿ Base64 㷨 +function Base64Encode(InputData: Pointer; DataByteLen: Integer; var OutputData: string; + URL: Boolean): Integer; +var + Times, I: Integer; + X1, X2, X3, X4: AnsiChar; + XT: Byte; +begin + if (InputData = nil) or (DataByteLen <= 0) then + begin + Result := ECN_BASE64_LENGTH; + Exit; + end; + + if DataByteLen mod 3 = 0 then + Times := DataByteLen div 3 + else + Times := DataByteLen div 3 + 1; + SetLength(OutputData, Times * 4); // һηڴ,һδַ,һδͷŷڴ + FillChar(OutputData[1], Length(OutputData) * SizeOf(Char), 0); + + if URL then + begin + for I := 0 to Times - 1 do + begin + if DataByteLen >= (3 + I * 3) then + begin + X1 := EnCodeTabURL[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); + X2 := EnCodeTabURL[XT]; + XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; + XT := XT or (Ord(PAnsiChar(InputData)[2 + I * 3]) shr 6); + X3 := EnCodeTabURL[XT]; + XT := (Ord(PAnsiChar(InputData)[2 + I * 3]) and 63); + X4 := EnCodeTabURL[XT]; + end + else if DataByteLen >= (2 + I * 3) then + begin + X1 := EnCodeTabURL[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); + X2 := EnCodeTabURL[XT]; + XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; + X3 := EnCodeTabURL[XT ]; + X4 := '='; + end + else + begin + X1 := EnCodeTabURL[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + X2 := EnCodeTabURL[XT]; + X3 := '='; + X4 := '='; + end; + OutputData[I shl 2 + 1] := Char(X1); + OutputData[I shl 2 + 2] := Char(X2); + OutputData[I shl 2 + 3] := Char(X3); + OutputData[I shl 2 + 4] := Char(X4); + end; + end + else + begin + for I := 0 to Times - 1 do + begin + if DataByteLen >= (3 + I * 3) then + begin + X1 := EnCodeTab[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); + X2 := EnCodeTab[XT]; + XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; + XT := XT or (Ord(PAnsiChar(InputData)[2 + I * 3]) shr 6); + X3 := EnCodeTab[XT]; + XT := (Ord(PAnsiChar(InputData)[2 + I * 3]) and 63); + X4 := EnCodeTab[XT]; + end + else if DataByteLen >= (2 + I * 3) then + begin + X1 := EnCodeTab[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); + X2 := EnCodeTab[XT]; + XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; + X3 := EnCodeTab[XT ]; + X4 := '='; + end + else + begin + X1 := EnCodeTab[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + X2 := EnCodeTab[XT]; + X3 := '='; + X4 := '='; + end; + OutputData[I shl 2 + 1] := Char(X1); + OutputData[I shl 2 + 2] := Char(X2); + OutputData[I shl 2 + 3] := Char(X3); + OutputData[I shl 2 + 4] := Char(X4); + end; + end; + + OutputData := Trim(OutputData); + if URL then + begin + // ɾ OutputData β = ַ + if (Length(OutputData) > 0) and (OutputData[Length(OutputData)] = '=') then + begin + Delete(OutputData, Length(OutputData), 1); + if (Length(OutputData) > 0) and (OutputData[Length(OutputData)] = '=') then + begin + Delete(OutputData, Length(OutputData), 1); + if (Length(OutputData) > 0) and (OutputData[Length(OutputData)] = '=') then + Delete(OutputData, Length(OutputData), 1); + end; + end; + end; + Result := ECN_BASE64_OK; +end; + +function Base64Encode(const InputData: AnsiString; var OutputData: string; URL: Boolean): Integer; +begin + if InputData <> '' then + Result := Base64Encode(@InputData[1], Length(InputData), OutputData, URL) + else + Result := ECN_BASE64_LENGTH; +end; + +function Base64Encode(InputData: TBytes; var OutputData: string; URL: Boolean): Integer; +begin + if Length(InputData) > 0 then + Result := Base64Encode(@InputData[0], Length(InputData), OutputData, URL) + else + Result := ECN_BASE64_LENGTH; +end; + +function Base64Decode(const InputData: string; OutputData: TStream; FixZero: Boolean): Integer; +var + Data: TBytes; +begin + Result := Base64Decode(InputData, Data, FixZero); + if (Result = ECN_BASE64_OK) and (Length(Data) > 0) then + begin + OutputData.Size := Length(Data); + OutputData.Position := 0; + OutputData.Write(Data[0], Length(Data)); + end; +end; + +function Base64Decode(const InputData: string; out OutputData: TBytes; + FixZero: Boolean): Integer; +var + SrcLen, DstLen, Times, I: Integer; + X1, X2, X3, X4, XT: Byte; + C, ToDec: Integer; + Data: AnsiString; + + function FilterLine(const Source: AnsiString): AnsiString; + var + P, PP: PAnsiChar; + I, FL: Integer; + begin + FL := Length(Source); + if FL > 0 then + begin + GetMem(P, FL); // һηڴ,һδַ,һδͷŷڴ + PP := P; + FillChar(P^, FL, 0); + for I := 1 to FL do + begin + if Source[I] in ['0'..'9', 'A'..'Z', 'a'..'z', '+', '/', '=', '-', '_'] then + begin + PP^ := Source[I]; + Inc(PP); + end; + end; + SetString(Result, P, PP - P); // ȡЧ + FreeMem(P); + end; + end; + +begin + if InputData = '' then + begin + Result := ECN_BASE64_OK; + Exit; + end; + OutPutData := nil; + + // D5 ²֪ôIJ AnsiString(InputData)ܻڴֿ + if FilterDecodeInput then + begin +{$IFDEF UNICODE} + Data := FilterLine(AnsiString(InputData)); +{$ELSE} + Data := FilterLine(InputData); +{$ENDIF} + end + else + begin +{$IFDEF UNICODE} + Data := AnsiString(InputData); +{$ELSE} + Data := InputData; +{$ENDIF} + end; + + // Base64URL Ľȥβ =ҪݳǷ 4 ı + if (Length(Data) and $03) <> 0 then + Data := Data + StringOfChar(AnsiChar('='), 4 - (Length(Data) and $03)); + + SrcLen := Length(Data); + DstLen := SrcLen * 3 div 4; + ToDec := 0; + + // βһȺζԭʼݲ˸ #0ȺζŲ #0ҪȥҲ̳ + // עⲻͬԭʼݵβ #0 ȥ + if Data[SrcLen] = '=' then + begin + Inc(ToDec); + if (SrcLen > 1) and (Data[SrcLen - 1] = '=') then + Inc(ToDec); + end; + + SetLength(OutputData, DstLen); // һηڴ,һδַ,һδͷŷڴ + Times := SrcLen div 4; + C := 0; + + for I := 0 to Times - 1 do + begin + X1 := DecodeTable[Data[1 + I shl 2]]; + X2 := DecodeTable[Data[2 + I shl 2]]; + X3 := DecodeTable[Data[3 + I shl 2]]; + X4 := DecodeTable[Data[4 + I shl 2]]; + X1 := X1 shl 2; + XT := X2 shr 4; + X1 := X1 or XT; + X2 := X2 shl 4; + OutputData[C] := X1; + Inc(C); + if X3 = 64 then + Break; + XT := X3 shr 2; + X2 := X2 or XT; + X3 := X3 shl 6; + OutputData[C] := X2; + Inc(C); + if X4 = 64 then + Break; + X3 := X3 or X4; + OutputData[C] := X3; + Inc(C); + end; + + // ݲĵȺĿǷɾβ #0 + while (ToDec > 0) and (OutputData[DstLen - 1] = 0) do + begin + Dec(ToDec); + Dec(DstLen); + end; + SetLength(OutputData, DstLen); + + // ٸⲿҪɾβ #0ʵ̫ʵ + if FixZero then + begin + while (DstLen > 0) and (OutputData[DstLen - 1] = 0) do + Dec(DstLen); + SetLength(OutputData, DstLen); + end; + + Result := ECN_BASE64_OK; +end; + +function Base64Decode(const InputData: string; var OutputData: AnsiString; FixZero: Boolean): Integer; +var + Data: TBytes; +begin + Result := Base64Decode(InputData, Data, FixZero); + if (Result = ECN_BASE64_OK) and (Length(Data) > 0) then + begin + SetLength(OutputData, Length(Data)); + Move(Data[0], OutputData[1], Length(Data)); + end; +end; + +function Base64Decode(const InputData: string; OutputData: Pointer; + DataByteLen: Integer; FixZero: Boolean): Integer; +var + Data: TBytes; +begin + Result := Base64Decode(InputData, Data, FixZero); + if (Result = ECN_BASE64_OK) and (Length(Data) > 0) then + begin + if OutputData = nil then + begin + Result := Length(Data); + Exit; + end; + + if DataByteLen < Length(Data) then + begin + Result := ECN_BASE64_LENGTH; + Exit; + end; + + Move(Data[0], OutPutData^, Length(Data)); + end; +end; + +end. diff --git a/CnPack/Crypto/CnConsts.dcu b/CnPack/Crypto/CnConsts.dcu new file mode 100644 index 0000000000000000000000000000000000000000..c867ed279f4c00fe26ff633e118584d938e5bedb GIT binary patch literal 14305 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 e3USNw2)Y>N%(KXha^|S(k2<+r=u|5s literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnConsts.pas b/CnPack/Crypto/CnConsts.pas new file mode 100644 index 0000000..f4f50aa --- /dev/null +++ b/CnPack/Crypto/CnConsts.pas @@ -0,0 +1,250 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnConsts; +{* |
+================================================================================
+* ƣ
+* ԪƣԴַ嵥Ԫ
+* ԪߣCnPack 
+*     ע
+* ƽ̨PWin98SE + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2005.12.24 V1.0
+*                ԪֲӢַ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +const + ECN_OK = 0; // OK޴ + + ECN_FILE_NOT_FOUND = $10; // ļ + + ECN_CUSTOM_ERROR_BASE = $1000; // 趨Ĵʼֵ + +//============================================================================== +// Strings DO NOT Localize: +//============================================================================== + +resourcestring + + // CnPack Reg Path + SCnPackRegPath = '\Software\CnPack'; + + // Tools Reg Path + SCnPackToolRegPath = 'CnTools'; + +//============================================================================== +// Strings to be Localized: +//============================================================================== + + +var + // Common Information + SCnInformation: string = 'Information'; + SCnWarning: string = 'Warning'; + SCnError: string = 'Error'; + SCnEnabled: string = 'Enabled'; + SCnDisabled: string = 'Disabled'; + SCnMsgDlgOK: string = '&OK'; + SCnMsgDlgCancel: string = '&Cancel'; + SCnMsgDlgYes: string = '&Yes'; + SCnMsgDlgNo: string = '&No'; + SCnMsgDlgYesToAll: string = 'Yes to &All'; + SCnMsgDlgNoToAll: string = 'No to A&ll'; + SCnVersion: string = 'Version'; + SCnNeedAdmin: string = 'Maybe Need Administrator.'; + +const + // CnPack Information + SCnPackAbout = 'CnPack'; + SCnPackVer = 'Ver 0.1.5.2'; + SCnPackStr = SCnPackAbout + ' ' + SCnPackVer; + SCnPackUrl = 'https://www.cnpack.org'; + SCnPackBbsUrl = 'https://bbs.cnpack.org'; + SCnPackNewsUrl = 'news://news.cnpack.org'; + SCnPackSourceUrl = 'https://github.com/cnpack'; + SCnPackEmail = 'master@cnpack.org'; + SCnPackBugEmail = 'bugs@cnpack.org'; + SCnPackSuggestionsEmail = 'suggestions@cnpack.org'; + + SCnPackDonationUrl = 'https://www.cnpack.org/foundation.php'; + SCnPackDonationUrlSF = 'http://sourceforge.net/donate/index.php?group_id=110999'; + SCnPackGroup = 'CnPack Team'; + SCnPackCopyright = '(C)Copyright 2001-2025 ' + SCnPackGroup; + + // CnPropEditors + SCopyrightFmtStr = + SCnPackStr + #13#10#13#10 + + 'Component Name: %s' + #13#10 + + 'Author: %s(%s)' + #13#10 + + 'Comment: %s' + #13#10 + + 'HomePage: ' + SCnPackUrl + #13#10 + + 'Email: ' + SCnPackEmail + #13#10#13#10 + + SCnPackCopyright; + +resourcestring + + // Component Palette Name + SCnNonVisualPalette = 'CnPack Tools'; + SCnGraphicPalette = 'CnPack VCL'; + SCnNetPalette = 'CnPack Net'; + SCnDatabasePalette = 'CnPack DB'; + SCnReportPalette = 'CnPack Report'; + + // CnPack Developers Added from Last. +var + SCnPack_Team: string = 'CnPack Team'; + SCnPack_Zjy: string = 'Zhou JingYu'; + SCnPack_Shenloqi: string = 'Chinbo'; + SCnPack_xiaolv: string = 'xiaolv'; + SCnPack_Flier: string = 'Flier Lu'; + SCnPack_LiuXiao: string = 'Liu Xiao'; + SCnPack_PanYing: string = 'Pan Ying'; + SCnPack_Hubdog: string = 'Hubdog'; + SCnPack_Wyb_star: string = 'wyb_star'; + SCnPack_Licwing: string = 'Licwing zue'; + SCnPack_Alan: string = 'Alan'; + SCnPack_GuYueChunQiu: string = 'GuYueChunQiu'; + SCnPack_Aimingoo: string = 'Aimingoo'; + SCnPack_QSoft: string = 'QSoft'; + SCnPack_Hospitality: string = 'ZhangJiongXuan (Hospitality)'; + SCnPack_SQuall: string = 'SQUALL'; + SCnPack_Hhha: string = 'Hhha'; + SCnPack_Beta: string = 'beta'; + SCnPack_Leeon: string = 'Leeon'; + SCnPack_SuperYoyoNc: string = 'SuperYoyoNC'; + SCnPack_JohnsonZhong: string = 'Johnson Zhong'; + SCnPack_DragonPC: string = 'Dragon P.C.'; + SCnPack_Kendling: string = 'Kending'; + SCnPack_ccrun: string = 'ccrun'; + SCnPack_Dingbaosheng: string = 'dingbaosheng'; + SCnPack_LuXiaoban: string = 'Zhou Yibo(Lu Xiaoban)'; + SCnPack_Savetime: string = 'savetime'; + SCnPack_solokey: string = 'solokey'; + SCnPack_Bahamut: string = 'Bahamut'; + SCnPack_Sesame: string = 'Sesame'; + SCnPack_BuDeXian: string = 'BuDeXian'; + SCnPack_XiaoXia: string = 'Summer'; + SCnPack_ZiMin: string = 'ZiMin'; + SCnPack_rarnu: string = 'rarnu'; + SCnPack_dejoy: string = 'dejoy'; + SCnPack_Rain: string = 'Rain'; + SCnPack_cnwinds: string = 'cnwinds'; + + // CnCommon + SUnknowError: string = 'Unknow error'; + SErrorCode: string = 'Error code:'; + +const + SCnPack_TeamEmail = 'master@cnpack.org'; + SCnPack_ZjyEmail = 'zjy@cnpack.org'; + SCnPack_ShenloqiEmail = 'Shenloqi@hotmail.com'; + SCnPack_xiaolvEmail = 'xiaolv888@etang.com'; + SCnPack_FlierEmail = 'flier_lu@sina.com'; + SCnPack_LiuXiaoEmail = 'liuxiao@cnpack.org'; + SCnPack_PanYingEmail = 'panying@sina.com'; + SCnPack_HubdogEmail = 'hubdog@263.net'; + SCnPack_Wyb_starMail = 'wyb_star@sina.com'; + SCnPack_LicwingEmail = 'licwing@chinasystemsn.com'; + SCnPack_AlanEmail = 'BeyondStudio@163.com'; + SCnPack_GuYueChunQiuEmail = 'guyuechunqiu@cnpack.org'; + SCnPack_AimingooEmail = 'aim@263.net'; + SCnPack_QSoftEmail = 'hq.com@263.net'; + SCnPack_HospitalityEmail = 'Hospitality_ZJX@msn.com'; + SCnPack_SQuallEmail = 'squall_sa@163.com'; + SCnPack_HhhaEmail = 'Hhha@eyou.com'; + SCnPack_BetaEmail = 'beta@01cn.net'; + SCnPack_LeeonEmail = 'real-like@163.com'; + SCnPack_SuperYoyoNcEmail = 'superyoyonc@sohu.com'; + SCnPack_JohnsonZhongEmail = 'zhongs@tom.com'; + SCnPack_DragonPCEmail = 'dragonpc@21cn.com'; + SCnPack_KendlingEmail = 'kendling@21cn.com'; + SCnPack_ccRunEmail = 'info@ccrun.com'; + SCnPack_DingbaoshengEmail = 'yzdbs@msn.com'; + SCnPack_LuXiaobanEmail = 'zhouyibo2000@sina.com'; + SCnPack_SavetimeEmail = 'savetime2k@hotmail.com'; + SCnPack_solokeyEmail = 'crh611@163.com'; + SCnPack_BahamutEmail = 'fantasyfinal@126.com'; + SCnPack_SesameEmail = 'sesamehch@163.com'; + SCnPack_BuDeXianEmail = 'appleak46@yahoo.com.cn'; + SCnPack_XiaoXiaEmail = 'summercore@163.com'; + SCnPack_ZiMinEmail = '441414288@qq.com'; + SCnPack_rarnuEmail = 'rarnu@cnpack.org'; + SCnPack_dejoyEmail = 'dejoybbs@163.com'; + SCnPack_RainEmail = SCnPack_TeamEmail; // Emailÿ + SCnPack_cnwindsEmail = SCnPack_TeamEmail; + + // CnMemProf + SCnPackMemMgr = 'CnMemProf'; + SMemLeakDlgReport = 'Found %d memory leaks. [There are %d allocated before replace memory manager.]'; + SMemMgrODSReport = 'Get = %d Free = %d Realloc = %d'; + SMemMgrOverflow = 'Memory Manager''s list capability overflow, Please enlarge it!'; + SMemMgrRunTime = '%d hour(s) %d minute(s) %d second(s)'; + SOldAllocMemCount = 'There are %d allocated before replace memory manager.'; + SAppRunTime = 'Application total run time: '; + SMemSpaceCanUse = 'HeapStatus.TotalAddrSpace: %d KB'; + SUncommittedSpace = 'HeapStatus.TotalUncommitted: %d KB'; + SCommittedSpace = 'HeapStatus.TotalCommitted: %d KB'; + SFreeSpace = 'HeapStatus.TotalFree: %d KB'; + SAllocatedSpace = 'HeapStatus.TotalAllocated: %d KB'; + SAllocatedSpacePercent = 'TotalAllocated div TotalAddrSpace: %d%%'; + SFreeSmallSpace = 'HeapStatus.FreeSmall: %d KB'; + SFreeBigSpace = 'HeapStatus.FreeBig: %d KB'; + SUnusedSpace = 'HeapStatus.Unused: %d KB'; + SOverheadSpace = 'HeapStatus.Overhead: %d KB'; + SObjectCountInMemory = 'Objects count in memory: '; + SNoMemLeak = ' No memory leak.'; + SNoName = '(no name)'; + SNotAnObject = ' Not an object'; + SByte = 'Byte'; + SCommaString = ','; + SPeriodString = '.'; + +resourcestring + SCnErrorMapViewOfFile = 'MapViewOfFile Failed. '; + SCnErrorCreateFileMapping = 'CreateFileMapping Failed. '; + +function CnGetLastError: Integer; + +procedure _CnSetLastError(Err: Integer); + +implementation + +threadvar + CnErrorCode: Integer; + +function CnGetLastError: Integer; +begin + Result := CnErrorCode; +end; + +procedure _CnSetLastError(Err: Integer); +begin + CnErrorCode := Err; +end; + +end. + diff --git a/CnPack/Crypto/CnDES.dcu b/CnPack/Crypto/CnDES.dcu new file mode 100644 index 0000000000000000000000000000000000000000..86e855f0e249b9d709daafffd26601b8f2c8b4ab GIT binary patch literal 30941 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 +================================================================================ +* ƣ +* ԪƣDES ԳƼӽ㷨ʵֵԪ +* ԪߣCnPack (master@cnpack.org) +* /ֲ䲿ֹܡ +* עԪʵ DES/3DES ԳƼӽ㷨ֿС 8 ֽڣʵ +* ECB/CBC ģʽ֧ģʽ +* +* ƽ̨PWin2000Pro + Delphi 5.0 +* ݲԣPWin9X/2000/XP + Delphi 5/6 +* õԪеַϱػʽ +* ޸ļ¼2024.11.30 V1.7 +* ɾ淶 DESEncryptStrToHex DESDecryptStrToHex +* ɾ淶 TripleDESEncryptStrToHex TripleDESDecryptStrToHex +* ECB 汾 +* Ż PAnsiChar ʽ Iv Ĵ +* 2024.10.12 V1.6 +* 3DES ²Խ⣬Ż Key Iv Ķ봦 +* 2022.08.13 V1.5 +* Կݼܷؿ +* 2021.02.07 V1.4 +* Ӷ TBytes ֧ +* 2020.03.25 V1.3 +* 3DES ֧ +* 2020.03.24 V1.2 +* ECB/CBC ַӽܺɾԭеַܺ +* 2019.04.15 V1.1 +* ֧ Win32/Win64/MacOS +* 2008.05.30 V1.0 +* Ԫ +================================================================================ +|} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, CnNative; + +const + CN_DES_KEYSIZE = 8; + {* DES Կȣ8 ֽ} + + CN_DES_BLOCKSIZE = 8; + {* DES ļܿ鳤ȣ8 ֽ} + + CN_TRIPLE_DES_KEYSIZE = CN_DES_KEYSIZE * 3; + {* 3DES Կȣ DES 24 ֽ} + + CN_TRIPLE_DES_BLOCKSIZE = CN_DES_BLOCKSIZE; + {* 3DES ļܿ鳤ȣ 8 ֽ} + +type + ECnDESException = class(Exception); + {* DES 쳣} + + TCnDESKey = array[0..CN_DES_KEYSIZE - 1] of Byte; + {* DES ļ Key8 ֽ} + + TCnDESBuffer = array[0..CN_DES_BLOCKSIZE - 1] of Byte; + {* DES ļܿ飬8 ֽ} + + TCnDESIv = array[0..CN_DES_BLOCKSIZE - 1] of Byte; + {* DES CBC ijʼ8 ֽ} + + TCn3DESKey = array[0..CN_TRIPLE_DES_KEYSIZE - 1] of Byte; + {* 3DES Կȣ DES 24 ֽ} + + TCn3DESBuffer = TCnDESBuffer; + {* 3DES ļܿ飬 DES ļܿ飬8 ֽ} + + TCn3DESIv = TCnDESIv; + {* 3DES CBC ijʼ DES CBC ijʼ8 ֽ} + +// ================================= DES ======================================= + +function DESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; +{* ֽڳȼ DES ȡǿ + + + InputByteLength: Integer - ֽڳ + + ֵInteger - DES ij +} + +procedure DESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +{* AnsiString DES ܣʹ ECB ģʽ + + + Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure DESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +{* AnsiString DES ܣʹ ECB ģʽ + + + Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure DESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; const Input: AnsiString; + Output: PAnsiChar); +{* AnsiString DES ܣʹ CBC ģʽ + + + Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure DESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; const Input: AnsiString; + Output: PAnsiChar); +{* AnsiString DES ܣʹ CBC ģʽ + + + Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +function DESEncryptEcbStrToHex(const Str: AnsiString; const Key: AnsiString): AnsiString; +{* KeyDES ܷתʮƵģʹ ECB ģʽĩβܲ #0 + + + const Str: AnsiString - ַܵ + const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + + ֵAnsiString - ؼܺʮַ +} + +function DESDecryptEcbStrFromHex(const HexStr: AnsiString; const Key: AnsiString): AnsiString; +{* ʮƵ KeyDES ܷģʹ ECB ģʽ + + + const HexStr: AnsiString - ܵʮַ + const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + + ֵAnsiString - ؽַܺ +} + +function DESEncryptCbcStrToHex(const Str: AnsiString; const Key: AnsiString; const Iv: AnsiString): AnsiString; +{* Key IvDES ܷתʮƵģʹ CBC ģʽĩβܲ #0 + + + const Str: AnsiString - ַܵ + const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + const Iv: AnsiString - 8 ֽڳʼ + + ֵAnsiString - ؼܺʮַ +} + +function DESDecryptCbcStrFromHex(const HexStr: AnsiString; const Key: AnsiString; + const Iv: AnsiString): AnsiString; +{* ʮƵ Key IvDES ܷģʹ ECB ģʽ + + + const HexStr: AnsiString - ܵʮַ + const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + const Iv: AnsiString - 8 ֽڳʼ + + ֵAnsiString - ؽַܺ +} + +function DESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +{* ֽ DES ܣʹ ECB ģʽ + + + Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 + Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı + + ֵTBytes - ؼֽܺ +} + +function DESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +{* ֽ DES ܣʹ ECB ģʽ + + + Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 + Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı + + ֵTBytes - ؽֽܺ +} + +function DESEncryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; +{* ֽ DES ܣʹ CBC ģʽ + + + Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 + Input: TBytes - ֽܵ + + ֵTBytes - ؼֽܺ +} + +function DESDecryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; +{* ֽ DES ܣʹ CBC ģʽ + + + Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 + Input: TBytes - ֽܵ + + ֵTBytes - ؽֽܺ +} + +procedure DESEncryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; Dest: TStream); overload; +{* DES ܣʹ ECB ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 8 ֽ DES Կ + Dest: TStream - + + ֵޣ +} + +procedure DESDecryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; Dest: TStream); overload; +{* DES ܣʹ ECB ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 8 ֽ DES Կ + Dest: TStream - + + ֵޣ +} + +procedure DESEncryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +{* DES ܣʹ CBC ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 8 ֽ DES Կ + const InitVector: TCnDESIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DESDecryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +{* DES ܣʹ CBC ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 8 ֽ DES Կ + const InitVector: TCnDESIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// =========================== 3-DES (Triple DES) ============================== + +function TripleDESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; +{* ֽڳȼȡǿ + + + InputByteLength: Integer - ֽڳ + + ֵInteger - 3DES ֽڳ +} + +procedure TripleDESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +{* AnsiString 3DES ܣʹ ECB ģʽ + + + Key: AnsiString - 24ֽ 3DES Կ̫ضϣ #0 + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure TripleDESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +{* AnsiString 3DES ܣʹ ECB ģʽ + + + Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure TripleDESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +{* AnsiString 3DES ܣʹ CBC ģʽ + + + Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure TripleDESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +{* AnsiString 3DES ܣʹ CBC ģʽ + + + Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +function TripleDESEncryptEcbStrToHex(const Str: AnsiString; const Key: AnsiString): AnsiString; +{* Key3DES ܷתʮƵģʹ ECB ģʽĩβܲ #0 + + + const Str: AnsiString - ַܵ + const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + + ֵAnsiString - ؼܺʮַ +} + +function TripleDESDecryptEcbStrFromHex(const HexStr: AnsiString; const Key: AnsiString): AnsiString; +{* ʮƵ Key3DES ܷģʹ ECB ģʽ + + + const HexStr: AnsiString - ܵʮַ + const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + + ֵAnsiString - ؽַܺ +} + +function TripleDESEncryptCbcStrToHex(const Str: AnsiString; const Key: AnsiString; + const Iv: AnsiString): AnsiString; +{* Key Iv3DES ܷתʮƵģʹ CBC ģʽĩβܲ #0 + + + const Str: AnsiString - ַܵ + const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + const Iv: AnsiString - 8 ֽڳʼ + + ֵAnsiString - ؼܺʮַ +} + +function TripleDESDecryptCbcStrFromHex(const HexStr: AnsiString; + const Key: AnsiString; const Iv: AnsiString): AnsiString; +{* ʮƵ Key Iv3DES ܷģʹ CBC ģʽ + + + const HexStr: AnsiString - ܵʮַ + const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + const Iv: AnsiString - 8 ֽڳʼ + + ֵAnsiString - ؽַܺ +} + +function TripleDESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +{* ֽ 3DES ܣʹ ECB ģʽ + + + Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 + Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı + + ֵTBytes - ؼֽܺ +} + +function TripleDESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +{* ֽ 3DES ܣʹ ECB ģʽ + + + Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 + Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı + + ֵTBytes - ؽֽܺ +} + +function TripleDESEncryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; +{* ֽ 3DES ܣʹ CBC ģʽ + + + Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 + Input: TBytes - ֽܵ + + ֵTBytes - ؼֽܺ +} + +function TripleDESDecryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; +{* ֽ 3DES ܣʹ CBC ģʽ + + + Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 + Input: TBytes - ֽܵ + + ֵTBytes - ؽֽܺ +} + +procedure TripleDESEncryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; Dest: TStream); overload; +{* 3DES ܣʹ ECB ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 24 ֽ 3DES Կ + Dest: TStream - + + ֵޣ +} + +procedure TripleDESDecryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; Dest: TStream); overload; +{* 3DES ܣʹ ECB ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 24 ֽ 3DES Կ + Dest: TStream - + + ֵޣ +} + +procedure TripleDESEncryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +{* 3DES ܣʹ CBC ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCn3DESKey - 24 ֽ 3DES Կ + const InitVector: TCnDESIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure TripleDESDecryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +{* 3DES ܣʹ CBC ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCn3DESKey - 24 ֽ 3DES Կ + const InitVector: TCnDESIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +implementation + +resourcestring + SCnErrorDESInvalidInBufSize = 'Invalid Buffer Size for Decryption'; + SCnErrorDESReadError = 'Stream Read Error'; + SCnErrorDESWriteError = 'Stream Write Error'; + +type + TKeyByte = array[0..5] of Byte; + TDesMode = (dmEncry, dmDecry); + TSubKey = array[0..15] of TKeyByte; + +const + BitIP: array[0..63] of Byte = + (57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7, + 56, 48, 40, 32, 24, 16, 8, 0, + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6); + + BitCP: array[0..63] of Byte = + (39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25, + 32, 0, 40, 8, 48, 16, 56, 24); + + BitExp: array[0..47] of Integer = + (31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, + 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, + 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0); + + BitPM: array[0..31] of Byte = + (15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, + 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24); + + sBox: array[0..7] of array[0..63] of Byte = + ((14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13), + + (15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9), + + (10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12), + + (7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14), + + (2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3), + + (12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13), + + (4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12), + + (13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11)); + + BitPMC1: array[0..55] of Byte = + (56, 48, 40, 32, 24, 16, 8, + 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, + 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, + 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, + 20, 12, 4, 27, 19, 11, 3); + + BitPMC2: array[0..47] of Byte = + (13, 16, 10, 23, 0, 4, + 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, + 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, + 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, + 45, 41, 49, 35, 28, 31); + +function Min(A, B: Integer): Integer; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + if A < B then + Result := A + else + Result := B; +end; + +procedure InitPermutation(var InData: array of Byte); +var + NewData: array[0..7] of Byte; + I: Integer; +begin + FillChar(NewData, 8, 0); + for I := 0 to 63 do + if (InData[BitIP[I] shr 3] and (1 shl (7 - (BitIP[I] and $07)))) <> 0 then + NewData[I shr 3] := NewData[I shr 3] or (1 shl (7 - (I and $07))); + for I := 0 to 7 do InData[I] := NewData[I]; +end; + +procedure ConversePermutation(var InData: array of Byte); +var + NewData: array[0..7] of Byte; + I: Integer; +begin + FillChar(NewData, 8, 0); + for I := 0 to 63 do + if (InData[BitCP[I] shr 3] and (1 shl (7 - (BitCP[I] and $07)))) <> 0 then + NewData[I shr 3] := NewData[I shr 3] or (1 shl (7 - (I and $07))); + for I := 0 to 7 do InData[I] := NewData[I]; +end; + +procedure Expand(const InData: array of Byte; var OutData: array of Byte); +var + I: Integer; +begin + FillChar(OutData, 6, 0); + for I := 0 to 47 do + if (InData[BitExp[I] shr 3] and (1 shl (7 - (BitExp[I] and $07)))) <> 0 then + OutData[I shr 3] := OutData[I shr 3] or (1 shl (7 - (I and $07))); +end; + +procedure Permutation(var InData: array of Byte); +var + NewData: array[0..3] of Byte; + I: Integer; +begin + FillChar(NewData, 4, 0); + for I := 0 to 31 do + if (InData[BitPM[I] shr 3] and (1 shl (7 - (BitPM[I] and $07)))) <> 0 then + NewData[I shr 3] := NewData[I shr 3] or (1 shl (7 - (I and $07))); + for I := 0 to 3 do InData[I] := NewData[I]; +end; + +function Si(S, InByte: Byte): Byte; +var + c: Byte; +begin + c := (InByte and $20) or ((InByte and $1E) shr 1) or + ((InByte and $01) shl 4); + Result := (sBox[S][c] and $0F); +end; + +procedure PermutationChoose1(const InData: array of Byte; var OutData: array of Byte); +var + I: Integer; +begin + FillChar(OutData, 7, 0); + for I := 0 to 55 do + if (InData[BitPMC1[I] shr 3] and (1 shl (7 - (BitPMC1[I] and $07)))) <> 0 then + OutData[I shr 3] := OutData[I shr 3] or (1 shl (7 - (I and $07))); +end; + +procedure PermutationChoose2(const InData: array of Byte; var OutData: array of Byte); +var + I: Integer; +begin + FillChar(OutData, 6, 0); + for I := 0 to 47 do + if (InData[BitPMC2[I] shr 3] and (1 shl (7 - (BitPMC2[I] and $07)))) <> 0 then + OutData[I shr 3] := OutData[I shr 3] or (1 shl (7 - (I and $07))); +end; + +procedure CycleMove(var InData: array of Byte; bitMove: Byte); +var + I: Integer; +begin + for I := 0 to bitMove - 1 do + begin + InData[0] := (InData[0] shl 1) or (InData[1] shr 7); + InData[1] := (InData[1] shl 1) or (InData[2] shr 7); + InData[2] := (InData[2] shl 1) or (InData[3] shr 7); + InData[3] := (InData[3] shl 1) or ((InData[0] and $10) shr 4); + InData[0] := (InData[0] and $0F); + end; +end; + +procedure MakeKey(const InKey: array of Byte; var OutKey: array of TKeyByte); +const + bitDisplace: array[0..15] of Byte = + (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1); +var + OutData56: array[0..6] of Byte; + Key28l: array[0..3] of Byte; + Key28r: array[0..3] of Byte; + Key56o: array[0..6] of Byte; + I: Integer; +begin + PermutationChoose1(InKey, OutData56); + Key28l[0] := OutData56[0] shr 4; + Key28l[1] := (OutData56[0] shl 4) or (OutData56[1] shr 4); + Key28l[2] := (OutData56[1] shl 4) or (OutData56[2] shr 4); + Key28l[3] := (OutData56[2] shl 4) or (OutData56[3] shr 4); + Key28r[0] := OutData56[3] and $0F; + Key28r[1] := OutData56[4]; + Key28r[2] := OutData56[5]; + Key28r[3] := OutData56[6]; + for I := 0 to 15 do + begin + CycleMove(Key28l, bitDisplace[I]); + CycleMove(Key28r, bitDisplace[I]); + Key56o[0] := (Key28l[0] shl 4) or (Key28l[1] shr 4); + Key56o[1] := (Key28l[1] shl 4) or (Key28l[2] shr 4); + Key56o[2] := (Key28l[2] shl 4) or (Key28l[3] shr 4); + Key56o[3] := (Key28l[3] shl 4) or (Key28r[0]); + Key56o[4] := Key28r[1]; + Key56o[5] := Key28r[2]; + Key56o[6] := Key28r[3]; + PermutationChoose2(Key56o, OutKey[I]); + end; +end; + +procedure Encry(const InData, ASubKey: array of Byte; var OutData: array of Byte); +var + OutBuf: array[0..5] of Byte; + Buf: array[0..7] of Byte; + I: Integer; +begin + Expand(InData, OutBuf); + for I := 0 to 5 do OutBuf[I] := OutBuf[I] xor ASubKey[I]; + Buf[0] := OutBuf[0] shr 2; + Buf[1] := ((OutBuf[0] and $03) shl 4) or (OutBuf[1] shr 4); + Buf[2] := ((OutBuf[1] and $0F) shl 2) or (OutBuf[2] shr 6); + Buf[3] := OutBuf[2] and $3F; + Buf[4] := OutBuf[3] shr 2; + Buf[5] := ((OutBuf[3] and $03) shl 4) or (OutBuf[4] shr 4); + Buf[6] := ((OutBuf[4] and $0F) shl 2) or (OutBuf[5] shr 6); + Buf[7] := OutBuf[5] and $3F; + for I := 0 to 7 do Buf[I] := si(I, Buf[I]); + for I := 0 to 3 do OutBuf[I] := (Buf[I * 2] shl 4) or Buf[I * 2 + 1]; + Permutation(OutBuf); + for I := 0 to 3 do OutData[I] := OutBuf[I]; +end; + +// InData OutData Ҫ 8 ֽ +procedure DesData(DesMode: TDesMode; SubKey: TSubKey; const InData: array of Byte; + var OutData: array of Byte); +var + I, J: Integer; + Temp, Buf: array[0..3] of Byte; +begin + for I := 0 to 7 do OutData[I] := InData[I]; + InitPermutation(OutData); + if DesMode = dmEncry then + begin + for I := 0 to 15 do + begin + for J := 0 to 3 do Temp[J] := OutData[J]; + for J := 0 to 3 do OutData[J] := OutData[J + 4]; + Encry(OutData, SubKey[I], Buf); + for J := 0 to 3 do OutData[J + 4] := Temp[J] xor Buf[J]; + end; + for J := 0 to 3 do Temp[J] := OutData[J + 4]; + for J := 0 to 3 do OutData[J + 4] := OutData[J]; + for J := 0 to 3 do OutData[J] := Temp[J]; + end + else if DesMode = dmDecry then + begin + for I := 15 downto 0 do + begin + for J := 0 to 3 do Temp[J] := OutData[J]; + for J := 0 to 3 do OutData[J] := OutData[J + 4]; + Encry(OutData, SubKey[I], Buf); + for J := 0 to 3 do OutData[J + 4] := Temp[J] xor Buf[J]; + end; + for J := 0 to 3 do Temp[J] := OutData[J + 4]; + for J := 0 to 3 do OutData[J + 4] := OutData[J]; + for J := 0 to 3 do OutData[J] := Temp[J]; + end; + ConversePermutation(OutData); +end; + +// Key #0 ճ 8 ֽ +procedure MakeKeyAlign(var Key: AnsiString); +begin + if Length(Key) < CN_DES_KEYSIZE then + while Length(Key) < CN_DES_KEYSIZE do + Key := Key + Chr(0); +end; + +// ַ #0 ճ 8 ıעմ +procedure MakeInputAlign(var Str: AnsiString); +begin + while Length(Str) mod CN_DES_KEYSIZE <> 0 do + Str := Str + Chr(0); +end; + +// ֽ鲹 0 ճ 8 ıע鲻 +procedure MakeInputBytesAlign(var Input: TBytes); +var + I, Len, NL: Integer; +begin + Len := Length(Input); + if Len mod CN_DES_BLOCKSIZE <> 0 then + begin + NL := ((Len div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE; + SetLength(Input, NL); + for I := Len to NL - 1 do + Input[I] := 0; + end; +end; + +function DESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; +begin + Result := (((InputByteLength - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE; +end; + +procedure DESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Str: AnsiString; + I: Integer; + SubKey: TSubKey; +begin + MakeKeyAlign(Key); + + Str := Input; + MakeInputAlign(Str); // Str 8 ı + + if Str = '' then // մֱӷؿ + begin + if Output <> nil then + Output[0] := #0; + Exit; + end; + + Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + DesData(dmEncry, SubKey, StrByte, OutByte); + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +procedure DESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + I: Integer; + SubKey: TSubKey; +begin + MakeKeyAlign(Key); + Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + DesData(dmDecry, SubKey, StrByte, OutByte); + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; + + // ĩβ 0 ⲿжɾ +end; + +procedure DESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Vector: TCnDESIv; + Str: AnsiString; + I: Integer; + SubKey: TSubKey; +begin + MakeKeyAlign(Key); + + Str := Input; + MakeInputAlign(Str); + + if Str = '' then // մֱӷؿ + begin + if Output <> nil then + Output[0] := #0; + Exit; + end; + + Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + Move(Iv^, Vector[0], SizeOf(TCnDESIv)); + + for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + + // CBC ݿֵȸ Iv + PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; + + // ټ + DesData(dmEncry, SubKey, StrByte, OutByte); + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ܽµ Iv + Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +procedure DESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Vector, TV: TCnDESIv; + I: Integer; + SubKey: TSubKey; +begin + MakeKeyAlign(Key); + Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); + + MakeKey(KeyByte, SubKey); + Move(Iv^, Vector[0], SizeOf(TCnDESIv)); + + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ + + // Ƚ + DesData(dmDecry, SubKey, StrByte, OutByte); + + // CBC ݿֵܺٸ Iv + PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ĸµ Iv + Move(TV[0], Vector[0], SizeOf(TCnDESIv)); + end; + + // ĩβ 0 ⲿжɾ +end; + +procedure SetResultLengthUsingInput(const Str: AnsiString; var Res: AnsiString); +var + Len: Integer; +begin + Len := Length(Str); + if Len < CN_DES_BLOCKSIZE then + Len := CN_DES_BLOCKSIZE + else + Len := (((Len - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE; + SetLength(Res, Len); +end; + +function DESEncryptEcbStrToHex(const Str, Key: AnsiString): AnsiString; +var + TempResult: AnsiString; +begin + Result := ''; + if Str = '' then + Exit; + + SetResultLengthUsingInput(Str, TempResult); + DESEncryptEcbStr(Key, Str, @TempResult[1]); + Result := AnsiStrToHex(TempResult); +end; + +function DESDecryptEcbStrFromHex(const HexStr, Key: AnsiString): AnsiString; +var + Str: AnsiString; +begin + Str := HexToAnsiStr(HexStr); + SetResultLengthUsingInput(Str, Result); + DESDecryptEcbStr(Key, Str, @(Result[1])); +end; + +function DESEncryptCbcStrToHex(const Str, Key, Iv: AnsiString): AnsiString; +var + TempResult: AnsiString; +begin + Result := ''; + if Str = '' then + Exit; + + SetResultLengthUsingInput(Str, TempResult); + DESEncryptCbcStr(Key, PAnsiChar(Iv), Str, @TempResult[1]); + Result := AnsiStrToHex(TempResult); +end; + +function DESDecryptCbcStrFromHex(const HexStr, Key, Iv: AnsiString): AnsiString; +var + Str: AnsiString; +begin + Str := HexToAnsiStr(HexStr); + SetResultLengthUsingInput(Str, Result); + DESDecryptCbcStr(Key, PAnsiChar(Iv), Str, @(Result[1])); +end; + +function DESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + I: Integer; + SubKey: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + MakeInputBytesAlign(Input); + + FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); + MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + DesData(dmEncry, SubKey, StrByte, OutByte); + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +function DESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + I: Integer; + SubKey: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); + MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + DesData(dmDecry, SubKey, StrByte, OutByte); + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +function DESEncryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Vector: TCnDESIv; + I: Integer; + SubKey: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + MakeInputBytesAlign(Input); + + FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); + MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + FillChar(Vector[0], SizeOf(TCnDESIv), 0); + MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + + // CBC ݿֵȸ Iv + PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; + + // ټ + DesData(dmEncry, SubKey, StrByte, OutByte); + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ܽµ Iv + Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +function DESDecryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Vector, TV: TCnDESIv; + I: Integer; + SubKey: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); + MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + FillChar(Vector[0], SizeOf(TCnDESIv), 0); + MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ + + // Ƚ + DesData(dmDecry, SubKey, StrByte, OutByte); + + // CBC ݿֵܺٸ Iv + PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ĸµ Iv + Move(TV[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +procedure DESEncryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; Dest: TStream); overload; +var + TempIn, TempOut: TCnDESBuffer; + Done: Cardinal; + SubKey: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + + MakeKey(Key, SubKey); + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + DesData(dmEncry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Dec(Count, SizeOf(TCnDESBuffer)); + end; + + if Count > 0 then // β 0 + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorDESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + + DesData(dmEncry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + end; +end; + +procedure DESDecryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; Dest: TStream); overload; +var + TempIn, TempOut: TCnDESBuffer; + Done: Cardinal; + SubKey: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + if (Count mod SizeOf(TCnDESBuffer)) > 0 then + raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); + + MakeKey(Key, SubKey); + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + DesData(dmDecry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Dec(Count, SizeOf(TCnDESBuffer)); + end; +end; + +procedure DESEncryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +var + TempIn, TempOut: TCnDESBuffer; + Vector: TCnDESIv; + Done: Cardinal; + SubKey: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + + Vector := InitVector; + MakeKey(Key, SubKey); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + + DesData(dmEncry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Move(TempOut[0], Vector[0], SizeOf(TCnDESIv)); + Dec(Count, SizeOf(TCnDESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorDESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + + DesData(dmEncry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + end; +end; + +procedure DESDecryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +var + TempIn, TempOut: TCnDESBuffer; + Vector1, Vector2: TCnDESIv; + Done: Cardinal; + SubKey: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + if (Count mod SizeOf(TCnDESBuffer)) > 0 then + raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); + + Vector1 := InitVector; + MakeKey(Key, SubKey); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorDESReadError); + + Move(TempIn[0], Vector2[0], SizeOf(TCnDESIv)); + DesData(dmDecry, SubKey, TempIn, TempOut); + + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorDESWriteError); + + Vector1 := Vector2; + Dec(Count, SizeOf(TCnDESBuffer)); + end; +end; + +procedure Make3DESKeys(Keys: AnsiString; var K1, K2, K3: TCnDESKey); overload; +var + I: Integer; +begin + if Length(Keys) < CN_TRIPLE_DES_KEYSIZE then + while Length(Keys) < CN_TRIPLE_DES_KEYSIZE do + Keys := Keys + Chr(0); + + for I := 0 to CN_DES_KEYSIZE - 1 do + begin + K1[I] := Ord(Keys[I + 1]); + K2[I] := Ord(Keys[I + 1 + CN_DES_KEYSIZE]); + K3[I] := Ord(Keys[I + 1 + CN_DES_KEYSIZE * 2]); + end; +end; + +procedure Make3DESKeys(Keys: TCn3DESKey; var K1, K2, K3: TCnDESKey); overload; +var + I: Integer; +begin + for I := 0 to CN_DES_KEYSIZE - 1 do + begin + K1[I] := Keys[I]; + K2[I] := Keys[I + CN_DES_KEYSIZE]; + K3[I] := Keys[I + CN_DES_KEYSIZE * 2]; + end; +end; + +procedure Make3DESKeys(Keys: TBytes; var K1, K2, K3: TCnDESKey); overload; +var + I, Len: Integer; +begin + Len := Length(Keys); + if Len < CN_TRIPLE_DES_KEYSIZE then + begin + SetLength(Keys, CN_TRIPLE_DES_KEYSIZE); + for I := Len to CN_TRIPLE_DES_KEYSIZE - 1 do + Keys[I] := 0; + end; + + for I := 0 to CN_DES_KEYSIZE - 1 do + begin + K1[I] := Ord(Keys[I]); + K2[I] := Ord(Keys[I + CN_DES_KEYSIZE]); + K3[I] := Ord(Keys[I + CN_DES_KEYSIZE * 2]); + end; +end; + +function TripleDESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; +begin + Result := (((InputByteLength - 1) div CN_TRIPLE_DES_BLOCKSIZE) + 1) * CN_TRIPLE_DES_BLOCKSIZE; +end; + +procedure TripleDESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Str: AnsiString; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + Str := Input; + MakeInputAlign(Str); + + if Str = '' then // մֱӷؿ + begin + if Output <> nil then + Output[0] := #0; + Exit; + end; + + for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + + DesData(dmEncry, SubKey1, StrByte, OutByte); + DesData(dmDecry, SubKey2, OutByte, StrByte); + DesData(dmEncry, SubKey3, StrByte, OutByte); + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +procedure TripleDESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + + DesData(dmDecry, SubKey3, StrByte, OutByte); + DesData(dmEncry, SubKey2, OutByte, StrByte); + DesData(dmDecry, SubKey1, StrByte, OutByte); + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; + + // ĩβ 0 ⲿжɾ +end; + +procedure TripleDESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Vector: TCnDESIv; + Str: AnsiString; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + Str := Input; + MakeInputAlign(Str); + + if Str = '' then // մֱӷؿ + begin + if Output <> nil then + Output[0] := #0; + Exit; + end; + + Move(Iv^, Vector[0], SizeOf(TCnDESIv)); + + for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + + // CBC ݿֵȸ Iv + PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; + + // ټ + DesData(dmEncry, SubKey1, StrByte, OutByte); + DesData(dmDecry, SubKey2, OutByte, StrByte); + DesData(dmEncry, SubKey3, StrByte, OutByte); + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ܽµ Iv + Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +procedure TripleDESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Vector, TV: TCnDESIv; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + Move(Iv^, Vector[0], SizeOf(TCnDESIv)); + + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ + + // Ƚ + DesData(dmDecry, SubKey3, StrByte, OutByte); + DesData(dmEncry, SubKey2, OutByte, StrByte); + DesData(dmDecry, SubKey1, StrByte, OutByte); + + // CBC ݿֵܺٸ Iv + PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ĸµ Iv + Move(TV[0], Vector[0], SizeOf(TCnDESIv)); + end; + + // ĩβ 0 ⲿжɾ +end; + +function TripleDESEncryptEcbStrToHex(const Str, Key: AnsiString): AnsiString; +var + TempResult, Temp: AnsiString; + I: Integer; +begin + SetResultLengthUsingInput(Str, TempResult); + TripleDESEncryptEcbStr(Key, Str, @TempResult[1]); + + Result := ''; + for I := 0 to Length(TempResult) - 1 do + begin + Temp := AnsiString(Format('%x', [Ord(TempResult[I + 1])])); + if Length(Temp) = 1 then + Temp := '0' + Temp; + Result := Result + Temp; + end; +end; + +function TripleDESDecryptEcbStrFromHex(const HexStr, Key: AnsiString): AnsiString; +var + Str: AnsiString; +begin + Str := HexToAnsiStr(HexStr); + SetResultLengthUsingInput(Str, Result); + TripleDESDecryptEcbStr(Key, Str, @(Result[1])); +end; + +function TripleDESEncryptCbcStrToHex(const Str, Key, Iv: AnsiString): AnsiString; +var + TempResult, Temp: AnsiString; + I: Integer; +begin + SetResultLengthUsingInput(Str, TempResult); + TripleDESEncryptCbcStr(Key, PAnsiChar(Iv), Str, @TempResult[1]); + + Result := ''; + for I := 0 to Length(TempResult) - 1 do + begin + Temp := AnsiString(Format('%x', [Ord(TempResult[I + 1])])); + if Length(Temp) = 1 then + Temp := '0' + Temp; + Result := Result + Temp; + end; +end; + +function TripleDESDecryptCbcStrFromHex(const HexStr, Key, Iv: AnsiString): AnsiString; +var + Str: AnsiString; +begin + Str := HexToAnsiStr(HexStr); + SetResultLengthUsingInput(Str, Result); + TripleDESDecryptCbcStr(Key, PAnsiChar(Iv), Str, @(Result[1])); +end; + +function TripleDESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + MakeInputBytesAlign(Input); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + + DesData(dmEncry, SubKey1, StrByte, OutByte); + DesData(dmDecry, SubKey2, OutByte, StrByte); + DesData(dmEncry, SubKey3, StrByte, OutByte); + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +function TripleDESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + + DesData(dmDecry, SubKey3, StrByte, OutByte); + DesData(dmEncry, SubKey2, OutByte, StrByte); + DesData(dmDecry, SubKey1, StrByte, OutByte); + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +function TripleDESEncryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Vector: TCnDESIv; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + MakeInputBytesAlign(Input); + FillChar(Vector[0], SizeOf(TCnDESIv), 0); + MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + + // CBC ݿֵȸ Iv + PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; + + // ټ + DesData(dmEncry, SubKey1, StrByte, OutByte); + DesData(dmDecry, SubKey2, OutByte, StrByte); + DesData(dmEncry, SubKey3, StrByte, OutByte); + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ܽµ Iv + Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +function TripleDESDecryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Vector, TV: TCnDESIv; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + FillChar(Vector[0], SizeOf(TCnDESIv), 0); + MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ + + // Ƚ + DesData(dmDecry, SubKey3, StrByte, OutByte); + DesData(dmEncry, SubKey2, OutByte, StrByte); + DesData(dmDecry, SubKey1, StrByte, OutByte); + + // CBC ݿֵܺٸ Iv + PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ĸµ Iv + Move(TV[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +procedure TripleDESEncryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; Dest: TStream); overload; +var + K1, K2, K3: TCnDESKey; + TempIn, TempOut: TCnDESBuffer; + Done: Cardinal; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + DesData(dmEncry, SubKey1, TempIn, TempOut); + DesData(dmDecry, SubKey2, TempOut, TempIn); + DesData(dmEncry, SubKey3, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Dec(Count, SizeOf(TCnDESBuffer)); + end; + + if Count > 0 then // β 0 + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorDESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + + DesData(dmEncry, SubKey1, TempIn, TempOut); + DesData(dmDecry, SubKey2, TempOut, TempIn); + DesData(dmEncry, SubKey3, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + end; +end; + +procedure TripleDESDecryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; Dest: TStream); overload; +var + K1, K2, K3: TCnDESKey; + TempIn, TempOut: TCnDESBuffer; + Done: Cardinal; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + if (Count mod SizeOf(TCnDESBuffer)) > 0 then + raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + DesData(dmDecry, SubKey3, TempIn, TempOut); + DesData(dmEncry, SubKey2, TempOut, TempIn); + DesData(dmDecry, SubKey1, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Dec(Count, SizeOf(TCnDESBuffer)); + end; +end; + +procedure TripleDESEncryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +var + K1, K2, K3: TCnDESKey; + TempIn, TempOut: TCnDESBuffer; + Vector: TCnDESIv; + Done: Cardinal; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + + Vector := InitVector; + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + + DesData(dmEncry, SubKey1, TempIn, TempOut); + DesData(dmDecry, SubKey2, TempOut, TempIn); + DesData(dmEncry, SubKey3, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Move(TempOut[0], Vector[0], SizeOf(TCnDESIv)); + Dec(Count, SizeOf(TCnDESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorDESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + + DesData(dmEncry, SubKey1, TempIn, TempOut); + DesData(dmDecry, SubKey2, TempOut, TempIn); + DesData(dmEncry, SubKey3, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + end; +end; + +procedure TripleDESDecryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +var + K1, K2, K3: TCnDESKey; + TempIn, TempOut: TCnDESBuffer; + Vector1, Vector2: TCnDESIv; + Done: Cardinal; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + if (Count mod SizeOf(TCnDESBuffer)) > 0 then + raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); + + Vector1 := InitVector; + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorDESReadError); + + Move(TempIn[0], Vector2[0], SizeOf(TCnDESIv)); + + DesData(dmDecry, SubKey3, TempIn, TempOut); + DesData(dmEncry, SubKey2, TempOut, TempIn); + DesData(dmDecry, SubKey1, TempIn, TempOut); + + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorDESWriteError); + + Vector1 := Vector2; + Dec(Count, SizeOf(TCnDESBuffer)); + end; +end; + +end. diff --git a/CnPack/Crypto/CnFloat.dcu b/CnPack/Crypto/CnFloat.dcu new file mode 100644 index 0000000000000000000000000000000000000000..609c33e673b3341b651478b135b8b56c24b5cb19 GIT binary patch literal 15913 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 +================================================================================ +* ƣ +* Ԫƣת +* ԪߣǬԪ(wqyfavor@163.com) +* עõԪʵ Extended תΪˡʮַĺ +* 㷨Ƕȡ Extended ڴеĶݽת Extended ͵˵ +* ԲοϡDouble Single Ϊϵͳֵ֧ͨĸͣ Delphi е +* Extended ڴ洢ʽвͬ߾β񻯣 Double Single β +* Ĭϵ 1βΪ 1.001 Double Single д洢Ϊ 001ȥ +* Сǰ 1 Extended 洢Ϊ 1001 +* NaN Ϊ "not a number"Ǹο Math.pas Ԫеij NaN +* Infinity Ϊ󣬶ο Math.pas Ԫеij Infinity NegInfinity. +* һ DecimalExp AlwaysUseExponent +* ʮƸתʱָʽѧ㷨Щ +* Ҳָֻʽ 1E-1000ָʱ 0.0000000...0001תָ +* ҲӦӦƱʾʱʮƱʾָ֣ƴ +* 1.001E101ֵΪ 100100ָʮƱһЩ 1.001D5ʾС +* 5 λDecimalExp ָǷʮƱֵָġע⣬ʮ +* ʾָ޹涨﷨ʹ "D" ʾ"E" ΪӦƱʾ⣬ +* ʮƱȽ⣬"D" "E" ΪʮַʮƱʱʹ "^" +* ַ 3.BD^D(12)A.BD^E(ABCE)粻ϲָʽ޸ġ +* AlwaysUseExponent ָǷһÿѧ 100.111 λȽ٣ +* ԶжϲҪʹÿѧ AlwaysUseExponent ΪʱһΪָ +* ʽ 1.00111E2 +* const +* MaxBinDigits = 120; +* MaxHexDigits = 30; +* MaxOctDigits = 40; +* ָλʱһʹÿѧ +* +* ⣬Extended ֻ Win32 10 ֽڣMacOS/Linux x64 ¾ 16 ֽڣWin64 ARM ƽ̨ 8 ֽ +* ңMacOS64 µ 16 ֽչȲ IEEE 754-2008 й涨 Quadruple ʽǰ 10 ֽڽضϣ +* ڲṹͬ Win32 µչ 10 ֽ +* +* ƽ̨WinXP + Delphi 2009 +* ݲԣDelphi 2007 Extended ֻ֧Сģʽ +* õԪеַϱػʽ +* ޸ļ¼2023.01.13 +* ݴ Win64 Extended 8 ֽ Double 10 ֽչȵ +* ݴ MacOS64/Linux64 µ 16 ֽ Extendedֻضϴǰ 10 ֽڣ +* 2022.02.17 +* FPC ı֧֣ +* 2021.09.05 +* תΪ UInt64֧ UInt64 Int64 棩ĺ +* 2020.11.11 +* UInt64֧ UInt64 Int64 棩תΪĺ +* 2020.06.24 +* ⿪ƴյĺ +* 2009.1.12 +* Ԫ +================================================================================ +|} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, SysConst, {$IFDEF MSWINDOWS} Windows, {$ENDIF} CnNative; + +{ + IEEE 754 涨ָʽЧڵλ 0 + + Single 1 λ S8 λָ E23 λЧ M 4 ֽ 32 λ + ˫ Double 1 λ S11 λָ E52 λЧ M 8 ֽ 64 λ + չ˫ Extended 1 λ S15 λָ E64 λЧ M 10 ֽ 80 λ + + IEEE 754-2008 + ı Quadruple 1 λ S15 λָ E112 λЧ M 16 ֽ 128 λ + ˱ Octuple 1 λ S19 λָ E236 λЧ M 32 ֽ 256 λ + + Уλ S0 ʾ1 ʾE Ҫȥ 127/1023/16383/16383 ָ + M: 淶/˫ȵĶ M ĸλӸ 1. Чչӣ 1. + ֵЧ 1.xxxx ʽ 2 E ηעⲻ 10 E η + + ʽ ֽ 1 ֽ 2 ֽ 3 ֽ 4 ... ֽ nÿֽڵұߵλ 0 + 4 SXXXXXXX XMMMMMMM MMMMMMMM MMMMMMMM + ˫ 8 SXXXXXXX XXXXMMMM MMMMMMMM MMMMMMMM ... MMMMMMMM + չ˫ 10 SXXXXXXX XXXXXXXX 1MMMMMMM MMMMMMMM ... MMMMMMMM // עЧְ 1඼ʡ 1 + ı 16 SXXXXXXX XXXXXXXX MMMMMMMM MMMMMMMM ... MMMMMMMM + ˱ 32 SXXXXXXX XXXXXXXX XXXXMMMM MMMMMMMM ... MMMMMMMM + + ע⣺Little Endian ϣֽ 1 n 򡣱Ԫѵ + + 0ȫ 0 + -0ȫ 0 λΪ 1 + ָȫ 1Чȫ 0 0 1 +} + +type + TCnQuadruple = packed record + {* Delphi ıͣýṹָ} + Lo: TUInt64; + Hi0: Cardinal; + case Boolean of + True: (Hi1: Cardinal); + False: (W0, W1: Word); // С˻ϣźָ W1 + end; + PCnQuadruple = ^TCnQuadruple; + + TCnOctuple = packed record + {* Delphi ް˱ͣ Int64 ָ} + F0: Int64; + F1: Int64; + F2: Int64; + F3: Int64; + end; + PCnOctuple = ^TCnOctuple; + + ECnFloatSizeError = class(Exception); + +const + CN_EXTENDED_SIZE_8 = 8; // Win64 µ Extended ֻ 8 ֽ + CN_EXTENDED_SIZE_10 = 10; // Win32 µ Extended DZ׼ 10 ֽ + CN_EXTENDED_SIZE_16 = 16; // MACOS64/Linux64 16 ֽ + + CN_SIGN_SINGLE_MASK = $80000000; + CN_SIGN_DOUBLE_MASK = $8000000000000000; + CN_SIGN_EXTENDED_MASK = $8000; // ȥ 8 ֽЧ + CN_SIGN_QUADRUPLE_MASK = $80000000; // ֻǰֽڣȥ˺ + + CN_EXPONENT_SINGLE_MASK = $7F800000; // Ҫ 23 λ + CN_EXPONENT_DOUBLE_MASK = $7FF0000000000000; // Ҫ 52 λ + CN_EXPONENT_EXTENDED_MASK = $7FFF; // ȥ 8 ֽЧ + CN_EXPONENT_QUADRUPLE_MASK = $7FFF; // ȥ 14 ֽЧ + + CN_SIGNIFICAND_SINGLE_MASK = $007FFFFF; // 23 λ + CN_SIGNIFICAND_DOUBLE_MASK = $000FFFFFFFFFFFFF; // 52 λ + CN_SIGNIFICAND_EXTENDED_MASK = $FFFFFFFFFFFFFFFF; // 64 λʵȫ 8 ֽ + CN_SIGNIFICAND_QUADRUPLE_MASK = $FFFF; + + CN_SINGLE_SIGNIFICAND_BITLENGTH = 23; + CN_DOUBLE_SIGNIFICAND_BITLENGTH = 52; + CN_EXTENDED_SIGNIFICAND_BITLENGTH = 63; + + CN_EXPONENT_OFFSET_SINGLE = 127; // ʵֵָҪܴ浽ڴָ + CN_EXPONENT_OFFSET_DOUBLE = 1023; + CN_EXPONENT_OFFSET_EXTENDED = 16383; // 10 16 ֽչȸΪ + + CN_SINGLE_MIN_EXPONENT = -127; + CN_SINGLE_MAX_EXPONENT = 127; // Max ָȫ 1 Σ + CN_DOUBLE_MIN_EXPONENT = -1023; + CN_DOUBLE_MAX_EXPONENT = 1023; + CN_EXTENDED_MIN_EXPONENT = -16383; + CN_EXTENDED_MAX_EXPONENT = 16383; + +procedure ExtractFloatSingle(Value: Single; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: Cardinal); +{* ӵȸнλָЧ֡ + עָΪʵָЧΪ 24 λԭʼΪ 0~22 λ 23 λΪȥ 1 + + + Value: Single - ⿪ĵȸ + out SignNegative: Boolean - λTrue Ϊ + out Exponent: Integer - ָ + out Mantissa: Cardinal - Ч + + ֵޣ +} + +procedure ExtractFloatDouble(Value: Double; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: TUInt64); +{* ˫ȸнλָЧ֡ + עָΪʵָЧΪ 53 λԭʼΪ 0~51 λ 52 λΪȥ 1 + + + Value: Double - ⿪˫ȸ + out SignNegative: Boolean - λTrue Ϊ + out Exponent: Integer - ָ + out Mantissa: TUInt64 - Ч + + ֵޣ +} + +procedure ExtractFloatExtended(Value: Extended; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: TUInt64); +{* չȸнλָЧ֣֧ 10 ֽڡ + Լ 16 ֽڽضΪ 10 ֽڵ Extended ʽ + עָΪʵָЧΪȫ 64 λλ 63 λΪԴ 1 + + + Value: Extended - ⿪չȸ + out SignNegative: Boolean - λTrue Ϊ + out Exponent: Integer - ָ + out Mantissa: TUInt64 - Ч + + ֵޣ +} + +procedure ExtractFloatQuadruple(Value: Extended; out SignNegative: Boolean; + out Exponent: Integer; out MantissaLo: TUInt64; out MantissaHi: TUInt64); +{* ʮֽھȸнλָЧֻ֣ Extended Ϊ 16 ֽ + Ҹʽ IEEE 754-2008 ıȸʱЧĿǰ Delphi ָ֧øʽ + עָΪʵָЧ 112 λΪߵ֡ + + + Value: Extended - ⿪ʮֽھȸ + out SignNegative: Boolean - λTrue Ϊ + out Exponent: Integer - ָ + out MantissaLo: TUInt64 - Чֵ 64 λ + out MantissaHi: TUInt64 - Чָ 64 λ + + ֵޣ +} + +procedure CombineFloatSingle(SignNegative: Boolean; Exponent: Integer; + Mantissa: Cardinal; var Value: Single); +{* ѷλָЧƴɵȸ + + + SignNegative: Boolean - λTrue Ϊ + Exponent: Integer - ָ + Mantissa: Cardinal - Ч + var Value: Single - ϵĵȸ + + ֵޣ +} + +procedure CombineFloatDouble(SignNegative: Boolean; Exponent: Integer; + Mantissa: TUInt64; var Value: Double); +{* ѷλָЧƴ˫ȸ + + + SignNegative: Boolean - λTrue Ϊ + Exponent: Integer - ָ + Mantissa: TUInt64 - Ч + var Value: Double - ϵ˫ȸ + + ֵޣ +} + +procedure CombineFloatExtended(SignNegative: Boolean; Exponent: Integer; + Mantissa: TUInt64; var Value: Extended); +{* ѷλָЧƴչȸ֧ 10 ֽڡ + Լ 16 ֽڽضΪ 10 ֽڵ Extended ʽ + + + SignNegative: Boolean - λTrue Ϊ + Exponent: Integer - ָ + Mantissa: TUInt64 - Ч + var Value: Extended - ϵչȸ + + ֵޣ + +} + +procedure CombineFloatQuadruple(SignNegative: Boolean; Exponent: Integer; + MantissaLo: TUInt64; MantissaHi: TUInt64; var Value: Extended); +{* ѷλָЧƴչȸֻ Extended Ϊ 16 ֽ + Ҹʽ IEEE 754-2008 ıȸʱЧĿǰ Delphi ָ֧øʽ + + + SignNegative: Boolean - λTrue Ϊ + Exponent: Integer - ָ + MantissaLo: TUInt64 - Чֵ 64 λ + MantissaHi: TUInt64 - Чָ 64 λ + var Value: Extended - ϵʮֽھȸ + + ֵޣ +} + +function UInt64ToSingle(U: TUInt64): Single; +{* Int64 зģ 64 λ޷͸ֵ Singleʵͬ + + + U: TUInt64 - ֵ 64 λ޷ֵ + + ֵSingle - صĵȸ +} + +function UInt64ToDouble(U: TUInt64): Double; +{* Int64 зģ 64 λ޷͸ֵ Doubleʵͬ + + + U: TUInt64 - ֵ 64 λ޷ֵ + + ֵDouble - ص˫ȸ +} + +function UInt64ToExtended(U: TUInt64): Extended; +{* Int64 зģ 64 λ޷͸ֵ Extendedʵͬ + + + U: TUInt64 - ֵ 64 λ޷ֵ + + ֵExtended - صչȸ +} + +function SingleToUInt64(F: Single): TUInt64; +{* Single ֵ Int64 зģ 64 λ޷ͣʵͬ + + + F: Single - ֵĵȸ + + ֵTUInt64 - ص 64 λ޷ֵ +} + +function DoubleToUInt64(F: Double): TUInt64; +{* Double ֵ Int64 зģ 64 λ޷ͣʵͬ + + + F: Double - ֵ˫ȸ + + ֵTUInt64 - ص 64 λ޷ֵ +} + +function ExtendedToUInt64(F: Extended): TUInt64; +{* Extended ֵ Int64 зģ 64 λ޷ͣʵͬ + + + F: Extended - ֵ˫ȸ + + ֵTUInt64 - ص 64 λ޷ֵ +} + +function SingleIsInfinite(AValue: Single): Boolean; +{* ȸǷ + + + AValue: Single - жϵĵȸ + + ֵBoolean - Ƿ +} + +function DoubleIsInfinite(AValue: Double): Boolean; +{* ˫ȸǷ + + + AValue: Double - жϵ˫ȸ + + ֵBoolean - Ƿ +} + +function ExtendedIsInfinite(AValue: Extended): Boolean; +{* չȸǷ + + + AValue: Extended - жϵչȸ + + ֵBoolean - Ƿ +} + +function SingleIsNan(AValue: Single): Boolean; +{* ȸǷʵ + + + AValue: Single - жϵĵȸ + + ֵBoolean - Ƿʵ +} + +function DoubleIsNan(AValue: Double): Boolean; +{* ˫ȸǷʵ + + + AValue: Double - жϵ˫ȸ + + ֵBoolean - Ƿʵ +} + +function ExtendedIsNan(AValue: Extended): Boolean; +{* չȸǷʵ + + + AValue: Extended - жϵչȸ + + ֵBoolean - Ƿʵ +} + +// FPCWindows 64/Linux 64 ƽ̨Լ Delphi 56 ֧ +{$IFDEF WIN32} +{$IFDEF COMPILER7_UP} + +{ FloatDecimalToBinExtended, FloatDecimalToOctExtendedFloatDecimalToHexExtended + FloatDecimalToBinaryExtended ̣FloatDecimalToBinaryExtended } + +function FloatDecimalToBinExtended(fIn: Extended; DecimalExp: Boolean; + AlwaysUseExponent: Boolean): AnsiString; // Convert to binary + +function FloatDecimalToOctExtended(fIn: Extended; DecimalExp: Boolean; + AlwaysUseExponent: Boolean): AnsiString; // Convert to octal + +function FloatDecimalToHexExtended(fIn: Extended; DecimalExp: Boolean; + AlwaysUseExponent: Boolean): AnsiString; // Convert to hexdecimal + +{$ENDIF} +{$ENDIF} + +implementation + +const + UINT64_EXTENDED_EXP_MAX = $4040; // UINT64 Ӧ Extended ָ + +resourcestring + SCN_ERROR_EXTENDED_SIZE = 'Extended Size Error'; + +type + TExtendedRec10 = packed record + {* 10 ֽڵչȸֻ Win32 Ч} + Mantissa: TUInt64; + ExpSign: Word; + end; + PExtendedRec10 = ^TExtendedRec10; + +{$IFDEF WIN32} +{$IFDEF COMPILER7_UP} + +type + PConvertFloatSystem = ^TConvertFloatSystem; + TConvertFloatSystem = record + Negative: Boolean; + ExpFlag, ExponentI: Integer; + end; + +const + MaxBinDigits = 120; + MaxHexDigits = 30; + MaxOctDigits = 40; + +function FloatDecimalToBinaryExtended(fIn: Extended; DecimalExp, + AlwaysUseExponent: Boolean; var ForHexOct: PConvertFloatSystem): AnsiString; +var + Neg: Boolean; + i, Flag, IntExp: Integer; + Exp: AnsiString; +label UseExponent; +begin +{ +Extended(32.125) in memory: +0 100000000000100 10000000 10000000 00000000 00000000 00000000 00000000 00000000 00000000 + 9 8 7 6 5 4 3 2nd Byte 1stByte 0 +sign exponent digits +0 111111111111111 1000000000000000000000000000000000000000000000000000000000000000 + Inf +1 111111111111111 1000000000000000000000000000000000000000000000000000000000000000 - Inf +1 111111111111111 1100000000000000000000000000000000000000000000000000000000000000 Nan +0 111111111111111 1100000000000000000000000000000000000000000000000000000000000000 -Nan +} + SetLength(Result, 255); + SetLength(Exp, 2 * SizeOf(Extended) + 1); + Neg := False; + asm + push EBX + push ESI + mov EBX, Result // Address of Result + mov EBX, [EBX] + mov EAX, 0 + // Test if fIN equals 0 + lea ESI, fIn[7] // get the first byte of digits + mov AL, [ESI] + test AL, 128 // 10000000B + jz @Zero + mov ECX, 0 + lea ESI, fIn[8] + mov AX, [ESI] // Get first two bytes + test AX, 32768 // 32768D = 1000000000000000B + jz @Positive + mov Neg, 1 + sub AX, 32768 // Sign bit <- 0 + @Positive: + // Test if fIn is NaN or Infinity + cmp AX, 32767 + jnz @NotNAN_INF + mov DL, [ESI - 1] + test DL, 64 // 01000000B + jz @INF + mov Flag, 4 // NaN + jmp @Done + @INF: + mov Flag, 3 // INF + jmp @Done + @NotNAN_INF: + sub AX, 16383 // AX = AX - 011111111111111B + jns @ExpPositive + sub AX, 1 + not AX + mov Flag, 2 // // Exponent sign negative + jmp @JudgeDecimalExp + @ExpPositive: + mov Flag, 1 // Exponent sign positive + @JudgeDecimalExp: + mov IntExp, EAX + cmp DecimalExp, 1 + je @MoveDigits + // Binary string exponent. Convert AX to binary string and store it in Exp + lea EBX, Exp + mov EBX, [EBX] + push ECX + mov [EBX], 69 // 'E' // "D" for decimal exponent + mov ECX, 1 + cmp Flag, 2 + jnz @NoNegativeInExp + mov [EBX + 1], 45 // '-' // Add a "-" to exponent string + mov ECX, 2 + @NoNegativeInExp: + mov ESI, 0 // flag whehter "1" appears + // Move exponent digits to Exp + mov DX, 32768 // 1000000000000000 + @NextExpDigit: + test AX, DX + jz @AppendExp0 + mov [EBX + ECX], 49 // '1' + mov ESI, 1 + jmp @NextExpIncECX + @AppendExp0: + cmp ESI, 0 + jz @NextExpNoIncECX // do not append this "0" + mov [EBX + ECX], 48 // '0' + @NextExpIncECX: + inc ECX + @NextExpNoIncECX: + shr DX, 1 + cmp DX, 0 + jne @NextExpDigit + pop ECX + mov EBX, Result + mov EBX, [EBX] + jmp @MoveDigits + @MoveDigits: + // Move digits to Result + mov ESI, 8 + @NextByte: + dec ESI + mov EAX, EBX + lea EBX, fIn[ESI] + mov DL, [EBX] + mov EBX, EAX + mov AL, 128 // 10000000 + @NextDigit: + test DL, AL + jz @Append0 + mov [EBX + ECX], 49 // '1' + mov i, ECX + jmp @Next + @Append0: + mov [EBX + ECX], 48 // '0' + @Next: + inc ECX + shr AL, 1 + cmp AL, 0 + jne @NextDigit + cmp ESI, 0 // if the last byte + jne @NextByte + jmp @Done + @Zero: + mov Flag, 0 + @Done: + pop ESI + pop EBX + end; + case Flag of + 0: + begin + ForHexOct := nil; + Result := '0'; + Exit; + end; + 1, 2: + begin + // Delete redundant "0" in Result + Delete(Result, i + 2, MaxInt); // i stores the position of the last 1 in Result + if Assigned(ForHexOct) then + begin + // Copy to ForHexOct + with ForHexOct^ do + begin + Negative := Neg; + ExpFlag := Flag; + ExponentI := IntExp; + end; + Exit; + end; + // Add dot and exponent to Result + if (IntExp = 0) then + begin + if (Length(Result) > 1) then + Insert('.', Result, 2); + end + else + begin + { Decide whether use exponent. For example "1000.101" shouldn't be output + as 1.000101E11 when AlwaysUseExponent is False. } + if AlwaysUseExponent then + begin +UseExponent: + if DecimalExp then + if Flag = 1 then + Exp := 'D' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(IntExp)) + else + Exp := 'D-' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(IntExp)); + if Length(Result) >=2 then + Insert('.', Result, 2); + Result := Result + Exp; + end + else + begin + // IntExp may be negative. + if Flag = 1 then + begin + // Calculate all digits required without exponent + if IntExp <= Length(Result) - 2 then + begin + // Do not use exponent + Insert('.', Result, IntExp + 2); + end + else if IntExp = Length(Result) - 1 then + { 1.001, Exp = 3, output 1001 } + else + begin + if IntExp + 1> MaxBinDigits then + goto UseExponent + else + begin + Inc(IntExp); + i := Length(Result); + // Add zeros at tail + SetLength(Result, IntExp); + for i := i + 1 to IntExp do + Result := '0'; + end; + end; + end + else + begin + if IntExp + Length(Result) > MaxBinDigits then + goto UseExponent + else + begin + // Add leading zeros and place "." + SetLength(Exp, 1 + IntExp); + Exp[1] := '0'; + Exp[2] := '.'; + for i := 3 to IntExp + 1 do + Exp := '0'; //} + Result := Exp + Result; + end; + end; + end; + end; + end; + 3: // INF + begin + ForHexOct := nil; + Result := 'INF'; + end; + 4: // NaN + begin + ForHexOct := nil; + Result := 'NaN'; + Exit; + end; + end; + if Neg then + Result := '-' + Result; +end; + +function FloatDecimalToBinExtended(fIn: Extended; DecimalExp, + AlwaysUseExponent: Boolean): AnsiString; +var + PTmp: PConvertFloatSystem; +begin + PTmp := nil; + Result := FloatDecimalToBinaryExtended(fIn, DecimalExp, AlwaysUseExponent, PTmp); +end; + +function FloatDecimalToHexExtended(fIn: Extended; DecimalExp, + AlwaysUseExponent: Boolean): AnsiString; +const + DecToHex: array[0..15] of AnsiChar = + ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); + BinPow: array[0..3] of Integer = (8, 4, 2, 1); + + function IntToHex(Int: Integer): AnsiString; + var + k ,t: Integer; + Buf: array[1..5] of AnsiChar; + begin + k := 1; + while (Int <> 0) do + begin + Buf[k] := DecToHex[Int mod 16]; + Inc(k); + Int := Int div 16; + end; + Dec(k); + SetLength(Result, k); + t := 1; + while (k > 0) do + begin + Result[t] := Buf[k]; + Inc(t); + Dec(k); + end; + end; + + function ToHex(const S: AnsiString; LeftToDot: Boolean): AnsiString; + var + i, l, t, m, k: Integer; + Buf: array[1..20] of AnsiChar; + begin + { LeftToDot = True, S will be patched with zeroes on its left side. + For example, S = '110', after patching, S = '0110'. + LeftToDot = False, S will be patched with zeroes on its right side. + S = '110', after patching, S = '1100'. } + l := Length(S); + if LeftToDot then + t := (4 - (l mod 4)) mod 4 + else + t := 0; + i := 1; + m := 1; + k := 0; + while i <= l do + begin + k := k + BinPow[t] * (Ord(S[i]) - Ord('0')); + Inc(t); + if (t = 4) or (i = l) then + begin + Buf[m] := DecToHex[k]; + Inc(m); + k := 0; + t := 0; + end; + Inc(i); + end; + Dec(m); + SetLength(Result, m); + + while (m > 0) do + begin + Result[m] := Buf[m]; + Dec(m); + end; + end; + +var + PConvertData: PConvertFloatSystem; + ConvertData: TConvertFloatSystem; + tmpS: AnsiString; + k, t, i, m: Integer; +label UseExponent; +begin + PConvertData := @ConvertData; + Result := FloatDecimalToBinaryExtended(fIn, True, True, PConvertData); + // See FloatDecimalToBinaryExtended, PConvertData is set to nil when result is definite. + if PConvertData = nil then + Exit; + with ConvertData do + begin + { 3.BD^D(12) + A.BD^E(ABCE) + AB.FFFF } + k := Length(Result) - 1; + if AlwaysUseExponent then + begin +UseExponent: + { Algorithm: + X.XXXXXXXX^Y Shift Count Exp + 1.00000001^0 = 1.00000001 = 1.01^0 (16) + 1.00000001^1 = 10.0000001 = 2.02^0 (16) + 1.00000001^2 = 100.000001 = 4.04^0 (16) + 1.00000001^3 = 1000.00001 = 8.08^0 (16) + 1.00000001^4 = 1.00000001^100 = 1.01^1 (16) + 1.00000001^5 = 10.0000001^100 = 2.02^1 (16) + Shift Count = Y mod 4 + Exp = Y div 4 + X.XXXXXXXXX^Y Y < 0 Exp + 1.00000001^-1 = 0.100000001 = 1000.00001^-100 = 8.08^-1 + 1.00000001^-2 = 0.0100000001 = 100.000001^-100 = 4.04^-1 + 1.00000001^-3 = 0.00100000001 = 10.0000001^-100 = 2.02^-1 + 1.00000001^-4 = 0.000100000001 = 1.00000001^-100 = 1.01^-1 + 1.00000001^-5 = 0.0000100000001 = 1000.00001^-100 = 8.08^-2 + Shift Count = 4 - (Abs(Y) mod 4) + Exp = -(Abs(Y) div 4 + 1) } + if ExpFlag = 1 then + begin + t := ExponentI div 4; // Exp + i := ExponentI mod 4; // Shift Count + end + else + begin + t := -((ExponentI - 1) div 4 + 1); // Exp + i := (4 - (ExponentI mod 4)) mod 4; // Shift Count + end; + // Get hex digits + if k < i then + begin + // Add extra zeroes + SetLength(Result, i + 1); + for m := k + 2 to i + 1 do + Result[m] := '0'; + Result := ToHex(Result, True); + end + else if k = i then + Result := ToHex(Result, True) + else + begin + tmpS := Copy(Result, 1, i + 1); + Delete(Result, 1, i + 1); + Result := ToHex(tmpS, True) + '.' + ToHex(Result, False); + end; + if t <> 0 then + begin + // Format exponent + if DecimalExp then + Result := Result + '^D(' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(t)) + ')' + else + begin + if ExpFlag = 1 then + Result := Result + '^E(' + IntToHex(t) + ')' + else // t < 0 + Result := Result + '^E(-' + IntToHex(-t) + ')'; + end; + end; + end + else + begin + { Always remember that Result equals "XXXXXXXX" not "X.XXXXXXX". + Judge whether to use exponent: + There are K "X" after '.', K = Length(Result) - 1, no "." in Result originally. + X.XXXXXXX^Y (Binary string, ExponentI = Abs(Y)) + case Y >= 0 (Condition: ExpFlag = 2) + Y <= K: + Y+1 binary digits on left side of '.', K-Y digits on right side + totally requires ((Y+1 - 1) div 4 + 1) + ((K-Y - 1) div 4 + 1) hex digits + Y > K: + Y+1 binary digits on left side, totally ((Y+1 - 1) div 4 + 1) hex digits + case Y<0 (Condition: ExpFlag = 1) 0.XXXX or 0.000XXXX + One digit '0' on left side and K+1+Abs(Y)-1 digits on right side, + totally 1 + ((K+1+Abs(Y)-1-1) div 4 + 1) hex digits. + Compare hdc = hex digit count with MaxHexDigits. If hdc > MaxHexDigits, + goto UseExponent. } + if ExponentI = 0 then + begin + if (Length(Result) > 1) then + Result := '1.' + ToHex(Copy(Result, 2, MaxInt), False); + end + else + begin + if ExpFlag = 1 then + begin + if ExponentI < k then + begin + // No possible that "ExponentI div 4 + (k - ExponentI - 1) div 4 + 2" > MaxHexDigits + tmpS := Copy(Result, 1, ExponentI + 1); + Delete(Result, 1, ExponentI + 1); + Result := ToHex(tmpS, True) + '.' + ToHex(Result, False); + end + else if ExponentI = k then + // 1.01^2 = 101, no ".", no extra "0". + Result := ToHex(Result, True) + else + begin + t := ExponentI div 4 + 1; + if t > MaxHexDigits then + goto UseExponent + else + begin + // Append "0" after Result + Inc(ExponentI); + // Add '0' to Result + SetLength(Result, ExponentI); + for t := k + 2{original Length(Result) + 1} to ExponentI do + Result[t] := '0'; + Result := ToHex(Result, True); + end; + end; + end + else + begin + // ExpFlag = 2, X.XXXXXXX^Y, Y < 0 + t := 2 + (k + ExponentI - 1) div 4; {1 + ((K+1+Abs(Y)-1-1) div 4 + 1)} + if t > MaxHexDigits then + goto UseExponent + else + begin + // Add leading zeroes before Result + SetLength(tmpS, ExponentI - 1); // tmpS stores extra zeroes + for t := 1 to ExponentI - 1 do + tmpS[t] := '0'; + Result := '0.' + ToHex(tmpS + Result, False); + end; + end; + end; + end; + if Negative then + Result := '-' + Result; + end; +end; + +function FloatDecimalToOctExtended(fIn: Extended; DecimalExp, + AlwaysUseExponent: Boolean): AnsiString; +const + DecToOct: array[0..7] of AnsiChar = + ('0', '1', '2', '3', '4', '5', '6', '7'); + BinPow: array[0..2] of Integer = (4, 2, 1); + + function IntToOct(Int: Integer): AnsiString; + var + k ,t: Integer; + Buf: array[1..10] of AnsiChar; + begin + k := 1; + while (Int <> 0) do + begin + Buf[k] := DecToOct[Int mod 8]; + Inc(k); + Int := Int div 8; + end; + Dec(k); + SetLength(Result, k); + t := 1; + while (k > 0) do + begin + Result[t] := Buf[k]; + Inc(t); + Dec(k); + end; + end; + + function ToOct(const S: AnsiString; LeftToDot: Boolean): AnsiString; + var + i, l, t, m, k: Integer; + Buf: array[1..30] of AnsiChar; + begin + { LeftToDot = True, S will be patched with zeroes on its left side. + For example, S = '110', after patching, S = '0110'. + LeftToDot = False, S will be patched with zeroes on its right side. + S = '110', after patching, S = '1100'. } + l := Length(S); + if LeftToDot then + t := (3 - (l mod 3)) mod 3 + else + t := 0; + i := 1; + m := 1; + k := 0; + while i <= l do + begin + k := k + BinPow[t] * (Ord(S[i]) - Ord('0')); + Inc(t); + if (t = 3) or (i = l) then + begin + Buf[m] := DecToOct[k]; + Inc(m); + k := 0; + t := 0; + end; + Inc(i); + end; + Dec(m); + SetLength(Result, m); + + while (m > 0) do + begin + Result[m] := Buf[m]; + Dec(m); + end; + end; + +var + PConvertData: PConvertFloatSystem; + ConvertData: TConvertFloatSystem; + tmpS: AnsiString; + k, t, i, m: Integer; +label UseExponent; +begin + PConvertData := @ConvertData; + Result := FloatDecimalToBinaryExtended(fIn, True, True, PConvertData); + // See FloatDecimalToBinaryExtended, PConvertData is set to nil when result is definite. + if PConvertData = nil then + Exit; + with ConvertData do + begin + { 3.333D12 // 12 is decimal + 2.22E33 // 33 is octal} + k := Length(Result) - 1; + if AlwaysUseExponent then + begin +UseExponent: + if ExpFlag = 1 then + begin + t := ExponentI div 3; // Exp + i := ExponentI mod 3; // Shift Count + end + else + begin + t := -((ExponentI - 1) div 3 + 1); // Exp + i := (3 - (ExponentI mod 3)) mod 3; // Shift Count + end; + // Get hex digits + if k < i then + begin + // Add extra zeroes + SetLength(Result, i + 1); + for m := k + 2 to i + 1 do + Result[m] := '0'; + Result := ToOct(Result, True); + end + else if k = i then + Result := ToOct(Result, True) + else + begin + tmpS := Copy(Result, 1, i + 1); + Delete(Result, 1, i + 1); + Result := ToOct(tmpS, True) + '.' + ToOct(Result, False); + end; + if t <> 0 then + begin + // Format exponent + if DecimalExp then + Result := Result + 'D' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(t)) + else + begin + if ExpFlag = 1 then + Result := Result + 'E' + IntToOct(t) + else // t < 0 + Result := Result + 'E-' + IntToOct(-t); + end; + end; + end + else + begin + if ExponentI = 0 then + begin + if (Length(Result) > 1) then + Result := '1.' + ToOct(Copy(Result, 2, MaxInt), False); + end + else + begin + if ExpFlag = 1 then + begin + if ExponentI < k then + begin + tmpS := Copy(Result, 1, ExponentI + 1); + Delete(Result, 1, ExponentI + 1); + Result := ToOct(tmpS, True) + '.' + ToOct(Result, False); + end + else if ExponentI = k then + // 1.01^2 = 101, no ".", no extra "0". + Result := ToOct(Result, True) + else + begin + t := ExponentI div 3 + 1; + if t > MaxHexDigits then + goto UseExponent + else + begin + // Append "0" after Result + Inc(ExponentI); + // Add '0' to Result + SetLength(Result, ExponentI); + for t := k + 2{original Length(Result) + 1} to ExponentI do + Result[t] := '0'; + Result := ToOct(Result, True); + end; + end; + end + else + begin + // ExpFlag = 2, X.XXXXXXX^Y, Y < 0 + t := 2 + (k + ExponentI - 1) div 3; + if t > MaxHexDigits then + goto UseExponent + else + begin + // Add leading zeroes before Result + SetLength(tmpS, ExponentI - 1); // tmpS stores extra zeroes + for t := 1 to ExponentI - 1 do + tmpS[t] := '0'; + Result := '0.' + ToOct(tmpS + Result, False); + end; + end; + end; + end; + if Negative then + Result := '-' + Result; + end; +end; + +{$ENDIF} +{$ENDIF} + +procedure ExtractFloatSingle(Value: Single; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: Cardinal); +begin + SignNegative := (PCardinal(@Value)^ and CN_SIGN_SINGLE_MASK) <> 0; + Exponent := ((PCardinal(@Value)^ and CN_EXPONENT_SINGLE_MASK) shr 23) - CN_EXPONENT_OFFSET_SINGLE; + Mantissa := PCardinal(@Value)^ and CN_SIGNIFICAND_SINGLE_MASK; + Mantissa := Mantissa or (1 shl 23); // λټӸ 1 +end; + +procedure ExtractFloatDouble(Value: Double; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: TUInt64); +begin + SignNegative := (PUInt64(@Value)^ and CN_SIGN_DOUBLE_MASK) <> 0; + Exponent := ((PUInt64(@Value)^ and CN_EXPONENT_DOUBLE_MASK) shr 52) - CN_EXPONENT_OFFSET_DOUBLE; + Mantissa := PUInt64(@Value)^ and CN_SIGNIFICAND_DOUBLE_MASK; + Mantissa := Mantissa or (TUInt64(1) shl 52); // λټӸ 1 +end; + +procedure ExtractFloatExtended(Value: Extended; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: TUInt64); +begin + if (SizeOf(Extended) = CN_EXTENDED_SIZE_10) or (SizeOf(Extended) = CN_EXTENDED_SIZE_16) then + begin + SignNegative := (PExtendedRec10(@Value)^.ExpSign and CN_SIGN_EXTENDED_MASK) <> 0; + Exponent := (PExtendedRec10(@Value)^.ExpSign and CN_EXPONENT_EXTENDED_MASK) - CN_EXPONENT_OFFSET_EXTENDED; + Mantissa := PExtendedRec10(@Value)^.Mantissa; // 1ü + end + else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then + ExtractFloatDouble(Value, SignNegative, Exponent, Mantissa) + else + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); +end; + +procedure ExtractFloatQuadruple(Value: Extended; out SignNegative: Boolean; + out Exponent: Integer; out MantissaLo, MantissaHi: TUInt64); +begin + if SizeOf(Extended) <> CN_EXTENDED_SIZE_16 then + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); + + SignNegative := (PCnQuadruple(@Value)^.W1 and CN_SIGN_QUADRUPLE_MASK) <> 0; + Exponent := (PCnQuadruple(@Value)^.W1 and CN_EXPONENT_QUADRUPLE_MASK) - CN_EXPONENT_OFFSET_EXTENDED; + + // Extract 16 Bytes to Mantissas + MantissaLo := PCnQuadruple(@Value)^.Lo; + MantissaHi := TUInt64(PCnQuadruple(@Value)^.Hi0) or (TUInt64(PCnQuadruple(@Value)^.W0) shl 32) or (TUInt64(1) shl 48); // λټӸ 1 +end; + +procedure CombineFloatSingle(SignNegative: Boolean; Exponent: Integer; + Mantissa: Cardinal; var Value: Single); +begin + Mantissa := Mantissa and not (1 shl 23); // ȥ 23 λϵ 1еĻ + PCardinal(@Value)^ := Mantissa and CN_SIGNIFICAND_SINGLE_MASK; + Inc(Exponent, CN_EXPONENT_OFFSET_SINGLE); + + PCardinal(@Value)^ := PCardinal(@Value)^ or (LongWord(Exponent) shl 23); + if SignNegative then + PCardinal(@Value)^ := PCardinal(@Value)^ or CN_SIGN_SINGLE_MASK + else + PCardinal(@Value)^ := PCardinal(@Value)^ and not CN_SIGN_SINGLE_MASK; +end; + +procedure CombineFloatDouble(SignNegative: Boolean; Exponent: Integer; + Mantissa: TUInt64; var Value: Double); +begin + Mantissa := Mantissa and not (TUInt64(1) shl 52); // ȥ 52 λϵ 1еĻ + PUInt64(@Value)^ := Mantissa and CN_SIGNIFICAND_DOUBLE_MASK; + Inc(Exponent, CN_EXPONENT_OFFSET_DOUBLE); + + PUInt64(@Value)^ := PUInt64(@Value)^ or (TUInt64(Exponent) shl 52); + if SignNegative then + PUInt64(@Value)^ := PUInt64(@Value)^ or CN_SIGN_DOUBLE_MASK + else + PUInt64(@Value)^ := PUInt64(@Value)^ and not CN_SIGN_DOUBLE_MASK; +end; + +{$HINTS OFF} + +procedure CombineFloatExtended(SignNegative: Boolean; Exponent: Integer; + Mantissa: TUInt64; var Value: Extended); +var + D: Double; +begin + if (SizeOf(Extended) = CN_EXTENDED_SIZE_10) or (SizeOf(Extended) = CN_EXTENDED_SIZE_16) then + begin + PExtendedRec10(@Value)^.Mantissa := Mantissa; + Inc(Exponent, CN_EXPONENT_OFFSET_EXTENDED); + + PExtendedRec10(@Value)^.ExpSign := Exponent and CN_EXPONENT_EXTENDED_MASK; + if SignNegative then + PExtendedRec10(@Value)^.ExpSign := PExtendedRec10(@Value)^.ExpSign or CN_SIGN_EXTENDED_MASK + else + PExtendedRec10(@Value)^.ExpSign := PExtendedRec10(@Value)^.ExpSign and not CN_SIGN_EXTENDED_MASK; + end + else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then + begin + CombineFloatDouble(SignNegative, Exponent, Mantissa, D); + Value := D; + end + else + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); +end; + +{$HINTS ON} + +procedure CombineFloatQuadruple(SignNegative: Boolean; Exponent: Integer; + MantissaLo, MantissaHi: TUInt64; var Value: Extended); +begin + if SizeOf(Extended) <> CN_EXTENDED_SIZE_16 then + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); + + MantissaHi := MantissaHi and not (TUInt64(1) shl 48); // ȥ 112 λϵ 1еĻ + PCnQuadruple(@Value)^.Lo := MantissaLo; + PCnQuadruple(@Value)^.Hi0 := Cardinal(MantissaHi and $FFFFFFFF); + PCnQuadruple(@Value)^.Hi1 := (MantissaHi shr 32) and CN_SIGNIFICAND_QUADRUPLE_MASK; + + Inc(Exponent, CN_EXPONENT_OFFSET_EXTENDED); + PCnQuadruple(@Value)^.W1 := Exponent and CN_EXPONENT_QUADRUPLE_MASK; + if SignNegative then + PCnQuadruple(@Value)^.Hi1 := PCnQuadruple(@Value)^.Hi1 or CN_SIGN_QUADRUPLE_MASK + else + PCnQuadruple(@Value)^.Hi1 := PCnQuadruple(@Value)^.Hi1 and not CN_SIGN_QUADRUPLE_MASK; +end; + +// UInt64 Ϊ +function UFloat(U: TUInt64): Extended; +{$IFNDEF SUPPORT_UINT64} +var + L, H: Cardinal; +{$ENDIF} +begin +{$IFDEF SUPPORT_UINT64} + Result := U; +{$ELSE} + if U < 0 then // Int64 С 0 ʱ UInt64 Ǵ Int64 ֵ + begin + H := Int64Rec(U).Hi; + L := Int64Rec(U).Lo; + Result := Int64(H) * Int64(CN_MAX_UINT16 + 1); // + Result := Result * (CN_MAX_UINT16 + 1); + Result := Result + L; + end + else + Result := U; +{$ENDIF} +end; + +function UInt64ToSingle(U: TUInt64): Single; +begin + Result := UFloat(U); +end; + +function UInt64ToDouble(U: TUInt64): Double; +begin + Result := UFloat(U); +end; + +function UInt64ToExtended(U: TUInt64): Extended; +begin + Result := UFloat(U); +end; + +// ͨ Trunc ֻܷ Int64 UInt64 +function UTrunc(F: Extended): TUInt64; +var + T: Integer; + SignNeg: Boolean; + Exponent: Integer; + Mantissa: TUInt64; +begin + // õʵָ 1 ͷЧ֣С 1 + ExtractFloatExtended(F, SignNeg, Exponent, Mantissa); + if SignNeg then + raise ERangeError.Create(SRangeError); // ֧ + + // Mantissa 64 λЧ֣С 63 λָС 0 ˵СҪƣôֵ 0 + if Exponent < 0 then + Result := 0 + else + begin + // С Exponent λСߵ + T := 63 - Exponent; // С 0 63 λ 63 λұߣСƺ T λұ + if T < 0 then + raise ERangeError.Create(SRangeError); // Exponent ̫ + + Result := Mantissa shr T; + end; +end; + +function SingleToUInt64(F: Single): TUInt64; +begin + Result := UTrunc(F); +end; + +function DoubleToUInt64(F: Double): TUInt64; +begin + Result := UTrunc(F); +end; + +function ExtendedToUInt64(F: Extended): TUInt64; +begin + Result := UTrunc(F); +end; + +function SingleIsInfinite(AValue: Single): Boolean; +begin + Result := ((PCardinal(@AValue)^ and $7F800000) = $7F800000) and + ((PCardinal(@AValue)^ and $007FFFFF) = $00000000); +end; + +function DoubleIsInfinite(AValue: Double): Boolean; +begin + Result := ((PUInt64(@AValue)^ and $7FF0000000000000) = $7FF0000000000000) and + ((PUInt64(@AValue)^ and $000FFFFFFFFFFFFF) = $0000000000000000); +end; + +function ExtendedIsInfinite(AValue: Extended): Boolean; +begin + if SizeOf(Extended) = CN_EXTENDED_SIZE_10 then + Result := ((PExtendedRec10(@AValue)^.ExpSign and $7FFF) = $7FFF) and + ((PExtendedRec10(@AValue)^.Mantissa) = 0) + else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then + Result := DoubleIsInfinite(AValue) + else + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); +end; + +function SingleIsNan(AValue: Single): Boolean; +begin + Result := ((PCardinal(@AValue)^ and $7F800000) = $7F800000) and + ((PCardinal(@AValue)^ and $007FFFFF) <> $00000000); +end; + +function DoubleIsNan(AValue: Double): Boolean; +begin + Result := ((PUInt64(@AValue)^ and $7FF0000000000000) = $7FF0000000000000) and + ((PUInt64(@AValue)^ and $000FFFFFFFFFFFFF) <> $0000000000000000); +end; + +function ExtendedIsNan(AValue: Extended): Boolean; +begin + if SizeOf(Extended) = CN_EXTENDED_SIZE_10 then + Result := ((PExtendedRec10(@AValue)^.ExpSign and $7FFF) = $7FFF) and + ((PExtendedRec10(@AValue)^.Mantissa and $7FFFFFFFFFFFFFFF) <> 0) + else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then + Result := DoubleIsNan(AValue) + else + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); +end; + +end. diff --git a/CnPack/Crypto/CnKDF.dcu b/CnPack/Crypto/CnKDF.dcu new file mode 100644 index 0000000000000000000000000000000000000000..ab8a24ef0bda87b06579270c031782ff29ce117e GIT binary patch literal 13854 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

GjU1lO-!A@MOz*mL zk-Gj!-RqIMz67tk4skxc*I|n>dmVNPQe>KCjM`HsD%@3flg^&Dvi^!w+b8c};+RtI?`sDq~mozdF9E(z)B^q_;Pr50Yd@w&7R z8H$M3nEMFY0*=QnVorAJx|L{6Fg+< z7;|^UJ08+Il8Fbf3+yXbx}voM`Q>wuO{fDM?E@KY7bev66Yeu@KZvR#T%)~!64hci z79&rggoBMp<3FI2(lEa6_=6Mf-t^9qaT4Ykg0e)E6~1C})eE=5R;yH2iT5g85?0WXyV2pxeT?4D8&@ zvvpo)4{iR!L8QS9&iLOaEn4FCP4aa3@0175PT|@ z;lQyp9#Ohu;fU@&ZZy>M*Qo<-dAr-+WNo>)k5rx>Q26=5inSTp^Ok_RrsI`?l9+m& zugS$L66HYW*@QDE)FGZ|`qMkNAjXYF?FGg}LmKfiXb64Cg~T!FGQvE#gsbj3(~U$# z%YT?Ek;BLN`xJlo@b?-1?&a@S=`HR9JRG}JpsQ{4BMs}BW0bWilt@Q9+UILkXGeR6 zR&~%J_bwbdoa`=s)NRL!fV7(2Cr0fl9#q(~Po3x(mDBJ25IJySap#Lzu%F|h9f>^k zA3MTxoM%DRz5ihiXWndY?7o&uQjA_O~?dh=4sVNc5(aBhj0t>FT2nr1g zzHig897SdVJ&xr9>|fi)g?_g&CK)@?%XoXR^Ic@F{D4q}z)^!;FjCp95E3taBKW zlkG(`j826K*Tqs{EY3|d7M-0bM$HhYJp}?zZ^iJ9>Cz}&E_cn0su{S}#FHs9o#RKc z183cHR?&B8+7xWJs^= zS6Gl-%zK6XI`v%o{p2d~DL*Wxd^4sO!m|(0V|ZS`(~n0x9uDw*nd`}}0Cn1ROq=gC|#35~lGT;1ZghXDFj035(G zjE5!TA2smg;DKLZ=J@DISozDieVf}?$8?h#B8y|4nkfy^tXQXJLY;(D0{j$9DB_4K z7oh`*eeUxmU3N*wmwvAn1TDa`7tc{Vr}3P}lWZgF33TxwAmzfkA_xq=76b;Lff|L12g^1VLN`L12g^1c4!GQh&v<>_1YZ--XuuI3FT+} zob43n>~rFrjpIZ75pm;#fgpI83i0df~7W!ROF;4bThM>`~qaC+JzI zLsX|g4EfZ=91$M~aSA^liqS+*e9(-%CMaC(5K`O#9(;tUp2Nda9zNDYK%Ljqr*ZJI z0c{N59ZbHbsgCJR-*3>Ttadhmq`=rq9am9dc?p@3&6+dK*JIGle`aZA{GSQ&4ac_M z!|_L%Ji1yQUCTaU@+Yh1Pu8+ACXcO_$ExtHmOQ>(9&ce5d>3VrT(TlLP>N@_O}5$O zRGYlZCfjZDOq=Ym$+K;8hE1MllbtsCPMds(O}=Y6!xwDmxdc6J@{U}VhGxjd=89s0 zD6*xEY=v}#yg~{n`3_~(Y-PDaxpuy?e4etZSSg>U6fKq)NU6%|OsGj!x>A*j`AX$t zWz|Am+^H;|sT9pq4pk^cmCEvkdVTFQGS5M#l*`Olo?E9Bg#Wd%! z1J(lhfHhy|AFvt*!RkF}El^&wI`ECbwGhZ)uc6)OkYBUrDw`KiUMVL*KWohdd(s$Z z0qv}A$|(r70T)6%+C@5EQOSh;qo^4Ln{vDMRZo>{3pGlf&3T)Rr?E>gOu=bS83PEOBxai#Ji zmNYS7H3!O5ii(95DnyY#4Sbps%#))$1{cdwp2<))7bxBQeUiUl+;N#+OO+yo#Y+8e z-Q~p~Q>6bby^Pp=rN~9@s{Q3EMQbl3`Ppa-&?~{QGuci#2Tmvcwtqc}-eP$*aeIaLK=P$a%N5w#pBo3^$|9cy8q=T?)I{Cn%D-*cb}? z{cIe??4#HXP&$W@*HNy%iKR$M605Kwv7?Q0E|qI-Yyp+)Z4CbwE3u7~-%-|B>?}r= zXKE#6QB- +================================================================================ +* ƣ +* ԪƣԿ㷨KDFԪ +* ԪߣCnPack (master@cnpack.org) +* עԪʵ˻ RFC2898 PBKDF1 PBKDF2 Կ㷨 PBKDF1 ֧ MD2 㷨 +* ͬʱҲʵ˻ RFC5869 HKDF HMac Կ㷨 +* SM2/SM9 㷨й涨㷨 +* ƽ̨WinXP + Delphi 5.0 +* ݲԣδ +* õԪ豾ػ +* ޸ļ¼2025.01.09 V1.5 +* HKDF ʵֺ +* 2022.06.21 V1.4 +* ϲһֽ CnSM2SM9KDF AnsiString ڸ߰汾 Delphi ¿ +* 2022.04.26 V1.3 +* ޸ LongWord Integer ַת֧ MacOS64 +* 2022.01.02 V1.2 +* CnPBKDF2 һԼ Unicode µļ +* 2021.11.25 V1.1 +* CnSM2KDF Unicode µļ +* 2020.03.30 V1.0 +* Ԫ CnPemUtils ж +================================================================================ +|} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, CnNative, CnMD5, CnSHA1, CnSHA2, CnSHA3, CnSM3; + +type + TCnKeyDeriveHash = (ckdMd5, ckdSha256, ckdSha1); + {* CnGetDeriveKey ʹõӴշ} + + TCnPBKDF1KeyHash = (cpdfMd2, cpdfMd5, cpdfSha1); + {* PBKDF1 涨Ӵշ MD2 Dz֧} + + TCnPBKDF2KeyHash = (cpdfSha1Hmac, cpdfSha256Hmac); + {* PBKDF2 涨Ӵշ} + + TCnHKDFHash = (chkMd5, chkSha1, chkSha256, chkSha3_256, chkSm3); + {* HKDFHMAC-based Key Derivation Functionֵ֧Ӵ} + + ECnKDFException = class(Exception); + {* KDF 쳣} + +function CnGetDeriveKey(const Password: AnsiString; const Salt: AnsiString; + OutKey: PAnsiChar; KeyLength: Cardinal; KeyHash: TCnKeyDeriveHash = ckdMd5): Boolean; +{* Openssl е BytesToKeyָӴ㷨ɼ Key + Ŀǰ KeyLength ֧ HashҲ MD5 32 ֽڣSHA256 64 ֽڡ + + + const Password: AnsiString - + const Salt: AnsiString - ֵ + OutKey: PAnsiChar - Կݿַ + KeyLength: Cardinal - Կݿֽڳ + KeyHash: TCnKeyDeriveHash - Ӵ㷨 + + ֵBoolean - Ƿɳɹ +} + +function CnPBKDF1(const Password: AnsiString; const Salt: AnsiString; Count: Integer; + DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF1KeyHash = cpdfMd5): AnsiString; +{* Password Based KDF 1 ʵ֣򵥵Ĺ̶Ӵյֻ֧ MD5 SHA1뷵ֵΪ AnsiString + DerivedKeyByteLength Կֽȹ̶ + + + const Password: AnsiString - + const Salt: AnsiString - ֵ + Count: Integer - + DerivedKeyByteLength: Integer - ɵԿֽڳ + KeyHash: TCnPBKDF1KeyHash - Ӵ㷨 + + ֵAnsiString - ɵԿ +} + +function CnPBKDF2(const Password: AnsiString; const Salt: AnsiString; Count: Integer; + DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF2KeyHash = cpdfSha1Hmac): AnsiString; +{* Password Based KDF 2 ʵ֣ HMAC-SHA1 HMAC-SHA256뷵ֵΪ AnsiString + DerivedKeyByteLength Կֽȿɱ䣬 + + + const Password: AnsiString - + const Salt: AnsiString - ֵ + Count: Integer - + DerivedKeyByteLength: Integer - ɵԿֽڳ + KeyHash: TCnPBKDF2KeyHash - Ӵ㷨 + + ֵAnsiString - ɵԿ +} + +function CnPBKDF1Bytes(const Password: TBytes; const Salt: TBytes; Count: Integer; + DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF1KeyHash = cpdfMd5): TBytes; +{* Password Based KDF 1 ʵ֣򵥵Ĺ̶Ӵյֻ֧ MD5 SHA1뷵ֵΪֽ顣 + DerivedKeyByteLength Կֽȹ̶ + + + const Password: TBytes - + const Salt: TBytes - ֵ + Count: Integer - + DerivedKeyByteLength: Integer - ɵԿֽڳ + KeyHash: TCnPBKDF1KeyHash - Ӵ㷨 + + ֵTBytes - ɵԿ +} + +function CnPBKDF2Bytes(const Password: TBytes; const Salt: TBytes; Count: Integer; + DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF2KeyHash = cpdfSha1Hmac): TBytes; +{* Password Based KDF 2 ʵ֣ HMAC-SHA1 HMAC-SHA256뷵ֵΪֽ顣 + DerivedKeyByteLength Կֽȿɱ䣬 + + + const Password: TBytes - + const Salt: TBytes - ֵ + Count: Integer - + DerivedKeyByteLength: Integer - ɵԿֽڳ + KeyHash: TCnPBKDF2KeyHash - Ӵ㷨 + + ֵTBytes - ɵԿ +} + +// ============ SM2/SM9 й涨ͬһԿַװʵ =============== + +function CnSM2KDF(const Data: AnsiString; DerivedKeyByteLength: Integer): AnsiString; +{* SM2 Բ߹Կ㷨й涨ԿDerivedKeyLength Կֽ + AnsiStringͬʱƺҲû SharedInfo ANSI-X9.63-KDF + + + const Data: AnsiString - Կԭʼݣ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵAnsiString - ɵԿ +} + +function CnSM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): AnsiString; +{* SM9 ʶ㷨й涨ԿDerivedKeyLength Կֽ + AnsiStringͬʱƺҲû SharedInfo ANSI-X9.63-KDF + + + Data: Pointer - Կԭʼݿַ + DataByteLen: Integer - Կԭʼݵֽڳ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵAnsiString - ɵԿ +} + +function CnSM2KDFBytes(const Data: TBytes; DerivedKeyByteLength: Integer): TBytes; +{* Ϊֽʽ SM2 Բ߹Կ㷨й涨Կ + DerivedKeyLength Կֽɵֽ顣 + + + const Data: TBytes - Կԭʼݵֽ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnSM9KDFBytes(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; +{* Ϊڴʽ SM9 ʶ㷨й涨Կ + DerivedKeyLength Կֽɵֽ顣 + + + Data: Pointer - Կԭʼݿַ + DataByteLen: Integer - Կԭʼݵֽڳ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnSM2SM9KDF(Data: TBytes; DerivedKeyByteLength: Integer): TBytes; overload; +{* Ϊֽʽ SM2 Բ߹Կ㷨 SM9 ʶ㷨й涨Կ + DerivedKeyLength ԿֽɵԿֽ顣 + + + Data: TBytes - Կԭʼݵֽ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnSM2SM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; overload; +{* Ϊڴʽ SM2 Բ߹Կ㷨 SM9 ʶ㷨й涨Կ + DerivedKeyLength ԿֽԿֽ顣 + + + Data: Pointer - Կԭʼݿַ + DataByteLen: Integer - Կԭʼݵֽڳ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnHKDF(HKDF: TCnHKDFHash; IKM: Pointer; IKMByteLen: Integer; + Salt: Pointer; SaltByteLen: Integer; Info: Pointer; InfoByteLen: Integer; + DerivedKeyByteLength: Integer): TBytes; overload; +{* HMAC KDF Կ IKMSalt InfoָȵԿ + Salt Ϊգڲʹù̶Ӵսȵȫ 0Info ΪաɵԿ + + + HKDF: TCnHKDFHash - Ӵ㷨 + IKM: Pointer - ԿݣInput Keying Materialַ + IKMByteLen: Integer - Կݵֽڳ + Salt: Pointer - Կֵݿַ + SaltByteLen: Integer - Կֵݵֽڳ + Info: Pointer - ԿĿѡϢݿַ + InfoByteLen: Integer - ԿĿѡϢݵֽڳ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnHKDFBytes(HKDF: TCnHKDFHash; IKM: TBytes; Salt: TBytes; Info: TBytes; + DerivedKeyByteLength: Integer): TBytes; overload; +{* HMAC KDF Կ IKMSalt Info ֽ飬ָȵԿ + Salt Ϊգڲʹù̶Ӵսȵȫ 0Info ΪաɵԿ + + HKDF: TCnHKDFHash - Ӵ㷨 + IKM: TBytes - Կ + Salt: TBytes - Կֵ + Info: TBytes - ԿĿѡϢ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +implementation + +resourcestring + SCnErrorKDFKeyTooLong = 'Derived Key Too Long.'; + SCnErrorKDFParam = 'Invalid Parameters.'; + SCnErrorKDFHashNOTSupport = 'Hash Method NOT Support.'; + +function Min(A, B: Integer): Integer; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + if A < B then + Result := A + else + Result := B; +end; + +function CnGetDeriveKey(const Password, Salt: AnsiString; OutKey: PAnsiChar; KeyLength: Cardinal; + KeyHash: TCnKeyDeriveHash): Boolean; +var + Md5Dig, Md5Dig2: TCnMD5Digest; + Sha256Dig, Sha256Dig2: TCnSHA256Digest; + SaltBuf, PS, PSMD5, PSSHA256: AnsiString; +begin + Result := False; + + if (Password = '') or (OutKey = nil) or (KeyLength < 8) then + Exit; + + SetLength(SaltBuf, 8); + FillChar(SaltBuf[1], Length(SaltBuf), 0); + if Salt <> '' then + Move(Salt[1], SaltBuf[1], Min(Length(Salt), 8)); + + if not (KeyHash in [ckdMd5, ckdSha256]) then + raise ECnKDFException.Create(SCnErrorKDFHashNOTSupport); + + PS := AnsiString(Password) + SaltBuf; // 涨ǰ 8 ֽΪ Salt + if KeyHash = ckdMd5 then + begin + SetLength(PSMD5, SizeOf(TCnMD5Digest) + Length(PS)); + Move(PS[1], PSMD5[SizeOf(TCnMD5Digest) + 1], Length(PS)); + Md5Dig := MD5StringA(PS); + // Salt ƴ MD5 16 ByteΪһ + + Move(Md5Dig[0], OutKey^, Min(KeyLength, SizeOf(TCnMD5Digest))); + if KeyLength <= SizeOf(TCnMD5Digest) then + begin + Result := True; + Exit; + end; + + KeyLength := KeyLength - SizeOf(TCnMD5Digest); + OutKey := PAnsiChar(TCnNativeInt(OutKey) + SizeOf(TCnMD5Digest)); + + Move(Md5Dig[0], PSMD5[1], SizeOf(TCnMD5Digest)); + Md5Dig2 := MD5StringA(PSMD5); + Move(Md5Dig2[0], OutKey^, Min(KeyLength, SizeOf(TCnMD5Digest))); + if KeyLength <= SizeOf(TCnMD5Digest) then + Result := True; + + // KeyLength ̫㲻 + end + else if KeyHash = ckdSha256 then + begin + SetLength(PSSHA256, SizeOf(TCnSHA256Digest) + Length(PS)); + Move(PS[1], PSSHA256[SizeOf(TCnSHA256Digest) + 1], Length(PS)); + Sha256Dig := SHA256StringA(PS); + // Salt ƴ SHA256 32 ByteΪһ + + Move(Sha256Dig[0], OutKey^, Min(KeyLength, SizeOf(TCnSHA256Digest))); + if KeyLength <= SizeOf(TCnSHA256Digest) then + begin + Result := True; + Exit; + end; + + KeyLength := KeyLength - SizeOf(TCnSHA256Digest); + OutKey := PAnsiChar(TCnNativeInt(OutKey) + SizeOf(TCnSHA256Digest)); + + Move(Sha256Dig[0], PSSHA256[1], SizeOf(TCnSHA256Digest)); + Sha256Dig2 := SHA256StringA(PSSHA256); + Move(Sha256Dig2[0], OutKey^, Min(KeyLength, SizeOf(TCnSHA256Digest))); + if KeyLength <= SizeOf(TCnSHA256Digest) then + Result := True; + + // KeyLength ̫㲻 + end; +end; + +(* + T_1 = Hash (P || S) , + T_2 = Hash (T_1) , + ... + T_c = Hash (T_{c-1}) , + DK = Tc<0..dkLen-1> +*) +function CnPBKDF1(const Password, Salt: AnsiString; Count, DerivedKeyByteLength: Integer; + KeyHash: TCnPBKDF1KeyHash): AnsiString; +var + P, S, Res: TBytes; +begin + P := AnsiToBytes(Password); + S := AnsiToBytes(Salt); + Res := CnPBKDF1Bytes(P, S, Count, DerivedKeyByteLength, KeyHash); + Result := BytesToAnsi(Res); +end; + +{ + DK = T1 + T2 + ... + Tdklen/hlen + Ti = F(Password, Salt, c, i) + + F(Password, Salt, c, i) = U1 ^ U2 ^ ... ^ Uc + + U1 = PRF(Password, Salt + INT_32_BE(i)) + U2 = PRF(Password, U1) + ... + Uc = PRF(Password, Uc-1) +} +function CnPBKDF2(const Password, Salt: AnsiString; Count, DerivedKeyByteLength: Integer; + KeyHash: TCnPBKDF2KeyHash): AnsiString; +var + P, S, Res: TBytes; +begin + P := AnsiToBytes(Password); + S := AnsiToBytes(Salt); + Res := CnPBKDF2Bytes(P, S, Count, DerivedKeyByteLength, KeyHash); + Result := BytesToAnsi(Res); +end; + +function CnPBKDF1Bytes(const Password, Salt: TBytes; Count, DerivedKeyByteLength: Integer; + KeyHash: TCnPBKDF1KeyHash = cpdfMd5): TBytes; +var + I: Integer; + Md5Dig, TM: TCnMD5Digest; + Sha1Dig, TS: TCnSHA1Digest; + Ptr: PAnsiChar; +begin + Result := nil; + if (Password = nil) or (Count <= 0) or (DerivedKeyByteLength <= 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + case KeyHash of + cpdfMd5: + begin + if DerivedKeyByteLength > SizeOf(TCnMD5Digest) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + SetLength(Result, DerivedKeyByteLength); + Md5Dig := MD5Bytes(ConcatBytes(Password, Salt)); // Got T1 + if Count > 1 then + begin + Ptr := PAnsiChar(@TM[0]); + for I := 2 to Count do + begin + TM := Md5Dig; + Md5Dig := MD5Buffer(Ptr, SizeOf(TCnMD5Digest)); // Got T_c + end; + end; + + Move(Md5Dig[0], Result[0], DerivedKeyByteLength); + end; + cpdfSha1: + begin + if DerivedKeyByteLength > SizeOf(TCnSHA1Digest) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + SetLength(Result, DerivedKeyByteLength); + Sha1Dig := SHA1Bytes(ConcatBytes(Password, Salt)); // Got T1 + if Count > 1 then + begin + Ptr := PAnsiChar(@TS[0]); + for I := 2 to Count do + begin + TS := Sha1Dig; + Sha1Dig := SHA1Buffer(Ptr, SizeOf(TCnSHA1Digest)); // Got T_c + end; + end; + + Move(Sha1Dig[0], Result[0], DerivedKeyByteLength); + end; + else + raise ECnKDFException.Create(SCnErrorKDFHashNOTSupport); + end; +end; + +function CnPBKDF2Bytes(const Password, Salt: TBytes; Count, DerivedKeyByteLength: Integer; + KeyHash: TCnPBKDF2KeyHash = cpdfSha1Hmac): TBytes; +var + HLen, D, I, J, K: Integer; + Sha1Dig1, Sha1Dig, T1: TCnSHA1Digest; + Sha256Dig1, Sha256Dig, T256: TCnSHA256Digest; + S, S1, S256, Pad: TBytes; + PAddr: Pointer; +begin + Result := nil; + if (Salt = nil) or (Count <= 0) or (DerivedKeyByteLength <=0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + if (Password = nil) or (Length(Password) = 0) then + PAddr := nil + else + PAddr := @Password[0]; + + case KeyHash of + cpdfSha1Hmac: + HLen := 20; + cpdfSha256Hmac: + HLen := 32; + else + raise ECnKDFException.Create(SCnErrorKDFParam); + end; + + D := (DerivedKeyByteLength div HLen) + 1; + SetLength(S1, SizeOf(TCnSHA1Digest)); + SetLength(S256, SizeOf(TCnSHA256Digest)); + + SetLength(Pad, 4); + if KeyHash = cpdfSha1Hmac then + begin + for I := 1 to D do + begin + Pad[0] := I shr 24; + Pad[1] := I shr 16; + Pad[2] := I shr 8; + Pad[3] := I; + S := ConcatBytes(Salt, Pad); + + SHA1Hmac(PAddr, Length(Password), PAnsiChar(@S[0]), Length(S), Sha1Dig1); + T1 := Sha1Dig1; + + for J := 2 to Count do + begin + SHA1Hmac(PAddr, Length(Password), PAnsiChar(@T1[0]), SizeOf(TCnSHA1Digest), Sha1Dig); + T1 := Sha1Dig; + for K := Low(TCnSHA1Digest) to High(TCnSHA1Digest) do + Sha1Dig1[K] := Sha1Dig1[K] xor T1[K]; + end; + + Move(Sha1Dig1[0], S1[0], Length(S1)); + Result := ConcatBytes(Result, S1); + end; + Result := Copy(Result, 0, DerivedKeyByteLength); + end + else if KeyHash = cpdfSha256Hmac then + begin + for I := 1 to D do + begin + Pad[0] := I shr 24; + Pad[1] := I shr 16; + Pad[2] := I shr 8; + Pad[3] := I; + S := ConcatBytes(Salt, Pad); + + SHA256Hmac(PAddr, Length(Password), PAnsiChar(@S[0]), Length(S), Sha256Dig1); + T256 := Sha256Dig1; + + for J := 2 to Count do + begin + SHA256Hmac(PAddr, Length(Password), PAnsiChar(@T256[0]), SizeOf(TCnSHA256Digest), Sha256Dig); + T256 := Sha256Dig; + for K := Low(TCnSHA256Digest) to High(TCnSHA256Digest) do + Sha256Dig1[K] := Sha256Dig1[K] xor T256[K]; + end; + + Move(Sha256Dig1[0], S256[0], SizeOf(TCnSHA256Digest)); + Result := ConcatBytes(Result, S256); + end; + Result := Copy(Result, 0, DerivedKeyByteLength); + end; +end; + +function CnSM2KDF(const Data: AnsiString; DerivedKeyByteLength: Integer): AnsiString; +var + Res: TBytes; +begin + if (Data = '') or (DerivedKeyByteLength <= 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + Res := CnSM2SM9KDF(@Data[1], Length(Data), DerivedKeyByteLength); + Result := BytesToAnsi(Res); +end; + +function CnSM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): AnsiString; +var + Res: TBytes; +begin + Res := CnSM2SM9KDF(Data, DataByteLen, DerivedKeyByteLength); + Result := BytesToAnsi(Res); +end; + +function CnSM2KDFBytes(const Data: TBytes; DerivedKeyByteLength: Integer): TBytes; +begin + Result := CnSM2SM9KDF(Data, DerivedKeyByteLength); +end; + +function CnSM9KDFBytes(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; +begin + Result := CnSM2SM9KDF(Data, DataByteLen, DerivedKeyByteLength); +end; + +function CnSM2SM9KDF(Data: TBytes; DerivedKeyByteLength: Integer): TBytes; +begin + if (Data = nil) or (Length(Data) <= 0) or (DerivedKeyByteLength <= 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + Result := CnSM2SM9KDF(@Data[0], Length(Data), DerivedKeyByteLength); +end; + +function CnSM2SM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; overload; +var + DArr: TBytes; + CT, SCT: Cardinal; + I, CeilLen: Integer; + IsInt: Boolean; + SM3D: TCnSM3Digest; +begin + Result := nil; + if (Data = nil) or (DataByteLen <= 0) or (DerivedKeyByteLength <= 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + DArr := nil; + CT := 1; + + try + SetLength(DArr, DataByteLen + SizeOf(Cardinal)); + Move(Data^, DArr[0], DataByteLen); + + IsInt := DerivedKeyByteLength mod SizeOf(TCnSM3Digest) = 0; + CeilLen := (DerivedKeyByteLength + SizeOf(TCnSM3Digest) - 1) div SizeOf(TCnSM3Digest); + + SetLength(Result, DerivedKeyByteLength); + for I := 1 to CeilLen do + begin + SCT := UInt32HostToNetwork(CT); // Ȼĵû˵Ҫһ + Move(SCT, DArr[DataByteLen], SizeOf(Cardinal)); + SM3D := SM3(@DArr[0], Length(DArr)); + + if (I = CeilLen) and not IsInt then + begin + // һ 32 ʱֻƶһ + Move(SM3D[0], Result[(I - 1) * SizeOf(TCnSM3Digest)], (DerivedKeyByteLength mod SizeOf(TCnSM3Digest))); + end + else + Move(SM3D[0], Result[(I - 1) * SizeOf(TCnSM3Digest)], SizeOf(TCnSM3Digest)); + + Inc(CT); + end; + finally + SetLength(DArr, 0); + end; +end; + +function CnHKDF(HKDF: TCnHKDFHash; IKM: Pointer; IKMByteLen: Integer; + Salt: Pointer; SaltByteLen: Integer; Info: Pointer; InfoByteLen: Integer; + DerivedKeyByteLength: Integer): TBytes; +const + MAX_BYTE = 255; +var + PRKMd5, Md5T: TCnMD5Digest; + PRKSha1, Sha1T: TCnSHA1Digest; + PRKSha256, Sha256T: TCnSHA256Digest; + PRKSha3256, Sha3256T: TCnSHA3_256Digest; + PRKSm3, Sm3T: TCnSM3Digest; + T0, T: TBytes; + N, I, Start, HashLen: Integer; +begin + if IKM = nil then + IKMByteLen := 0; + + if Salt = nil then + SaltByteLen := 0; + + if Info = nil then + InfoByteLen := 0; + + if (IKMByteLen < 0) or (SaltByteLen < 0) or (InfoByteLen < 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + // Extract HMac(Salt, IKM)ע IKM ݣ HMac Key + case HKDF of + chkMd5: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnMD5Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnMD5Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKMd5[0], HashLen, 0); + MD5Hmac(@PRKMd5[0], HashLen, IKM, IKMByteLen, PRKMd5); + end + else + MD5Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKMd5); + end; + chkSha1: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSHA1Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnSHA1Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKSha1[0], HashLen, 0); + SHA1Hmac(@PRKSha1[0], HashLen, IKM, IKMByteLen, PRKSha1); + end + else + SHA1Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSha1); + end; + chkSha256: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSHA256Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnSHA256Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKSha256[0], HashLen, 0); + SHA256Hmac(@PRKSha256[0], HashLen, IKM, IKMByteLen, PRKSha256); + end + else + SHA256Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSha256); + end; + chkSha3_256: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSHA3_256Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnSHA3_256Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKSha3256[0], HashLen, 0); + SHA3_256Hmac(@PRKSha3256[0], HashLen, IKM, IKMByteLen, PRKSha3256); + end + else + SHA3_256Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSha3256); + end; + chkSm3: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSM3Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnSM3Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKSm3[0], HashLen, 0); + SM3Hmac(@PRKSm3[0], HashLen, IKM, IKMByteLen, PRKSm3); + end + else + SM3Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSm3); + end; + else + raise ECnKDFException.Create(SCnErrorKDFHashNOTSupport); + end; + + // ʼ Expand + SetLength(T0, InfoByteLen + 1); + if InfoByteLen > 0 then + Move(Info^, T0[0], InfoByteLen); + T0[InfoByteLen] := 1; // ƴװ T0 + + // ʼÿֵļ + SetLength(T, HashLen + InfoByteLen + 1); + + // ýȲ + N := (DerivedKeyByteLength + HashLen - 1) div HashLen; + SetLength(Result, DerivedKeyByteLength); + + // T0 һ T1 + case HKDF of + chkMd5: MD5Hmac(@PRKMd5[0], HashLen, @T0[0], Length(T0), Md5T); + chkSha1: SHA1Hmac(@PRKSha1[0], HashLen, @T0[0], Length(T0), Sha1T); + chkSha256: SHA256Hmac(@PRKSha256[0], HashLen, @T0[0], Length(T0), Sha256T); + chkSha3_256: SHA3_256Hmac(@PRKSha3256[0], HashLen, @T0[0], Length(T0), Sha3256T); + chkSm3: SM3Hmac(@PRKSm3[0], HashLen, @T0[0], Length(T0), Sm3T); + end; + + Start := 0; + for I := 1 to N do + begin + // T1 ƴڽ + if DerivedKeyByteLength > HashLen then + begin + case HKDF of + chkMd5: Move(Md5T[0], Result[Start], HashLen); + chkSha1: Move(Sha1T[0], Result[Start], HashLen); + chkSha256: Move(Sha256T[0], Result[Start], HashLen); + chkSha3_256: Move(Sha3256T[0], Result[Start], HashLen); + chkSm3: Move(Sm3T[0], Result[Start], HashLen); + end; + Inc(Start, HashLen); + Dec(DerivedKeyByteLength, HashLen); + end + else + begin + case HKDF of + chkMd5: Move(Md5T[0], Result[Start], DerivedKeyByteLength); + chkSha1: Move(Sha1T[0], Result[Start], DerivedKeyByteLength); + chkSha256: Move(Sha256T[0], Result[Start], DerivedKeyByteLength); + chkSha3_256: Move(Sha3256T[0], Result[Start], DerivedKeyByteLength); + chkSm3: Move(Sm3T[0], Result[Start], DerivedKeyByteLength); + end; + Break; + end; + + // T1 Info ƴһ𲢼һ + case HKDF of + chkMd5: Move(Md5T[0], T[0], HashLen); + chkSha1: Move(Sha1T[0], T[0], HashLen); + chkSha256: Move(Sha256T[0], T[0], HashLen); + chkSha3_256: Move(Sha3256T[0], T[0], HashLen); + chkSm3: Move(Sm3T[0], T[0], HashLen); + end; + Move(Info^, T[HashLen], InfoByteLen); + T[HashLen + InfoByteLen] := I + 1; + + // Ӵ T2 T1 + case HKDF of + chkMd5: MD5Hmac(@PRKMd5[0], HashLen, @T[0], Length(T), Md5T); + chkSha1: SHA1Hmac(@PRKSha1[0], HashLen, @T[0], Length(T), Sha1T); + chkSha256: SHA256Hmac(@PRKSha256[0], HashLen, @T[0], Length(T), Sha256T); + chkSha3_256: SHA3_256Hmac(@PRKSha3256[0], HashLen, @T[0], Length(T), Sha3256T); + chkSm3: SM3Hmac(@PRKSm3[0], HashLen, @T[0], Length(T), Sm3T); + end; + end; +end; + +function CnHKDFBytes(HKDF: TCnHKDFHash; IKM: TBytes; Salt: TBytes; Info: TBytes; + DerivedKeyByteLength: Integer): TBytes; +var + IKMP, SaltP, InfoP: Pointer; + IKML, SaltL, InfoL: Integer; +begin + IKMP := nil; + SaltP := nil; + InfoP := nil; + IKML := 0; + SaltL := 0; + InfoL := 0; + + if Length(IKM) > 0 then + begin + IKMP := @IKM[0]; + IKML := Length(IKM); + end; + if Length(Salt) > 0 then + begin + SaltP := @Salt[0]; + SaltL := Length(Salt); + end; + if Length(Info) > 0 then + begin + InfoP := @Info[0]; + InfoL := Length(Info); + end; + + Result := CnHKDF(HKDF, IKMP, IKML, SaltP, SaltL, InfoP, InfoL, DerivedKeyByteLength); +end; + +end. diff --git a/CnPack/Crypto/CnMD5.dcu b/CnPack/Crypto/CnMD5.dcu new file mode 100644 index 0000000000000000000000000000000000000000..cb8d6620407415739e0d60166eaf5935ca4734ae GIT binary patch literal 15598 zcmcgz4SZC^wV%CvXR`@OSYn_Nfwu`lV}ullT0qoIvNvQgA4{?e;Y(aMyGvrS37ZX) zKBGy)J_#`vt61toAH1qXv?_iTsQMD5f~~cvJjIHyv5l}oz(`YFC1l?@Gxy%y5M1lC zzqhiPGiT?`o)pI;k|2H#G!3wIJ$CD037o@dO&G>iqBhc$M2L<~0R9C#Rng zy~cc3pt8#Es`)(HDtM{QAH3$OKd*c7q&F_FuCB)8^3QF3=@xIiJ=fn*mA}RnXkH(= z%xh=}2CDqN880RN-kap~SGnsdJ>|o!1nkV~hiUXPZ^F_lrTxR7J$>362cvj=p1}4u z8(#3~ZGJbx^Tyfhs(>Hp{PL1JU_iyL-!#P?^BD`OYHDzJ?CCRSc7iMQNI_ zyZUXPSX{Txvtr^0SAzx|6=kd^ZW!_z7J7ok%o)UMR9fDxyJ5C3&cd5sy==q%zPN&b z$0PUi87*>c>${F*U$Ujp<*%&q6ri_inm)O?{PhV?|%R1JAH|)%~5AZht2i0l|lPb=nd_eXKs2J)L{+Umtu#NRV#Kv2h;E~q5J@w30@(|1;0OHffKRW8JjDr}r`I+P0mB~Edv-4|Q4Go?K z@S-=)0Rwnkwbz`Tm+8Aiu4Kc6+v^&tf{+d?QcAmq8_I_pRzib!j02(zLmO0_*zs$Z zFELxg`Ca3d=X@y|Ms_}Q40@9GzwxEJa;$6(6wY8(4Kv5!z{G3#((_J>cdSDR@j_2c zy(jR5(ZAoD?2yxr^D<5z*zPs5q%8BeA9(IeiZ8)iTUzh&mw8;3Pd1;J?K636%VA19 zR*%1FX`m|TNxb94Y;QdG8vv}?WGL|^WUKYkn|lAlhbkR)IAOPc{OjS`PkuXRzt5z0 zmEk$2nCB=jB36t^q6yzow6LVjIsJ&X+L61RHmQg@{>-=AOSZwMk(-}v%;zZ3}6 z1&UquOR7A#m3q;YRaIV#?^30Sy9@cysUEarGt*Pz3RbQ2pq_ZEE9i366?)b$_|>F1 zUownV7ieO}gTTSPQ}i(LOCcxgtFob}thM|+UTKD*!<9%b9TzO$`nZ%e+hk>Dk{<+4 zyzUz}3{swvV}Jcgn=i?pyO3ilEh$>Y#z-15t?&GB&0W4Ern@-T&d~2cOUB56aKS!# zd-|_@W1aq5Z9Ht9)9nCPdV)o+h9C=<-wf zKzzVwz5D7oIptdzgH*eL1-;~zVa;#{Xs>n;Yv9t_xV;}*^Zjc0fhlprQMDZm;h`2U zfT-Hk0u}gdce}F^?65~$t9+h@;6_3|EogGg%}R8zomu5({P3p7=Vy)K-2A#mKX#?9 z!F3B1W_b{n5nx_c`&YRh=&Y~#IYxH_O0pPCuect1FSxJgg*h$x; z+QVJDUbSXTklC&pw>?nj3wRnD3L5=xXiseYI^!mP-kQ zEFxqqKr>HED=f~GmsXa=a4!hH_x=1Qn=qS{5 zGH1m*Ktq0B6`&MI2+Oe9 z0GkG6F;;rq+v0UXrcNi2Xr^xAx0W3bvg4U-A=jJbhO&j?9NvV4pp_Pc8xnujF9~UdhKYoUXG@hcXkqhNU@O zR}Q6+mM-MxBf|vBRxxD@nVY_|vSy~Nkoj%bceU&xrp(41`P6q+_A)9nNPc`KMZf6; z)R=B4uWJmrJzhd4MA8ioSHS1N7@E+ZPFV&54Z)==hjLDjS?7Q@!ogHUMq;=qs}>+e>t!ct|0-6k?A;Jfjdh6=J(WY*mQO3b9ckS`^~5A%*%#rQTAh zZk5`tQae=YUX^N9skJKQQmMr%m8(*-RVrPj#;KG}r9L~a+NV-)sZ_U0?N+HBDs`_) zwW`!wm2#=nVwK8Oso5%(u2SPvN~cnv4XXC3)LSamtx~&HYKKbQt5U5hwN|BEDz#Xp za#d=!N~NpRIF-_=)Mw{Z`_8#D<6yH50GX0(f!ild|BU!G70_Z3HThwk2V;@VKX#Vde$S|V~(@C0zqiRnkH)! z)M1ul+I$sjh>0)+9#*tN80(qYer7_CS*%iqaAz7pH9MREfIF)ndr@9EGDZN+Fz`(r z%$nbC7I7Z~vZP02`%$yO?y8ja!pboY54!<4GJ<}7kU+~jsURA0RbodA(2)^IkAv*T z2c=s8bAJX)?fKz!IH1?mWEZq{14`hY_fYd&~)rx}d8@VHmcXU&Q-N?HVQKGDo`&OPwn1MLpK?i(ek7$!XkUnG7-WL_AXfj_DDtG5sTqX_bxP#~zTs z?x_Q1WFM2)0~0JszCc{e1wN=Xh25DLsa!M{WYh=-E8ARGd8 zf{BosdKS*{x!AqLRf{p4d^jV{)*#i^2b=yNK+Ht65&OAWR|uZEDr^?gSaWkonMsI!CM%e;{dI3T5qRx3_RRThIcqkojh1Ag^Uz;f-=Qsg{_z{X5 z5Dy@R>pkW%cv_Y3qM*lwqa(rs)=*8-9yTYVI$OhXPoPdtF5{aII_YA{Lm5H5v?O{A{PQqD-#X z6?Crwxdg-Hw@4A2Ex|gQ$)pR`IY?-qt&KwRpwBG(!r~|d*=OTUBxxxZ%7aL19i0{nU3BUN!C`ulABXN{> zfa?y0fKuQw#ZAS5;8h3Sif~36GUQ0&oC@TyAma6{td8L$FuaJz_%&A^L{H>Eg0zHp z9b`C?I726glJfoobPa!Q29l3SKoNdqWioSEnZTVOE0ZT@`1S**2EX``z16}h|Mx%6 zj=r`7{q4mA?aoNMG}s{xPL(1Z&cQFkCvI1%4nZLh}1gKW-V=K4CMf$p#n>RPw7UFtn3g)u@Qc*ed+ zI-Gs&LX?FP)Vh0M68hq`4AX^-G=M0=o}_@2WP-dD z^dUQRh>0E@1y?#spB{Vr-(z8YgNYs)jr9o4dhM=-v9KOyqK8LgJxnhtn6)z&)+0>x zjnP=&pt>yu=VM_#%0yv-x?pOhL-gp@ma14-k1^2$qp=>KPk&+Uh=sL>iFS>~+C_J- zh(=>!?Pa1bjmG*CedWEC?Xj?indqL;SohG3ahq?Ag|&}~K0g}k^Yp&8TfxI$AH)4j z^qJ9EpP~2UH$4^$>i`pdax~T_X}a-wTP&2@-#5dJK4SkmpJw@jPzxq_9le7$T$ zzVbkPgkgnjXPLv2?h$Hv&eEk|jc57#y%G7!Cucju3aQQ(3fPbJ(ssId`AyRmtjR22 zQ?&VtX{v0@!%NGqgD-xfpoD!3GBt5Trt);#HX7wNy2|u}cVnUCA-Huk%B{3K)hfh7 z$*1N1(J1eyt;cs9je$~LS~jy8)xwoF(?jRpIS~shPq({AW4)Um|HDV=v9R(G+&CKR zM*42t4_}Ril`o?kMq}MT?@Ib_SfydXg%$WBGaBMcOUr1iE%bEiaw!&8mTsZj;XE@6 zF5^=A$zLCjg_vy|q4i7wY&+U8W?UNi#ixU@aI+;f6l4lu^U($~l)-XwU zB12(4tJ2ob*WRU|9>el?{OJ4*RWividz|anvntJSJyff}#pj;xlO}EYhFFM&Zf25b zDn7BXDovdGvAP3&kL7Uuh#Y1sRcPf%oLHsSldn7y3n$yBLlsO?#feq=_#gl0##lJ{ z>^hjFiW95!<{N(liz5%}i{WI;M##=2Rh(F*^)LO`E6RLc3@4B2A||QMCsyfecl>*1 z44n8>&F7FkZhiIr9VcU9V;LJNWaFsVuu4O-K0Oi(8(a88Rwk)p!z!hdH;S>av9&2= zVUj8~tkQXhkGvlPTZpI00w$^A#47#x=N}x8g_Etqp}9;_#feoKx&1%?B^FM;I9$af zRh(F*o+VEnh=EfI<7q@Q7uJj`UsLRo~U4IRv9m4~ULJ!cCab}V4BB&i#!xK0 zJlhhPtOhSKXllOh7qRA-uO&t%tHFy5x?`NNBow4Um{FagBKa}-go}(R1Ca$FEjx6 zAz1e7>>?xjbao>n!a94Rd_G>xFOm)t-Big3*C+?!6#T>=K4p|~=-57ZR0Lk)I>#JP zHkk8vyIm<$q2AV&mh<{PJW#XKv~sT#*4{aESWMkveOu2B>~syAw;r!`@=y&l;qvhp z{k8iW3{a0+Kq*{IOlCb&_n_h{rG9>2ajn!BSd2o>{!WJ}4S^K*@k2b^E-_o=BYhv7 zrB8t-z#i7)l@sH)Nnr~-(6x2laIG{D_$a3f>^ViTfK$u}tzmt4NAbXw#bK^bxlrrV zpc>G3u}095)8$-)zgn)0&Z=xTSCeW281!9sm~Z$Fz&Bz?uG}9s*+DQIP%uVL*Yah{ zD%(wKnm`4JFlI%x=M$)sQ)kp`l(2k-;p}HnO?&Y^l66LX!!GV?YwnxdkhEtmG+!w( zPmI~KUajl{3Wfm-IJi!xZ?6%!T$wWht$Xo)mDf4=)&rP(<*EZ-lm5oEn4&4|Qct_H zx2?ICG$yn)_mHt0rom+rC}HyL(xG^Hugjtk3<^}cRCMtNQqIWv8DMS3C6K* zrz)5#Q-^f8!+8Ylz7OnfyayszV54(|+M53WI;;EqF_Ic!@*(@XWpzk-fVn4Iw#08D}EhOipr139m&_}NSk4~(be z!M&<5T=qh0$rj29v zY**WX=iA|S9n*|{$nWR zsg|Axrws6Zp{_8l&5t0j5MhgJqOO1-M8uTkn z737)D5I(Ok7giH|=Wb+P*2`YLxQk&;z@eS0#cXy+wZJwEWkQ(K#%}mC7>K<;0x52& z+#7cCex)z2^(1J+ehr#_>a1XHvL`Kh!BbHkg5Iz=aXl)m)16z;#XDeV?ySxb)_Jd- zx6ACEA#^^2-LVD93Qn_`(R!J&)zRRWk1(2S_3&sd%_m4>N#_=vV(pk%*N%ykFOP|& zGA4HW`Y~6sG3D?b9uw9L&D^OL-V41uL#Tb9y7Q?*#~~>B65Vzn!Xxj(py3k^ueCJ& zAQNGY8iXW@?AGnWcb*J{=G~VQUbEq28uZw!wr`Z8o200^B*K79Q87H>L@uJ`n7Uv> zB3tgbth4x7CsWD>J17mH;!f!pH>RztV(&G;7=B^{3+Yzi>|J>Qd!R7Xb$hu5a`~Xt z4{b1m_>8p4YO27+x43_f2*)>gj_BWLO{kC?H<(b@h3y*>kPEMrqQ!lUd!Q?yP3K_S zeiUTyV>nBB($c=WgCSt;kBscl%jZGC=j>Ir4r_1S&y3Ly(8)T2LfHbGAg$ty?!lUk zSJ_12rH!J(IC39_0En^|->CQl@TL>$aUwL>lNTgWmp9==xyR&t$CNEQog$SPqEX@>7Z z!Y=Z%@D%w_fZySNDNuoo*Ds(S3h@ibG;u4Po=j$nJv4I?9j~7S-+G#9A~rFL&YB?F z#6|Rx3_4Ss2&9Q#Wun)l5|?-l{ZgnDhbBOSnSH;6-%Gue zLM=tqC1wC;0=;Sytp^=u@`5-AdZOk@&}bsBv-)(k{-HRX7MjElp$jT3z+tfGL|~hv(h9mfk?zV8XVU5P`4noI0#pip5%g~+Ho9E2f!s`*AqErZI`9>pOPkP9)I@KB zJ`-X5t7Hu}I)}cJ1x?v>e+Cp8^fg3;om1!`>}+@-f!>@(e>a8Roknk&C~i!k_ax9t z-UEl6ZrJ(_Jjk)m9*1q=r$ACLTAyRP9pHDFZ!^F?55Y#*F`Ix zo=vB}29~1hVH&_rEZ?VB;j{oB5Q3Lx!rb9Bod&7hVEyZK5`CYhl6ZqC4kW;DJ;Z@T z0>8|GnOOu8DH;=XNruhjUW0HC5gwW=Y~Gtl?jvM(0?o$XB#SSY4B7C1!ZC_w!>^KE z;`=5s`<8|V@#jzmYoJVh_U2v@R`wa>I249OBn(AjAvp;}N+IckBCU{|fnv%c(htSu z{p2hZ*^31-U=WDKNCu&5v63N3;sVSO$jm~_6DSv9u0UCY`2uAL<_wf}%o`}nFn6GI zVE#b41ak<=3d|!Ym$O^~VkOHbAZ}{Kd;;Q@#~`7g^e)pw9syDR732(*Eg;i`#NC|~ zG60CjS|IYFd};&v5X%>b$Z0I!*hkJ|`KJd+5{2^k17tFmXCEXpu^gHSs*y++Rwckh z1NE_BhnWWAv`_$Z4aDE!XHJhIabB>%d;>xCVAAVIP1fhZBm*%`|18WZ5ZCE9!*l{s WtWPF_AP}eC1XBtgT&1reuKxu#%R$fp literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnMD5.pas b/CnPack/Crypto/CnMD5.pas new file mode 100644 index 0000000..e859993 --- /dev/null +++ b/CnPack/Crypto/CnMD5.pas @@ -0,0 +1,884 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +{******************************************************************************} +{ } +{ MD5 Message-Digest for Delphi 4 } +{ } +{ Delphi 4 Unit implementing the } +{ RSA Data Security, Inc. MD5 Message-Digest Algorithm } +{ } +{ Implementation of Ronald L. Rivest's RFC 1321 } +{ } +{ Copyright ?1997-1999 Medienagentur Fichtner & Meyer } +{ Written by Matthias Fichtner } +{ } +{ -----------------------------------------------------------------------------} +{ See RFC 1321 for RSA Data Security's copyright and license notice! } +{ -----------------------------------------------------------------------------} +{ The latest release of md5.pas will always be available from } +{ the distribution site at: http://www.fichtner.net/delphi/md5/ } +{ -----------------------------------------------------------------------------} +{ Please send questions, bug reports and suggestions } +{ regarding this code to: mfichtner@fichtner-meyer.com } +{ -----------------------------------------------------------------------------} +{ This code is provided "as is" without express or } +{ implied warranty of any kind. Use it at your own risk. } +{******************************************************************************} + +unit CnMD5; +{* |

+================================================================================
+* ƣ
+* ԪƣMD5 Ӵ㷨ʵֵԪ
+* Ԫߣ壨QSoft hq.com@263.net; http://qsoft.51.net
+*            Ronald L. Rivest  MD5.pas дԭʼ
+*     עԪʵ MD5 Ӵ㷨Ӧ HMAC 㷨
+* ƽ̨PWin2000Pro + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2019.12.12 V1.4
+*               ֧ TBytes
+*           2019.04.15 V1.3
+*               ֧ Win32/Win64/MacOS
+*           2014.11.14 V1.2
+*               л Pascal ֿ֧ƽ̨
+*           2003.09.18 V1.1
+*               òҵ˸õԪԭߵİȨ
+*           2003.09.18 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + Classes, SysUtils, CnConsts, CnNative {$IFDEF MSWINDOWS}, Windows {$ENDIF}; + +type + PMD5Digest = ^TCnMD5Digest; + TCnMD5Digest = array[0..15] of Byte; + {* MD5 Ӵս16 ֽ} + + TCnMD5Count = array[0..1] of Cardinal; + TCnMD5State = array[0..3] of Cardinal; + TCnMD5Block = array[0..15] of Cardinal; + + TCnMD5Buffer = array[0..63] of Byte; + + TCnMD5Context = record + {* MD5 Ľṹ} + State : TCnMD5State; + Count : TCnMD5Count; + Buffer : TCnMD5Buffer; + Ipad : array[0..63] of Byte; {!< HMAC: inner padding } + Opad : array[0..63] of Byte; {!< HMAC: outer padding } + end; + + TCnMD5CalcProgressFunc = procedure (ATotal, AProgress: Int64; + var Cancel: Boolean) of object; + {* Ȼص¼} + +//---------------------------------------------------------------- +// û API +//---------------------------------------------------------------- + +function MD5(Input: PAnsiChar; ByteLength: Cardinal): TCnMD5Digest; +{* ݿ MD5 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5Buffer(const Buffer; Count: Cardinal): TCnMD5Digest; +{* ݿ MD5 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5Bytes(Data: TBytes): TCnMD5Digest; +{* ֽ MD5 㡣 + + + Data: TBytes - ֽ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5String(const Str: string): TCnMD5Digest; +{* String ݽ MD5 㡣ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + + const Str: string - ַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5StringA(const Str: AnsiString): TCnMD5Digest; +{* AnsiString ݽ MD5 㣬ֱӼڲݣޱ봦 + + + const Str: AnsiString - ַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5StringW(const Str: WideString): TCnMD5Digest; +{* WideString ַת MD5 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +{$IFDEF UNICODE} + +function MD5UnicodeString(const Str: string): TCnMD5Digest; +{* UnicodeString ݽֱӵ MD5 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +{$ELSE} + +function MD5UnicodeString(const Str: WideString ): TCnMD5Digest; +{* UnicodeString ݽֱӵ MD5 㣬ֱӼڲ UTF16 ݣת + + + + const Str: WideString - Ŀַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +{$ENDIF} + +function MD5File(const FileName: string; + CallBack: TCnMD5CalcProgressFunc = nil): TCnMD5Digest; +{* ָļݽ MD5 㡣 + + + const FileName: string - ļ + CallBack: TCnMD5CalcProgressFunc - ȻصĬΪ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5Stream(Stream: TStream; + CallBack: TCnMD5CalcProgressFunc = nil): TCnMD5Digest; +{* ָݽ MD5 㡣 + + + Stream: TStream - + CallBack: TCnMD5CalcProgressFunc - ȻصĬΪ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +// ⲿݽɢ MD5 㣬MD5Update ɶα + +procedure MD5Init(var Context: TCnMD5Context); +{* ʼһ MD5 ģ׼ MD5 + + + var Context: TCnMD5Context - ʼ MD5 + + ֵޣ +} + +procedure MD5Update(var Context: TCnMD5Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ MD5 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnMD5Context - MD5 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure MD5Final(var Context: TCnMD5Context; var Digest: TCnMD5Digest); +{* ּ㣬 MD5 Digest С + + + var Context: TCnMD5Context - MD5 + var Digest: TCnMD5Digest - ص MD5 Ӵֵ + + ֵޣ +} + +function MD5Print(const Digest: TCnMD5Digest): string; +{* ʮƸʽ MD5 Ӵֵ + + + const Digest: TCnMD5Digest - ָ MD5 Ӵֵ + + ֵstring - ʮַ +} + +function MD5Match(const D1: TCnMD5Digest; const D2: TCnMD5Digest): Boolean; +{* Ƚ MD5 ӴֵǷȡ + + + const D1: TCnMD5Digest - Ƚϵ MD5 Ӵֵһ + const D2: TCnMD5Digest - Ƚϵ MD5 Ӵֵ + + ֵBoolean - Ƿ +} + +function MD5DigestToStr(const Digest: TCnMD5Digest): string; +{* MD5 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnMD5Digest - ת MD5 Ӵֵ + + ֵstring - صַ +} + +procedure MD5Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnMD5Digest); +{* MD5 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - MD5 Կݿַ + KeyByteLength: Integer - MD5 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnMD5Digest - ص MD5 Ӵֵ + + ֵޣ +} + +implementation + +const + MAX_FILE_SIZE = 512 * 1024 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + HMAC_MD5_BLOCK_SIZE_BYTE = 64; + HMAC_MD5_OUTPUT_LENGTH_BYTE = 16; + +type + TMD5CBits = array[0..7] of Byte; + +var + PADDING: TCnMD5Buffer = ( + $80, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00 + ); + +function F(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and y) or ((not X) and z); +end; + +function G(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and z) or (y and (not z)); +end; + +function H(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor y xor z; +end; + +function I(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := y xor (X or (not z)); +end; + +procedure ROT(var X: Cardinal; N: BYTE); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + X := (X shl N) or (X shr (32 - N)); +end; + +procedure FF(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Inc(A, F(B, C, D) + X + AC); + ROT(A, S); + Inc(A, B); +end; + +procedure GG(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Inc(A, G(B, C, D) + X + AC); + ROT(A, S); + Inc(A, B); +end; + +procedure HH(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Inc(A, H(B, C, D) + X + AC); + ROT(A, S); + Inc(A, B); +end; + +procedure II(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Inc(A, I(B, C, D) + X + AC); + ROT(A, S); + Inc(A, B); +end; + +// Encode Count bytes at Source into (Count / 4) DWORDs at Target +procedure Encode(Source, Target: Pointer; Count: Cardinal); +var + S: PByte; + T: PCardinal; + I: Cardinal; +begin + S := Source; + T := Target; + for I := 1 to Count div 4 do + begin + T^ := S^; + Inc(S); + T^ := T^ or (S^ shl 8); + Inc(S); + T^ := T^ or (S^ shl 16); + Inc(S); + T^ := T^ or (S^ shl 24); + Inc(S); + Inc(T); + end; +end; + +// Decode Count DWORDs at Source into (Count * 4) Bytes at Target +procedure Decode(Source, Target: Pointer; Count: Cardinal); +var + S: PCardinal; + T: PByte; + I: Cardinal; +begin + S := Source; + T := Target; + for I := 1 to Count do + begin + T^ := S^ and $ff; + Inc(T); + T^ := (S^ shr 8) and $ff; + Inc(T); + T^ := (S^ shr 16) and $ff; + Inc(T); + T^ := (S^ shr 24) and $ff; + Inc(T); + Inc(S); + end; +end; + +// Transform State according to first 64 bytes at Buffer +procedure Transform(Buffer: Pointer; var State: TCnMD5State); +var + A, B, C, D: Cardinal; + Block: TCnMD5Block; +begin + Encode(Buffer, @Block, 64); + A := State[0]; + B := State[1]; + C := State[2]; + D := State[3]; + FF (A, B, C, D, Block[ 0], 7, $d76aa478); + FF (D, A, B, C, Block[ 1], 12, $e8c7b756); + FF (C, D, A, B, Block[ 2], 17, $242070db); + FF (B, C, D, A, Block[ 3], 22, $c1bdceee); + FF (A, B, C, D, Block[ 4], 7, $f57c0faf); + FF (D, A, B, C, Block[ 5], 12, $4787c62a); + FF (C, D, A, B, Block[ 6], 17, $a8304613); + FF (B, C, D, A, Block[ 7], 22, $fd469501); + FF (A, B, C, D, Block[ 8], 7, $698098d8); + FF (D, A, B, C, Block[ 9], 12, $8b44f7af); + FF (C, D, A, B, Block[10], 17, $ffff5bb1); + FF (B, C, D, A, Block[11], 22, $895cd7be); + FF (A, B, C, D, Block[12], 7, $6b901122); + FF (D, A, B, C, Block[13], 12, $fd987193); + FF (C, D, A, B, Block[14], 17, $a679438e); + FF (B, C, D, A, Block[15], 22, $49b40821); + GG (A, B, C, D, Block[ 1], 5, $f61e2562); + GG (D, A, B, C, Block[ 6], 9, $c040b340); + GG (C, D, A, B, Block[11], 14, $265e5a51); + GG (B, C, D, A, Block[ 0], 20, $e9b6c7aa); + GG (A, B, C, D, Block[ 5], 5, $d62f105d); + GG (D, A, B, C, Block[10], 9, $2441453); + GG (C, D, A, B, Block[15], 14, $d8a1e681); + GG (B, C, D, A, Block[ 4], 20, $e7d3fbc8); + GG (A, B, C, D, Block[ 9], 5, $21e1cde6); + GG (D, A, B, C, Block[14], 9, $c33707d6); + GG (C, D, A, B, Block[ 3], 14, $f4d50d87); + GG (B, C, D, A, Block[ 8], 20, $455a14ed); + GG (A, B, C, D, Block[13], 5, $a9e3e905); + GG (D, A, B, C, Block[ 2], 9, $fcefa3f8); + GG (C, D, A, B, Block[ 7], 14, $676f02d9); + GG (B, C, D, A, Block[12], 20, $8d2a4c8a); + HH (A, B, C, D, Block[ 5], 4, $fffa3942); + HH (D, A, B, C, Block[ 8], 11, $8771f681); + HH (C, D, A, B, Block[11], 16, $6d9d6122); + HH (B, C, D, A, Block[14], 23, $fde5380c); + HH (A, B, C, D, Block[ 1], 4, $a4beea44); + HH (D, A, B, C, Block[ 4], 11, $4bdecfa9); + HH (C, D, A, B, Block[ 7], 16, $f6bb4b60); + HH (B, C, D, A, Block[10], 23, $bebfbc70); + HH (A, B, C, D, Block[13], 4, $289b7ec6); + HH (D, A, B, C, Block[ 0], 11, $eaa127fa); + HH (C, D, A, B, Block[ 3], 16, $d4ef3085); + HH (B, C, D, A, Block[ 6], 23, $4881d05); + HH (A, B, C, D, Block[ 9], 4, $d9d4d039); + HH (D, A, B, C, Block[12], 11, $e6db99e5); + HH (C, D, A, B, Block[15], 16, $1fa27cf8); + HH (B, C, D, A, Block[ 2], 23, $c4ac5665); + II (A, B, C, D, Block[ 0], 6, $f4292244); + II (D, A, B, C, Block[ 7], 10, $432aff97); + II (C, D, A, B, Block[14], 15, $ab9423a7); + II (B, C, D, A, Block[ 5], 21, $fc93a039); + II (A, B, C, D, Block[12], 6, $655b59c3); + II (D, A, B, C, Block[ 3], 10, $8f0ccc92); + II (C, D, A, B, Block[10], 15, $ffeff47d); + II (B, C, D, A, Block[ 1], 21, $85845dd1); + II (A, B, C, D, Block[ 8], 6, $6fa87e4f); + II (D, A, B, C, Block[15], 10, $fe2ce6e0); + II (C, D, A, B, Block[ 6], 15, $a3014314); + II (B, C, D, A, Block[13], 21, $4e0811a1); + II (A, B, C, D, Block[ 4], 6, $f7537e82); + II (D, A, B, C, Block[11], 10, $bd3af235); + II (C, D, A, B, Block[ 2], 15, $2ad7d2bb); + II (B, C, D, A, Block[ 9], 21, $eb86d391); + Inc(State[0], A); + Inc(State[1], B); + Inc(State[2], C); + Inc(State[3], D); +end; + +// Initialize given Context +procedure MD5Init(var Context: TCnMD5Context); +begin + with Context do + begin + State[0] := $67452301; + State[1] := $EFCDAB89; + State[2] := $98BADCFE; + State[3] := $10325476; + Count[0] := 0; + Count[1] := 0; + // ZeroMemory(@Buffer, SizeOf(TMD5Buffer)); + FillChar(Buffer, SizeOf(TCnMD5Buffer), 0); + end; +end; + +// Update given Context to include Length bytes of Input +procedure MD5Update(var Context: TCnMD5Context; Input: PAnsiChar; ByteLength: Cardinal); +var + Index: Cardinal; + PartLen: Cardinal; + I: Cardinal; +begin + with Context do + begin + Index := (Count[0] shr 3) and $3F; + Inc(Count[0], ByteLength shl 3); + if Count[0] < (ByteLength shl 3) then Inc(Count[1]); + Inc(Count[1], ByteLength shr 29); + end; + + PartLen := 64 - Index; + if ByteLength >= PartLen then + begin + Move(Input^, Context.Buffer[Index], PartLen); + Transform(@Context.Buffer, Context.State); + I := PartLen; + while I + 63 < ByteLength do + begin + Transform(@Input[I], Context.State); + Inc(I, 64); + end; + Index := 0; + end + else + I := 0; + + Move(Input[I], Context.Buffer[Index], ByteLength - I); +end; + +procedure MD5UpdateW(var Context: TCnMD5Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + pContent: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(pContent, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(pContent), CharLength * SizeOf(WideChar), nil, nil); + MD5Update(Context, pContent, iLen); + finally + FreeMem(pContent); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + MD5Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +// Finalize given Context, create Digest +procedure MD5Final(var Context: TCnMD5Context; var Digest: TCnMD5Digest); +var + Bits: TMD5CBits; + Index: Cardinal; + PadLen: Cardinal; +begin + Decode(@Context.Count, @Bits, 2); + Index := (Context.Count[0] shr 3) and $3f; + if Index < 56 then + PadLen := 56 - Index + else + PadLen := 120 - Index; + MD5Update(Context, @PADDING, PadLen); + MD5Update(Context, @Bits, 8); + Decode(@Context.State, @Digest, 4); +end; + +function InternalMD5Stream(Stream: TStream; const BufSize: Cardinal; var D: + TCnMD5Digest; CallBack: TCnMD5CalcProgressFunc = nil): Boolean; +var + Context: TCnMD5Context; + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; +begin + Result := False; + Size := Stream.Size; + if Size = 0 then + Exit; + + SavePos := Stream.Position; + TotalBytes := 0; + + if Size < BufSize then + BufLen := Size + else + BufLen := BufSize; + + CancelCalc := False; + MD5Init(Context); + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + MD5Update(Context, Buf, ReadBytes); + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + MD5Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ݿ MD5 +function MD5(Input: PAnsiChar; ByteLength: Cardinal): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, Input, ByteLength); + MD5Final(Context, Result); +end; + +// ݿ MD5 +function MD5Buffer(const Buffer; Count: Cardinal): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, PAnsiChar(Buffer), Count); + MD5Final(Context, Result); +end; + +function MD5Bytes(Data: TBytes): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, PAnsiChar(@Data[0]), Length(Data)); + MD5Final(Context, Result); +end; + +// String ݽ MD5 +function MD5String(const Str: string): TCnMD5Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := MD5StringA(AStr); +end; + +// AnsiString ݽ MD5 +function MD5StringA(const Str: AnsiString): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, PAnsiChar(Str), Length(Str)); + MD5Final(Context, Result); +end; + +// WideString ݽ MD5 +function MD5StringW(const Str: WideString): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5UpdateW(Context, PWideChar(Str), Length(Str)); + MD5Final(Context, Result); +end; + +// UnicodeString ݽֱӵ MD5 㣬ת +{$IFDEF UNICODE} +function MD5UnicodeString(const Str: string): TCnMD5Digest; +{$ELSE} +function MD5UnicodeString(const Str: WideString): TCnMD5Digest; +{$ENDIF} +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + MD5Final(Context, Result); +end; + +// ָļݽ MD5 +function MD5File(const FileName: string; + CallBack: TCnMD5CalcProgressFunc): TCnMD5Digest; +var +{$IFDEF MSWINDOWS} + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; + Context: TCnMD5Context; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; + + function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} + var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec : Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then Exit; + try + if not GetFileInformationByHandle(H, Info) then Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} + end; + +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalMD5Stream(Stream, 4096 * 1024, Result, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + MD5Init(Context); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + MD5Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + MD5Final(Context, Result); +{$ENDIF} + end; +end; + +// ָ MD5 +function MD5Stream(Stream: TStream; + CallBack: TCnMD5CalcProgressFunc = nil): TCnMD5Digest; +begin + InternalMD5Stream(Stream, 4096 * 1024, Result, CallBack); +end; + +// ʮƸʽ MD5 Ӵֵ +function MD5Print(const Digest: TCnMD5Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnMD5Digest)); +end; + +// Ƚ MD5 ӴֵǷ +function MD5Match(const D1, D2: TCnMD5Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnMD5Digest)); +end; + +// MD5 Ӵֵת string +function MD5DigestToStr(const Digest: TCnMD5Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnMD5Digest)); +end; + +procedure MD5HmacInit(var Ctx: TCnMD5Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnMD5Digest; +begin + if KeyLength > HMAC_MD5_BLOCK_SIZE_BYTE then + begin + Sum := MD5Buffer(Key, KeyLength); + KeyLength := HMAC_MD5_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Ctx.Ipad, HMAC_MD5_BLOCK_SIZE_BYTE, $36); + FillChar(Ctx.Opad, HMAC_MD5_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Ctx.Ipad[I] := Byte(Ctx.Ipad[I] xor Byte(Key[I])); + Ctx.Opad[I] := Byte(Ctx.Opad[I] xor Byte(Key[I])); + end; + + MD5Init(Ctx); + MD5Update(Ctx, @(Ctx.Ipad[0]), HMAC_MD5_BLOCK_SIZE_BYTE); +end; + +procedure MD5HmacUpdate(var Ctx: TCnMD5Context; Input: PAnsiChar; Length: Cardinal); +begin + MD5Update(Ctx, Input, Length); +end; + +procedure MD5HmacFinal(var Ctx: TCnMD5Context; var Output: TCnMD5Digest); +var + Len: Integer; + TmpBuf: TCnMD5Digest; +begin + Len := HMAC_MD5_OUTPUT_LENGTH_BYTE; + MD5Final(Ctx, TmpBuf); + MD5Init(Ctx); + MD5Update(Ctx, @(Ctx.Opad[0]), HMAC_MD5_BLOCK_SIZE_BYTE); + MD5Update(Ctx, @(TmpBuf[0]), Len); + MD5Final(Ctx, Output); +end; + +procedure MD5Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnMD5Digest); +var + Ctx: TCnMD5Context; +begin + MD5HmacInit(Ctx, Key, KeyByteLength); + MD5HmacUpdate(Ctx, Input, ByteLength); + MD5HmacFinal(Ctx, Output); +end; + +end. diff --git a/CnPack/Crypto/CnNative.dcu b/CnPack/Crypto/CnNative.dcu new file mode 100644 index 0000000000000000000000000000000000000000..6b75b118ea19893f0e12fe282c3f47c9989c3dbf GIT binary patch literal 48972 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 literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnNative.pas b/CnPack/Crypto/CnNative.pas new file mode 100644 index 0000000..972f9e4 --- /dev/null +++ b/CnPack/Crypto/CnNative.pas @@ -0,0 +1,4904 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnNative; +{* |
+================================================================================
+* ƣCnPack 
+* Ԫƣ32 λ 64 λƽ̨һЩͳһԼһʵֵԪ
+* ԪߣCnPack  (master@cnpack.org)
+*     עԪһ 32 λ 64 λƽ̨һЩͳһʵ֡
+*           Delphi XE 2 ֧ 32  64 ų NativeInt  NativeUInt 
+*           ǰ 32 λ 64 ̬仯Ӱ쵽 PointerReferenceȶ
+*           ǵԣ̶ȵ 32 λ Cardinal/Integer Ⱥ Pointer Щ
+*           ͨˣʹ 32 λҲֹ˱Ԫ˼ͣ
+*           ͬʱڵͰ汾͸߰汾 Delphi ʹá
+*
+*           ԪҲڲ֧ UInt64 ı Delphi 5/6/7  Int64 ģ UInt64
+*           ĸ㣬ӼȻ֧֣˳Ҫģ div  mod
+*           ַ Integer(APtr)  64 λ MacOS ׳ֽضϣҪ NativeInt
+*
+*           ʵ˴Сءֽת̶ʱȷĴײ㺯빤ࡣ
+*
+* ƽ̨PWin2000 + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6/7 XE 2
+*   õԪеַϱػʽ
+* ޸ļ¼2023.08.14 V2.4
+*               ϼʱ̶ĺ
+*           2022.11.11 V2.3
+*               ϼ޷ֽ˳
+*           2022.07.23 V2.2
+*               Ӽڴλ㺯תַΪ CnNative
+*           2022.06.08 V2.1
+*               ĸʱ̶ĽԼڴ浹ź
+*           2022.03.14 V2.0
+*               Ӽʮת
+*           2022.02.17 V1.9
+*                FPC ı֧
+*           2022.02.09 V1.8
+*               ڵĴСжϺ
+*           2021.09.05 V1.7
+*                Int64/UInt64 㺯
+*           2020.10.28 V1.6
+*                UInt64 صж㺯
+*           2020.09.06 V1.5
+*                UInt64 ƽĺ
+*           2020.07.01 V1.5
+*               ж 32 λ 64 λ޷Ƿĺ
+*           2020.06.20 V1.4
+*                32 λ 64 λȡ͵ 1 λλõĺ
+*           2020.01.01 V1.3
+*                32 λ޷͵ mul 㣬ڲ֧ UInt64 ϵͳ Int64 Ա
+*           2018.06.05 V1.2
+*                64 λ͵ div/mod 㣬ڲ֧ UInt64 ϵͳ Int64  
+*           2016.09.27 V1.1
+*                64 λ͵һЩ
+*           2011.07.06 V1.0
+*               Ԫʵֹ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + Classes, SysUtils, SysConst, Math {$IFDEF COMPILER5}, Windows {$ENDIF}; + // D5 Ҫ Windows е PByte +type + ECnNativeException = class(Exception); + {* Native 쳣} + +{$IFDEF COMPILER5} + PCardinal = ^Cardinal; + {* D5 System Ԫδ壬} + PByte = Windows.PByte; + {* D5 PByte Windows У汾 System У + ͳһһ¹ʹ PByte ʱ uses Windowsڿƽ̨} +{$ENDIF} + +{$IFDEF BCB5OR6} + PInt64 = ^Int64; + {* C++Builder 5/6 sysmac.h û PInt64 Ķ壨е PUINT64 Сдͬ㣩} +{$ENDIF} + +{$IFDEF SUPPORT_32_AND_64} + TCnNativeInt = NativeInt; + TCnNativeUInt = NativeUInt; + TCnNativePointer = NativeInt; + TCnNativeIntPtr = PNativeInt; + TCnNativeUIntPtr = PNativeUInt; +{$ELSE} + TCnNativeInt = Integer; + TCnNativeUInt = Cardinal; + TCnNativePointer = Integer; + TCnNativeIntPtr = PInteger; + TCnNativeUIntPtr = PCardinal; +{$ENDIF} + +{$IFDEF CPU64BITS} + TCnUInt64 = NativeUInt; + TCnInt64 = NativeInt; +{$ELSE} + {$IFDEF SUPPORT_UINT64} + TCnUInt64 = UInt64; + {$ELSE} + TCnUInt64 = packed record // ֻĽṹ + case Boolean of + True: (Value: Int64); + False: (Lo32, Hi32: Cardinal); + end; + {$ENDIF} + TCnInt64 = Int64; +{$ENDIF} + +// TUInt64 cnvcl в֧ UInt64 div mod +{$IFDEF SUPPORT_UINT64} + TUInt64 = UInt64; + {$IFNDEF SUPPORT_PUINT64} + PUInt64 = ^UInt64; + {$ENDIF} +{$ELSE} + TUInt64 = Int64; + PUInt64 = ^TUInt64; +{$ENDIF} + +{$IFNDEF SUPPORT_INT64ARRAY} + // ϵͳûж Int64Array + Int64Array = array[0..$0FFFFFFE] of Int64; + PInt64Array = ^Int64Array; +{$ENDIF} + + TUInt64Array = array of TUInt64; // ̬ƺ׺;̬гͻ + + ExtendedArray = array[0..65537] of Extended; + PExtendedArray = ^ExtendedArray; + + PCnWord16Array = ^TCnWord16Array; + TCnWord16Array = array [0..0] of Word; + +{$IFDEF POSIX64} + TCnLongWord32 = Cardinal; // Linux64/MacOS64 (or POSIX64?) LongWord is 64 Bits +{$ELSE} + TCnLongWord32 = LongWord; +{$ENDIF} + PCnLongWord32 = ^TCnLongWord32; + + TCnLongWord32Array = array [0..MaxInt div SizeOf(Integer) - 1] of TCnLongWord32; + + PCnLongWord32Array = ^TCnLongWord32Array; + +{$IFNDEF TBYTES_DEFINED} + TBytes = array of Byte; + {* ޷ֽڶ̬飬δʱ} +{$ENDIF} + + TShortInts = array of ShortInt; + {* зֽڶ̬} + + TSmallInts = array of SmallInt; + {* з˫ֽڶ̬} + + TWords = array of Word; + {* ޷˫ֽڶ̬} + + TIntegers = array of Integer; + {* зֽڶ̬} + + TCardinals = array of Cardinal; + {* ޷ֽڶ̬} + + PCnByte = ^Byte; + PCnWord = ^Word; + + TCnBitOperation = (boAnd, boOr, boXor, boNot); + {* λ} + +type + TCnMemSortCompareProc = function (P1, P2: Pointer; ElementByteSize: Integer): Integer; + {* ڴ̶ߴȽϺԭ} + +const + CN_MAX_SQRT_INT64: Cardinal = 3037000499; + CN_MAX_INT8: ShortInt = $7F; + CN_MIN_INT8: ShortInt = -128; + CN_MAX_INT16: SmallInt = $7FFF; + CN_MIN_INT16: SmallInt = -32768; + CN_MAX_INT32: Integer = $7FFFFFFF; + CN_MIN_INT32: Integer = $80000000; // 뾯棬 -2147483648 + CN_MIN_INT32_IN_INT64: Int64 = $0000000080000000; + CN_MAX_INT64: Int64 = $7FFFFFFFFFFFFFFF; + CN_MIN_INT64: Int64 = $8000000000000000; + CN_MAX_UINT8: Byte = $FF; + CN_MAX_UINT16: Word = $FFFF; + CN_MAX_UINT32: Cardinal = $FFFFFFFF; + CN_MAX_TUINT64: TUInt64 = $FFFFFFFFFFFFFFFF; + CN_MAX_SIGNED_INT64_IN_TUINT64: TUInt64 = $7FFFFFFFFFFFFFFF; + +{* + D567 Ȳ֧ UInt64 ıȻ Int64 UInt64 мӼ洢 + ˳޷ֱɣװ System е _lludiv _llumod + ʵ Int64 ʾ UInt64 ݵ div mod ܡ +} +function UInt64Mod(A: TUInt64; B: TUInt64): TUInt64; +{* 64 λ޷ࡣ + + + A: TUInt64 - + B: TUInt64 - + + ֵTUInt64 - +} + +function UInt64Div(A: TUInt64; B: TUInt64): TUInt64; +{* 64 λ޷ + + + A: TUInt64 - + B: TUInt64 - + + ֵTUInt64 - +} + +function UInt64Mul(A: Cardinal; B: Cardinal): TUInt64; +{* 32 λ޷ˡڲ֧ UInt64 ƽ̨ϣ UInt64 ʽ Int64  + ֱʹ Int64 п + + + A: Cardinal - һ + B: Cardinal - + + ֵTUInt64 - +} + +procedure UInt64AddUInt64(A: TUInt64; B: TUInt64; var ResLo: TUInt64; var ResHi: TUInt64); +{* 64 λ޷ӣ ResLo ResHi С + עڲʵְ㷨ΪӣʵResHi Ȼ 1ֱж 1 + + + A: TUInt64 - һ + B: TUInt64 - + var ResLo: TUInt64 - ͵λ + var ResHi: TUInt64 - ͸λ + + ֵޣ +} + +procedure UInt64MulUInt64(A: TUInt64; B: TUInt64; var ResLo: TUInt64; var ResHi: TUInt64); +{* 64 λ޷ˣ ResLo ResHi СWin 64 λûʵ֣Լһϡ + + + A: TUInt64 - һ + B: TUInt64 - + var ResLo: TUInt64 - λ + var ResHi: TUInt64 - λ + + ֵޣ +} + +function UInt64ToHex(N: TUInt64): string; +{* 64 λ޷תΪʮַ + + + N: TUInt64 - תֵ + + ֵstring - ʮַ +} + +function UInt64ToStr(N: TUInt64): string; +{* 64 λ޷תΪʮַ + + + N: TUInt64 - תֵ + + ֵstring - ʮַ +} + +function StrToUInt64(const S: string): TUInt64; +{* ַתΪ 64 λ޷ + + + const S: string - תַ + + ֵTUInt64 - ת +} + +function UInt64Compare(A: TUInt64; B: TUInt64): Integer; +{* Ƚ 64 λ޷ֱֵݱȽϵĽǴڡڻС 10-1 + + + A: TUInt64 - Ƚϵһ + B: TUInt64 - Ƚϵ + + ֵInteger - رȽϽ +} + +function UInt64Sqrt(N: TUInt64): TUInt64; +{* 64 λ޷ƽ֡ + + + N: TUInt64 - ƽ + + ֵTUInt64 - ƽ +} + +function UInt32IsNegative(N: Cardinal): Boolean; +{* ж 32 λ޷ 32 λзʱǷС 0 + + + N: Cardinal - жϵֵ + + ֵBoolean - ǷС 0 +} + +function UInt64IsNegative(N: TUInt64): Boolean; +{* ж 64 λ޷ 64 λзʱǷС 0 + + + N: TUInt64 - жϵֵ + + ֵBoolean - ǷС 0 +} + +procedure UInt64SetBit(var B: TUInt64; Index: Integer); +{* 64 λijһλ 1λ Index 0 ʼ 63 + + + var B: TUInt64 - λֵ + Index: Integer - 1 λ + + ֵޣ +} + +procedure UInt64ClearBit(var B: TUInt64; Index: Integer); +{* 64 λijһλ 0λ Index 0 ʼ 63 + + + var B: TUInt64 - λֵ + Index: Integer - 0 λ + + ֵޣ +} + +function GetUInt64BitSet(B: TUInt64; Index: Integer): Boolean; +{* 64 λijһλǷ 1λ Index 0 ʼ 63 + + + B: TUInt64 - жϵֵ + Index: Integer - жϵλ + + ֵBoolean - ظλǷ 1 +} + +function GetUInt64HighBits(B: TUInt64): Integer; +{* 64 λ 1 ߶λǵڼλλ 0û 1 -1 + + + B: TUInt64 - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt32HighBits(B: Cardinal): Integer; +{* 32 λ 1 ߶λǵڼλλ 0û 1 -1 + + + B: Cardinal - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt16HighBits(B: Word): Integer; +{* 16 λ 1 ߶λǵڼλλ 0û 1 -1 + + + B: Word - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt8HighBits(B: Byte): Integer; +{* 8 λ 1 ߶λǵڼλλ 0û 1 -1 + + + B: Byte - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt64LowBits(B: TUInt64): Integer; +{* 64 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 + + + B: TUInt64 - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt32LowBits(B: Cardinal): Integer; +{* 32 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 + + + B: Cardinal - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt16LowBits(B: Word): Integer; +{* 16 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 + + + B: Word - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt8LowBits(B: Byte): Integer; +{* 8 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 + + + B: Byte - жϵֵ + + ֵInteger - 1 λ +} + +function Int64Mod(M: Int64; N: Int64): Int64; +{* װ Int64 ModM ֵʱȡģģ N Ҫס + + + M: Int64 - + N: Int64 - + + ֵInt64 - +} + +function IsUInt32PowerOf2(N: Cardinal): Boolean; +{* жһ 32 λ޷Ƿ 2 ݡ + + + N: Cardinal - жϵֵ + + ֵBoolean - Ƿ 2 +} + +function IsUInt64PowerOf2(N: TUInt64): Boolean; +{* жһ 64 λ޷Ƿ 2 ݡ + + + N: TUInt64 - жϵֵ + + ֵBoolean - Ƿ 2 +} + +function GetUInt32PowerOf2GreaterEqual(N: Cardinal): Cardinal; +{* õһָ 32 λ޷ȵ 2 ݣ򷵻 0 + + + N: Cardinal - ֵ + + ֵCardinal - ط 2 ݻ 0 +} + +function GetUInt64PowerOf2GreaterEqual(N: TUInt64): TUInt64; +{* õһָ 64 λ޷ȵ 2 ݣ򷵻 0 + + + N: TUInt64 - ֵ + + ֵTUInt64 - ط 2 ݻ 0 +} + +function IsInt32AddOverflow(A: Integer; B: Integer): Boolean; +{* ж 32 λзǷ 32 λзޡ + + + A: Integer - һ + B: Integer - + + ֵBoolean - Ƿ +} + +function IsUInt32AddOverflow(A: Cardinal; B: Cardinal): Boolean; +{* ж 32 λ޷Ƿ 32 λ޷ޡ + + + A: Cardinal - һ + B: Cardinal - + + ֵBoolean - Ƿ +} + +function IsInt64AddOverflow(A: Int64; B: Int64): Boolean; +{* ж 64 λзǷ 64 λзޡ + + + A: Int64 - һ + B: Int64 - + + ֵBoolean - Ƿ +} + +function IsUInt64AddOverflow(A: TUInt64; B: TUInt64): Boolean; +{* ж 64 λ޷Ƿ 64 λ޷ޡ + + + A: TUInt64 - һ + B: TUInt64 - + + ֵBoolean - Ƿ +} + +function IsUInt64SubOverflowInt32(A: TUInt64; B: TUInt64): Boolean; +{* жһ 64 λ޷ȥһ 64 λ޷ĽǷ񳬳 32 λзΧ + 64 λе JMP תжϡ + + + A: TUInt64 - + B: TUInt64 - + + ֵBoolean - Ƿ񳬳 32 λзΧ +} + +procedure UInt64Add(var R: TUInt64; A: TUInt64; B: TUInt64; out Carry: Integer); +{* 64 λ޷ӣA + B => R 1 ýλλ㡣 + + + var R: TUInt64 - + A: TUInt64 - һ + B: TUInt64 - + out Carry: Integer - λ + + ֵޣ +} + +procedure UInt64Sub(var R: TUInt64; A: TUInt64; B: TUInt64; out Carry: Integer); +{* 64 λ޷A - B => Rнλ 1 ýλλ㡣 + + + var R: TUInt64 - + A: TUInt64 - + B: TUInt64 - + out Carry: Integer - λ + + ֵޣ +} + +function IsInt32MulOverflow(A: Integer; B: Integer): Boolean; +{* ж 32 λзǷ 32 λзޡ + + + A: Integer - һ + B: Integer - + + ֵBoolean - Ƿ +} + +function IsUInt32MulOverflow(A: Cardinal; B: Cardinal): Boolean; +{* ж 32 λ޷Ƿ 32 λ޷ + + + A: Cardinal - һ + B: Cardinal - + + ֵBoolean - Ƿ +} + +function IsUInt32MulOverflowInt64(A: Cardinal; B: Cardinal; out R: TUInt64): Boolean; +{* ж 32 λ޷Ƿ 64 λзޣδҲ False ʱR ֱӷؽ + Ҳ TrueҪµ UInt64Mul ʵʩˡ + + + A: Cardinal - һ + B: Cardinal - + out R: TUInt64 - δʱػ + + ֵBoolean - Ƿ +} + +function IsInt64MulOverflow(A: Int64; B: Int64): Boolean; +{* ж 64 λзǷ 64 λзޡ + + + A: Int64 - һ + B: Int64 - + + ֵBoolean - Ƿ +} + +function PointerToInteger(P: Pointer): Integer; +{* ָת֧ͣ 32/64 λע 64 λ¿ܻᶪ 32 λݡ + + + P: Pointer - תָ + + ֵInteger - ת +} + +function IntegerToPointer(I: Integer): Pointer; +{* תָ֧ͣ 32/64 λ + + + I: Integer - ת + + ֵPointer - תָ +} + +function Int64NonNegativeAddMod(A: Int64; B: Int64; N: Int64): Int64; +{* 64 λзΧĺ࣬Ҫ N 0 + + + A: Int64 - һ + B: Int64 - һ + N: Int64 - ģ + + ֵInt64 - Ľ +} + +function UInt64NonNegativeAddMod(A: TUInt64; B: TUInt64; N: TUInt64): TUInt64; +{* 64 λ޷Χĺ࣬Ҫ N 0 + + + A: TUInt64 - һ + B: TUInt64 - + N: TUInt64 - ģ + + ֵTUInt64 - Ľ +} + +function Int64NonNegativeMulMod(A: Int64; B: Int64; N: Int64): Int64; +{* 64 λзΧڵֱ࣬Ӽ㣬Ҫ N 0 + + + A: Int64 - һ + B: Int64 - + N: Int64 - ģ + + ֵInt64 - Ľ +} + +function UInt64NonNegativeMulMod(A: TUInt64; B: TUInt64; N: TUInt64): TUInt64; +{* 64 λ޷Χڵֱ࣬Ӽ㣬 + + + A: TUInt64 - һ + B: TUInt64 - + N: TUInt64 - ģ + + ֵTUInt64 - Ľ +} + +function Int64NonNegativeMod(N: Int64; P: Int64): Int64; +{* װ 64 λзķǸຯҲΪʱӸ豣֤ P 0 + + + N: Int64 - + P: Int64 - + + ֵInt64 - طǸĽ +} + +function Int64NonNegativPower(N: Int64; Exp: Integer): Int64; +{* 64 λзķǸָݣ + + + N: Int64 - + Exp: Integer - ָҪ 0 + + ֵInt64 - ݵĽ +} + +function Int64NonNegativeRoot(N: Int64; Exp: Integer): Int64; +{* 64 λзķǸη֣ + + + N: Int64 - + Exp: Integer - + + ֵInt64 - ؿֽ +} + +function UInt64NonNegativPower(N: TUInt64; Exp: Integer): TUInt64; +{* 64 λ޷ķǸָݣ + + + N: TUInt64 - + Exp: Integer - ָҪ 0 + + ֵTUInt64 - ݵĽ +} + +function UInt64NonNegativeRoot(N: TUInt64; Exp: Integer): TUInt64; +{* 64 λ޷ķǸη֣ + + + N: TUInt64 - + Exp: Integer - + + ֵTUInt64 - ؿֽ +} + +function CurrentByteOrderIsBigEndian: Boolean; +{* صǰڻǷǴˣҲǷеĸֽڴ洢ڽϵ͵ʼַ + ϴҵĶϰߣ粿ָ ARM MIPS + + + ޣ + + ֵBoolean - صǰڻǷǴ +} + +function CurrentByteOrderIsLittleEndian: Boolean; +{* صǰڻǷСˣҲǷеĸֽڴ洢ڽϸߵʼַ x86 벿Ĭ ARM + + + ޣ + + ֵBoolean - صǰڻǷС +} + +function Int64ToBigEndian(Value: Int64): Int64; +{* ȷ 64 λзֵΪˣС˻лת + + + Value: Int64 - ת 64 λз + + ֵInt64 - شֵ +} + +function Int32ToBigEndian(Value: Integer): Integer; +{* ȷ 32 λзֵΪˣС˻лת + + + Value: Integer - ת 32 λз + + ֵInteger - شֵ +} + +function Int16ToBigEndian(Value: SmallInt): SmallInt; +{* ȷ 16 λзֵΪˣС˻лת + + + Value: SmallInt - ת 16 λз + + ֵSmallInt - شֵ +} + +function Int64ToLittleEndian(Value: Int64): Int64; +{* ȷ 64 λзֵΪСˣڴ˻лת + + + Value: Int64 - ת 64 λз + + ֵInt64 - شֵ +} + +function Int32ToLittleEndian(Value: Integer): Integer; +{* ȷ 32 λзֵΪСˣڴ˻лת + + + Value: Integer - ת 32 λз + + ֵInteger - Сֵ +} + +function Int16ToLittleEndian(Value: SmallInt): SmallInt; +{* ȷ 16 λзֵΪСˣڴ˻лת + + + Value: SmallInt - ת 16 λз + + ֵSmallInt - Сֵ +} + +function UInt64ToBigEndian(Value: TUInt64): TUInt64; +{* ȷ 64 λ޷ֵΪˣС˻лת + + + Value: TUInt64 - ת 64 λ޷ + + ֵTUInt64 - شֵ +} + +function UInt32ToBigEndian(Value: Cardinal): Cardinal; +{* ȷ 32 λ޷ֵΪˣС˻лת + + + Value: Cardinal - ת 32 λ޷ + + ֵCardinal - شֵ +} + +function UInt16ToBigEndian(Value: Word): Word; +{* ȷ 16 λ޷ֵΪˣС˻лת + + + Value: Word - ת 16 λ޷ + + ֵWord - شֵ +} + +function UInt64ToLittleEndian(Value: TUInt64): TUInt64; +{* ȷ 64 λ޷ֵΪСˣڴ˻лת + + + Value: TUInt64 - ת 64 λ޷ + + ֵTUInt64 - شֵ +} + +function UInt32ToLittleEndian(Value: Cardinal): Cardinal; +{* ȷ 32 λ޷ֵΪСˣڴ˻лת + + + Value: Cardinal - ת 32 λ޷ + + ֵCardinal - Сֵ +} + +function UInt16ToLittleEndian(Value: Word): Word; +{* ȷ 16 λ޷ֵΪСˣڴ˻лת + + + Value: Word - ת 16 λ޷ + + ֵWord - Сֵ +} + +function Int64HostToNetwork(Value: Int64): Int64; +{* 64 λзֵֽ˳תΪֽ˳С˻лת + + + Value: Int64 - ת 64 λз + + ֵInt64 - ֽ˳ֵ +} + +function Int32HostToNetwork(Value: Integer): Integer; +{* 32 λзֵֽ˳תΪֽ˳С˻лת + + + Value: Integer - ת 32 λз + + ֵInteger - ֽ˳ֵ +} + +function Int16HostToNetwork(Value: SmallInt): SmallInt; +{* 16 λзֵֽ˳תΪֽ˳С˻лת + + + Value: SmallInt - ת 16 λз + + ֵSmallInt - ֽ˳ֵ +} + +function Int64NetworkToHost(Value: Int64): Int64; +{* 64 λзֵֽ˳תΪֽ˳С˻лת + + + Value: Int64 - ת 64 λз + + ֵInt64 - ֽ˳ֵ +} + +function Int32NetworkToHost(Value: Integer): Integer; +{* 32 λзֵֽ˳תΪֽ˳С˻лת + + + Value: Integer - ת 32 λз + + ֵInteger - ֽ˳ֵ +} + +function Int16NetworkToHost(Value: SmallInt): SmallInt; +{* 16 λзֵֽ˳תΪֽ˳С˻лת + + + Value: SmallInt - ת 16 λз + + ֵSmallInt - ֽ˳ֵ +} + +function UInt64HostToNetwork(Value: TUInt64): TUInt64; +{* 64 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: TUInt64 - ת 64 λ޷ + + ֵTUInt64 - ֽ˳ֵ +} + +function UInt32HostToNetwork(Value: Cardinal): Cardinal; +{* 32 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: Cardinal - ת 32 λ޷ + + ֵCardinal - ֽ˳ֵ +} + +function UInt16HostToNetwork(Value: Word): Word; +{* 16 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: Word - ת 16 λ޷ + + ֵWord - ֽ˳ֵ +} + +function UInt64NetworkToHost(Value: TUInt64): TUInt64; +{* 64 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: TUInt64 - ת 64 λ޷ + + ֵTUInt64 - ֽ˳ֵ +} + +function UInt32NetworkToHost(Value: Cardinal): Cardinal; +{* 32 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: Cardinal - ת 32 λ޷ + + ֵCardinal - ֽ˳ֵ +} + +function UInt16NetworkToHost(Value: Word): Word; +{* 16 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: Word - ת 16 λ޷ + + ֵWord - ֽ˳ֵ +} + +procedure MemoryNetworkToHost(Mem: Pointer; MemByteLen: Integer); +{* һƬڴֽ˳תΪֽ˳С˻лת + ÷ӦóϽ٣¶ġֽתѾ㹻 + + + Mem: Pointer - תݿַ + MemByteLen: Integer - תݿֽڳ + + ֵޣ +} + +procedure MemoryHostToNetwork(Mem: Pointer; MemByteLen: Integer); +{* һƬڴֽ˳תΪֽ˳С˻лת + ÷ӦóϽ٣¶ġֽתѾ㹻 + + + Mem: Pointer - תݿַ + MemByteLen: Integer - תݿֽڳ + + ֵޣ +} + +procedure ReverseMemory(Mem: Pointer; MemByteLen: Integer); +{* ֽ˳һڴ飬ֽڲ䡣 + + + Mem: Pointer - õݿַ + MemByteLen: Integer - õݿֽڳ + + ֵޣ +} + +function ReverseBitsInInt8(V: Byte): Byte; +{* һֽڲλݡ + + + V: Byte - õһֽ + + ֵByte - صֵ +} + +function ReverseBitsInInt16(V: Word): Word; +{* öֽڼڲλݡ + + + V: Word - õĶֽ + + ֵWord - صֵ +} + +function ReverseBitsInInt32(V: Cardinal): Cardinal; +{* ֽڼڲλݡ + + + V: Cardinal - õֽ + + ֵCardinal - صֵ +} + +function ReverseBitsInInt64(V: Int64): Int64; +{* ðֽڼڲλݡ + + + V: Int64 - õİֽ + + ֵInt64 - صֵ +} + +procedure ReverseMemoryWithBits(Mem: Pointer; MemByteLen: Integer); +{* ֽ˳һڴ飬ÿֽҲ + + + Mem: Pointer - õݿַ + MemByteLen: Integer - õݿֽڳ + + ֵޣ +} + +procedure MemoryAnd(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +{* 鳤ͬڴ AMem BMem λ룬 ResMem У߿ͬ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + ResMem: Pointer - ݿַ + + ֵޣ +} + +procedure MemoryOr(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +{* 鳤ͬڴ AMem BMem λ򣬽 ResMem У߿ͬ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + ResMem: Pointer - ݿַ + + ֵޣ +} + +procedure MemoryXor(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +{* 鳤ͬڴ AMem BMem λ򣬽 ResMem У߿ͬ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + ResMem: Pointer - ݿַ + + ֵޣ +} + +procedure MemoryNot(Mem: Pointer; MemByteLen: Integer; ResMem: Pointer); +{* һڴ AMem ȡ ResMem У߿ͬ + + + Mem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + ResMem: Pointer - ݿַ + + ֵޣ +} + +procedure MemoryShiftLeft(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; BitCount: Integer); +{* AMem ڴ BitCount λ BMemڴַλƣλ 0߿ȡ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + BitCount: Integer - Ƶλ + + ֵޣ +} + +procedure MemoryShiftRight(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; BitCount: Integer); +{* AMem ڴ BitCount λ BMemڴַλƣλ 0߿ȡ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + BitCount: Integer - Ƶλ + + ֵޣ +} + +function MemoryIsBitSet(Mem: Pointer; N: Integer): Boolean; +{* ڴij Bit λǷ 1ڴַλ 0ֽڻұΪ 0 + + + Mem: Pointer - ݿַ + N: Integer - λ + + ֵBoolean - Ƿ 1 +} + +procedure MemorySetBit(Mem: Pointer; N: Integer); +{* ڴij Bit λ 1ڴַλ 0ֽڻұΪ 0 + + + Mem: Pointer - ݿַ + N: Integer - λ + + ֵޣ +} + +procedure MemoryClearBit(Mem: Pointer; N: Integer); +{* ڴij Bit λ 0ڴַλ 0ֽڻұΪ 0 + + + Mem: Pointer - ݿַ + N: Integer - λ + + ֵޣ +} + +function MemoryToBinStr(Mem: Pointer; MemByteLen: Integer; Sep: Boolean = False): string; +{* һڴݴӵ͵ֽ˳ΪַSep ʾֽ֮Ƿոָ + + + Mem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + Sep: Boolean - ֽ֮Ƿÿոָ + + ֵstring - ضַ +} + +procedure MemorySwap(AMem: Pointer; BMem: Pointer; MemByteLen: Integer); +{* ͬȵڴݣͬڴʲô + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + + ֵޣ +} + +function MemoryCompare(AMem: Pointer; BMem: Pointer; MemByteLen: Integer): Integer; +{* ޷ķʽȽڴ棬 10-1ͬڴֱӷ 0 + + + AMem: Pointer - Ƚϵݿַһ + BMem: Pointer - Ƚϵݿַ + MemByteLen: Integer - Ƚϵݿֽڳ + + ֵInteger - رȽϵĽ +} + +procedure MemoryQuickSort(Mem: Pointer; ElementByteSize: Integer; + ElementCount: Integer; CompareProc: TCnMemSortCompareProc = nil); +{* Թ̶СԪص + + + Mem: Pointer - ݿַ + ElementByteSize: Integer - Ԫֽڳ + ElementCount: Integer - ݿԪصĸ + CompareProc: TCnMemSortCompareProc - ԪرȽϵĻص + + ֵޣ +} + +function UInt8ToBinStr(V: Byte): string; +{* һ 8 λ޷תΪַ + + + V: Byte - ת 8 λ޷ + + ֵstring - ضַ +} + +function UInt16ToBinStr(V: Word): string; +{* һ 16 λ޷תΪַ + + + V: Word - ת 16 λ޷ + + ֵstring - ضַ +} + +function UInt32ToBinStr(V: Cardinal): string; +{* һ 32 λ޷תΪַ + + + V: Cardinal - ת 32 λ޷ + + ֵstring - ضַ +} + +function UInt32ToStr(V: Cardinal): string; +{* һ 32 λ޷תΪʮַ + + + V: Cardinal - ת 32 λ޷ + + ֵstring - ʮַ +} + +function UInt64ToBinStr(V: TUInt64): string; +{* һ 64 λ޷תΪַ + + + V: TUInt64 - ת 64 λ޷ + + ֵstring - ضַ +} + +function HexToInt(const Hex: string): Integer; overload; +{* һʮַתΪͣʺϽ϶ 2 ַַ + + + const Hex: string - תʮַ + + ֵInteger - +} + +function HexToInt(Hex: PChar; CharLen: Integer): Integer; overload; +{* һʮַָָתΪͣʺϽ϶ 2 ַַ + + + Hex: PChar - תʮַַ + CharLen: Integer - ַ + + ֵInteger - +} + +function IsHexString(const Hex: string): Boolean; +{* жһַǷϷʮִַСд + + + const Hex: string - жϵʮַ + + ֵBoolean - ǷǺϷʮַ +} + +function DataToHex(InData: Pointer; ByteLength: Integer; UseUpperCase: Boolean = True): string; +{* ڴתΪʮַڴλݳַ󷽣൱ֽ˳ + UseUpperCase ݵĴСд + + + InData: Pointer - תݿַ + ByteLength: Integer - תݿֽڳ + UseUpperCase: Boolean - ʮַڲǷд + + ֵstring - ʮַ +} + +function HexToData(const Hex: string; OutData: Pointer = nil): Integer; +{* ʮַתΪڴ飬ַ󷽵ݳڴλ൱ֽ˳ + ʮַΪתʧʱ׳쳣תɹֽ + ע OutData Ӧָ㹻תݵֽڳΪ Length(Hex) div 2 + nilֻֽڳȣʽת + + + const Hex: string - תʮַ + OutData: Pointer - ֽڳӦΪ Length(Hex) div 2 + + ֵInteger - תֽڳ +} + +function StringToHex(const Data: string; UseUpperCase: Boolean = True): string; +{* ַתΪʮַUseUpperCase ݵĴСд + + + const Data: string - תַ + UseUpperCase: Boolean - ʮַڲǷд + + ֵstring - תʮַ +} + +function HexToString(const Hex: string): string; +{* ʮַתΪַʮַΪתʧʱ׳쳣 + + + const Hex: string - תʮַ + + ֵstring - תַ +} + +function HexToAnsiStr(const Hex: AnsiString): AnsiString; +{* ʮַתΪַʮַΪתʧʱ׳쳣 + + + const Hex: AnsiString - תʮַ + + ֵAnsiString - תַ +} + +function AnsiStrToHex(const Data: AnsiString; UseUpperCase: Boolean = True): AnsiString; +{* AnsiString תΪʮַUseUpperCase ݵĴСд + + + const Data: AnsiString - תַ + UseUpperCase: Boolean - ʮַڲǷд + + ֵAnsiString - ʮַ +} + +function BytesToHex(Data: TBytes; UseUpperCase: Boolean = True): string; +{* ֽתΪʮַ±λݳַ󷽣൱ֽ˳ + UseUpperCase ݵĴСд + + + Data: TBytes - תֽ + UseUpperCase: Boolean - ʮַڲǷд + + ֵstring - ʮַ +} + +function HexToBytes(const Hex: string): TBytes; +{* ʮַתΪֽ飬ַߵݳ±λ൱ֽ˳ + ַΪתʧʱ׳쳣 + + + const Hex: string - תʮַ + + ֵTBytes - ½ֽ +} + +function StreamToHex(Stream: TStream; UseUpperCase: Boolean = True): string; +{* еȫݴͷתΪʮַ + + + Stream: TStream - + UseUpperCase: Boolean - ʮַڲǷд + + ֵstring - ʮַ +} + +function HexToStream(const Hex: string; Stream: TStream): Integer; +{* ʮַתдУдֽ + + + const Hex: string - תʮַ + Stream: TStream - д + + ֵInteger - дֽ +} + +procedure ReverseBytes(Data: TBytes); +{* ֽ˳һֽ顣 + + + Data: TBytes - õֽ + + ֵޣ +} + +function CloneBytes(Data: TBytes): TBytes; +{* һµֽ + + + Data: TBytes - Ƶֽ + + ֵTBytes - ½ֽ +} + +function StreamToBytes(Stream: TStream): TBytes; +{* ͷȫֽ飬½ֽ顣 + + + Stream: TStream - + + ֵTBytes - ½ֽ +} + +function BytesToStream(Data: TBytes; OutStream: TStream): Integer; +{* ֽдԭʼдֽ + + + Data: TBytes - дֽ + OutStream: TStream - д + + ֵInteger - дֽ +} + +function AnsiToBytes(const Str: AnsiString): TBytes; +{* AnsiString ֱתΪֽ飬롣 + + + const Str: AnsiString - תַ + + ֵTBytes - תֽ +} + +function BytesToAnsi(Data: TBytes): AnsiString; +{* ֱֽתΪ AnsiString롣 + + + Data: TBytes - תֽ + + ֵAnsiString - תַ +} + +function BytesToString(Data: TBytes): string; +{* ֽתΪ stringڲ Byte ֵΪ Char롣 + + + Data: TBytes - תֽ + + ֵstring - תַ +} + +function MemoryToString(Mem: Pointer; MemByteLen: Integer): string; +{* ڴתΪ stringڲֽڸֵ롣 + + + Mem: Pointer - תݿַ + MemByteLen: Integer - תݿֽڳ + + ֵstring - תַ +} + +function BitsToString(Bits: TBits): string; +{* λתΪ 0 1 ַ + + + Bits: TBits - תλ + + ֵstring - תַ +} + +function ConcatBytes(A: TBytes; B: TBytes): TBytes; +{* A B ֽ˳ƴ÷һֽ飬A B ֲ䡣 + + + A: TBytes - ƴӵֽһ + B: TBytes - ƴӵֽ + + ֵTBytes - ƴӵֽ +} + +function NewBytesFromMemory(Data: Pointer; DataByteLen: Integer): TBytes; +{* ½һֽ飬һƬڴݹ + + + Data: Pointer - ݿַ + DataByteLen: Integer - ݿֽڳ + + ֵTBytes - ½ֽ +} + +function CompareBytes(A: TBytes; B: TBytes): Boolean; overload; +{* ȽֽǷͬ + + + A: TBytes - Ƚϵֽһ + B: TBytes - Ƚϵֽ + + ֵBoolean - رȽϽǷͬ +} + +function CompareBytes(A: TBytes; B: TBytes; MaxLength: Integer): Boolean; overload; +{* Ƚֽǰ MaxLength ֽڵǷͬ + + + A: TBytes - Ƚϵֽһ + B: TBytes - Ƚϵֽ + MaxLength: Integer - Ƚϵֽ + + ֵBoolean - رȽϽǷͬ +} + +function MoveMost(const Source; var Dest; ByteLen: Integer; MostLen: Integer): Integer; +{* Source ƶ ByteLen Ҳ MostLen ֽڵ Dest Уʵƶֽ + ByteLen С MostLen Dest 0Ҫ Dest MostLen + + + const Source - ƶԴλáַ + var Dest - ƶĿλáַҪ MostLen ֽ + ByteLen: Integer - ƶֽ + MostLen: Integer - ƶֽ + + ֵInteger - ʵƶֽ +} + +// =============================== =================================== + +function SarInt8(var V: Byte; ShiftCount: Integer): Byte; +{* һ 8 λƣҲDZλơ + + + var V: Byte - Ƶ 8 λ + ShiftCount: Integer - Ƶλ + + ֵByte - λֵ +} + +function SarInt16(var V: Word; ShiftCount: Integer): Word; +{* һ 16 λƣҲDZλơ + + + var V: Word - Ƶ 16 λ + ShiftCount: Integer - Ƶλ + + ֵWord - λֵ +} + +function SarInt32(var V: Cardinal; ShiftCount: Integer): Cardinal; +{* һ 32 λƣҲDZλơ + + + var V: Cardinal - Ƶ 32 λ + ShiftCount: Integer - Ƶλ + + ֵCardinal - λֵ +} + +function SarInt64(var V: TUInt64; ShiftCount: Integer): TUInt64; +{* һ 64 λƣҲDZλơ + + + var V: TUInt64 - Ƶ 64 λ + ShiftCount: Integer - Ƶλ + + ֵTUInt64 - λֵ +} + +// ================ ִʱ̶ if жϵIJ߼ =============== + +procedure ConstTimeConditionalSwap8(CanSwap: Boolean; var A: Byte; var B: Byte); +{* 8 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B + + + CanSwap: Boolean - Ƿ񽻻 + var A: Byte - 8 λͱһ + var B: Byte - 8 λͱ + + ֵޣ +} + +procedure ConstTimeConditionalSwap16(CanSwap: Boolean; var A: Word; var B: Word); +{* 16 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B + + + CanSwap: Boolean - Ƿ񽻻 + var A: Word - 16 λͱһ + var B: Word - 16 λͱ + + ֵޣ +} + +procedure ConstTimeConditionalSwap32(CanSwap: Boolean; var A: Cardinal; var B: Cardinal); +{* 32 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B + + + CanSwap: Boolean - Ƿ񽻻 + var A: Cardinal - 32 λͱһ + var B: Cardinal - 32 λͱ + + ֵޣ +} + +procedure ConstTimeConditionalSwap64(CanSwap: Boolean; var A: TUInt64; var B: TUInt64); +{* 64 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B + + + CanSwap: Boolean - Ƿ񽻻 + var A: TUInt64 - 64 λͱһ + var B: TUInt64 - 64 λͱ + + ֵޣ +} + +function ConstTimeEqual8(A: Byte; B: Byte): Boolean; +{* ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True + + + A: Byte - Ƚϵ 8 λͱһ + B: Byte - Ƚϵ 8 λͱ + + ֵBoolean - Ƿ +} + +function ConstTimeEqual16(A: Word; B: Word): Boolean; +{* ˫ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True + + + A: Word - Ƚϵ 16 λͱһ + B: Word - Ƚϵ 16 λͱ + + ֵBoolean - Ƿ +} + +function ConstTimeEqual32(A: Cardinal; B: Cardinal): Boolean; +{* ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True + + + A: Cardinal - Ƚϵ 32 λͱһ + B: Cardinal - Ƚϵ 32 λͱ + + ֵBoolean - Ƿ +} + +function ConstTimeEqual64(A: TUInt64; B: TUInt64): Boolean; +{* ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True + + + A: TUInt64 - Ƚϵ 64 λͱһ + B: TUInt64 - Ƚϵ 64 λͱ + + ֵBoolean - Ƿ +} + +function ConstTimeBytesEqual(A: TBytes; B: TBytes): Boolean; +{* ͬȵִֽʱ̶ıȽϣͬʱ True + + + A: TBytes - Ƚϵֽһ + B: TBytes - Ƚϵֽ + + ֵBoolean - Ƿ +} + +function ConstTimeExpandBoolean8(V: Boolean): Byte; +{* V ֵ 8 λȫ 1 ȫ 0 + + + V: Boolean - Ƿ񷵻ȫ 1 + + ֵByte - $FF 0 +} + +function ConstTimeExpandBoolean16(V: Boolean): Word; +{* V ֵ 16 λȫ 1 ȫ 0 + + + V: Boolean - Ƿ񷵻ȫ 1 + + ֵWord - $FFFF 0 +} + +function ConstTimeExpandBoolean32(V: Boolean): Cardinal; +{* V ֵ 32 λȫ 1 ȫ 0 + + + V: Boolean - Ƿ񷵻ȫ 1 + + ֵCardinal - $FFFFFFFF 0 +} + +function ConstTimeExpandBoolean64(V: Boolean): TUInt64; +{* V ֵ 64 λȫ 1 ȫ 0 + + + V: Boolean - Ƿ񷵻ȫ 1 + + ֵTUInt64 - $FFFFFFFFFFFFFFFF 0 +} + +function ConstTimeConditionalSelect8(Condition: Boolean; A: Byte; B: Byte): Byte; +{* ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B + + + Condition: Boolean - Ƿѡ A ҲDzһ + A: Byte - ѡ 8 λһ + B: Byte - ѡ 8 λ + + ֵByte - ѡ 8 λ +} + +function ConstTimeConditionalSelect16(Condition: Boolean; A: Word; B: Word): Word; +{* ˫ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B + + + Condition: Boolean - Ƿѡ A ҲDzһ + A: Word - ѡ 16 λһ + B: Word - ѡ 16 λ + + ֵWord - ѡ 16 λ +} + +function ConstTimeConditionalSelect32(Condition: Boolean; A: Cardinal; B: Cardinal): Cardinal; +{* ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B + + + Condition: Boolean - Ƿѡ A ҲDzһ + A: Cardinal - ѡ 32 λһ + B: Cardinal - ѡ 32 λ + + ֵCardinal - ѡ 32 λ +} + +function ConstTimeConditionalSelect64(Condition: Boolean; A: TUInt64; B: TUInt64): TUInt64; +{* ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B + + + Condition: Boolean - Ƿѡ A ҲDzһ + A: TUInt64 - ѡ 64 λһ + B: TUInt64 - ѡ 64 λ + + ֵTUInt64 - ѡ 64 λ +} + +// ================ ִʱ̶ if жϵIJ߼ =============== + +{$IFDEF MSWINDOWS} + +// ĸΪ Intel ֻ֧࣬ 32 λ 64 λ Intel CPUӦCPUX86 CPUX64 + +procedure Int64DivInt32Mod(A: Int64; B: Integer; + var DivRes: Integer; var ModRes: Integer); +{* 64 λз 32 λз̷ DivRes ModRes + б֤ 32 λΧڣ쳣 + + + A: Int64 - + B: Integer - + var DivRes: Integer - + var ModRes: Integer - + + ֵޣ +} + +procedure UInt64DivUInt32Mod(A: TUInt64; B: Cardinal; + var DivRes: Cardinal; var ModRes: Cardinal); +{* 64 λ޷ 32 λ޷̷ DivRes ModRes + б֤ 32 λΧڣ쳣 + + + A: TUInt64 - + B: Cardinal - + var DivRes: Cardinal - + var ModRes: Cardinal - + + ֵޣ +} + +procedure Int128DivInt64Mod(ALo: Int64; AHi: Int64; B: Int64; + var DivRes: Int64; var ModRes: Int64); +{* 128 λз 64 λз̷ DivRes ModRes + б֤ 64 λΧڣ쳣 + + + ALo: Int64 - 64 λ + AHi: Int64 - 64 λ + B: Int64 - + var DivRes: Int64 - + var ModRes: Int64 - + + ֵޣ +} + +procedure UInt128DivUInt64Mod(ALo: TUInt64; AHi: TUInt64; B: TUInt64; + var DivRes: TUInt64; var ModRes: TUInt64); +{* 128 λ޷ 64 λ޷̷ DivRes ModRes + б֤ 64 λΧڣ쳣 + + + ALo: TUInt64 - 64 λ + AHi: TUInt64 - 64 λ + B: TUInt64 - + var DivRes: TUInt64 - + var ModRes: TUInt64 - + + ֵޣ +} + +{$ENDIF} + +function IsUInt128BitSet(Lo: TUInt64; Hi: TUInt64; N: Integer): Boolean; +{* Int64 ƴɵ 128 λ֣ص N λǷΪ 1N 0 127 + + + Lo: TUInt64 - жϵĵ 64 λ + Hi: TUInt64 - жϵĸ 64 λ + N: Integer - жϵλ + + ֵBoolean - ǷΪ 1 +} + +procedure SetUInt128Bit(var Lo: TUInt64; var Hi: TUInt64; N: Integer); +{* Int64 ƴɵ 128 λ֣õ N λΪ 1N 0 127 + + + var Lo: TUInt64 - õĵ 64 λ + var Hi: TUInt64 - õĸ 64 λ + N: Integer - õλ + + ֵޣ +} + +procedure ClearUInt128Bit(var Lo: TUInt64; var Hi: TUInt64; N: Integer); +{* Int64 ƴɵ 128 λ֣ N λN 0 127 + + + var Lo: TUInt64 - õĵ 64 λ + var Hi: TUInt64 - õĸ 64 λ + N: Integer - õλ + + ֵޣ +} + +function UnsignedAddWithLimitRadix(A: Cardinal; B: Cardinal; C: Cardinal; + var R: Cardinal; L: Cardinal; H: Cardinal): Cardinal; +{* Ƶ޷żӷA + B + C R Уؽλֵ + ȷ L H ıڣûȷ H LΡ + úַӳ䣬 C һǽλ + + + A: Cardinal - һ + B: Cardinal - + C: Cardinal - һǽλ + var R: Cardinal - + L: Cardinal - ͵ + H: Cardinal - ͵ + + ֵCardinal - Ƿнλ +} + +// =========================== ѭλ ==================================== + +// ע N Ӧ (0, A λ) ڣ N Ϊ 0 A λʱֵӦΪ A +// N ʱࣨΪͲȲͬ 32 λ AN Ϊ 33 ʱֵ N Ϊ 1 ʱķֵ + +function RotateLeft16(A: Word; N: Integer): Word; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 16 λѭ N λ + + + A: Word - ѭƵ 16 λ + N: Integer - ѭƵλ + + ֵWord - λֵ +} + +function RotateRight16(A: Word; N: Integer): Word; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 16 λѭ N λ + + + A: Word - ѭƵ 16 λ + N: Integer - ѭƵλ + + ֵWord - λֵ +} + +function RotateLeft32(A: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 32 λѭ N λ + + + A: Cardinal - ѭƵ 32 λ + N: Integer - ѭƵλ + + ֵCardinal - λֵ +} + +function RotateRight32(A: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 32 λѭ N λ + + + A: Cardinal - ѭƵ 32 λ + N: Integer - ѭƵλ + + ֵCardinal - λֵ +} + +function RotateLeft64(A: TUInt64; N: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 64 λѭ N λ + + + A: TUInt64 - ѭƵ 64 λ + N: Integer - ѭƵλ + + ֵTUInt64 - λֵ +} + +function RotateRight64(A: TUInt64; N: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 64 λѭ N λ + + + A: TUInt64 - ѭƵ 64 λ + N: Integer - ѭƵλ + + ֵTUInt64 - λֵ +} + +{$IFDEF COMPILER5} + +function BoolToStr(Value: Boolean; UseBoolStrs: Boolean = False): string; +{* תΪַDelphi 5 ûи BoolToStr ϡ + + + Value: Boolean - תIJֵ + UseBoolStrs: Boolean - Ƿ񷵻Ӣĵ + + ֵstring - UseBoolStrs Ϊ False ʱ -1 0򷵻 True False +} + +{$ENDIF} + +implementation + +uses + CnFloat; + +resourcestring + SCnErrorNotAHexPChar = 'Error: NOT a Hex PChar: %c'; + SCnErrorLengthNotHex = 'Error Length %d: NOT a Hex String'; + SCnErrorLengthNotHexAnsi = 'Error Length %d: NOT a Hex AnsiString'; + +var + FByteOrderIsBigEndian: Boolean = False; + +function CurrentByteOrderIsBigEndian: Boolean; +type + TByteOrder = packed record + case Boolean of + False: (C: array[0..1] of Byte); + True: (W: Word); + end; +var + T: TByteOrder; +begin + T.W := $00CC; + Result := T.C[1] = $CC; +end; + +function CurrentByteOrderIsLittleEndian: Boolean; +begin + Result := not CurrentByteOrderIsBigEndian; +end; + +function ReverseInt64(Value: Int64): Int64; +var + Lo, Hi: Cardinal; + Rec: Int64Rec; +begin + Lo := Int64Rec(Value).Lo; + Hi := Int64Rec(Value).Hi; + Lo := ((Lo and $000000FF) shl 24) or ((Lo and $0000FF00) shl 8) + or ((Lo and $00FF0000) shr 8) or ((Lo and $FF000000) shr 24); + Hi := ((Hi and $000000FF) shl 24) or ((Hi and $0000FF00) shl 8) + or ((Hi and $00FF0000) shr 8) or ((Hi and $FF000000) shr 24); + Rec.Lo := Hi; + Rec.Hi := Lo; + Result := Int64(Rec); +end; + +function ReverseUInt64(Value: TUInt64): TUInt64; +var + Lo, Hi: Cardinal; + Rec: Int64Rec; +begin + Lo := Int64Rec(Value).Lo; + Hi := Int64Rec(Value).Hi; + Lo := ((Lo and $000000FF) shl 24) or ((Lo and $0000FF00) shl 8) + or ((Lo and $00FF0000) shr 8) or ((Lo and $FF000000) shr 24); + Hi := ((Hi and $000000FF) shl 24) or ((Hi and $0000FF00) shl 8) + or ((Hi and $00FF0000) shr 8) or ((Hi and $FF000000) shr 24); + Rec.Lo := Hi; + Rec.Hi := Lo; + Result := TUInt64(Rec); +end; + +function Int64ToBigEndian(Value: Int64): Int64; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := ReverseInt64(Value); +end; + +function Int32ToBigEndian(Value: Integer): Integer; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) + or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24); +end; + +function Int16ToBigEndian(Value: SmallInt): SmallInt; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8); +end; + +function Int64ToLittleEndian(Value: Int64): Int64; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := ReverseInt64(Value); +end; + +function Int32ToLittleEndian(Value: Integer): Integer; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) + or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24); +end; + +function Int16ToLittleEndian(Value: SmallInt): SmallInt; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8); +end; + +function UInt64ToBigEndian(Value: TUInt64): TUInt64; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := ReverseUInt64(Value); +end; + +function UInt32ToBigEndian(Value: Cardinal): Cardinal; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) + or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24); +end; + +function UInt16ToBigEndian(Value: Word): Word; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := Word((Value and $00FF) shl 8) or Word((Value and $FF00) shr 8); +end; + +function UInt64ToLittleEndian(Value: TUInt64): TUInt64; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := ReverseUInt64(Value); +end; + +function UInt32ToLittleEndian(Value: Cardinal): Cardinal; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) + or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24); +end; + +function UInt16ToLittleEndian(Value: Word): Word; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := Word((Value and $00FF) shl 8) or Word((Value and $FF00) shr 8); +end; + +function Int64HostToNetwork(Value: Int64): Int64; +begin + if not FByteOrderIsBigEndian then + Result := ReverseInt64(Value) + else + Result := Value; +end; + +function Int32HostToNetwork(Value: Integer): Integer; +begin + if not FByteOrderIsBigEndian then + Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) + or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24) + else + Result := Value; +end; + +function Int16HostToNetwork(Value: SmallInt): SmallInt; +begin + if not FByteOrderIsBigEndian then + Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8) + else + Result := Value; +end; + +function Int64NetworkToHost(Value: Int64): Int64; +begin + if not FByteOrderIsBigEndian then + REsult := ReverseInt64(Value) + else + Result := Value; +end; + +function Int32NetworkToHost(Value: Integer): Integer; +begin + if not FByteOrderIsBigEndian then + Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) + or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24) + else + Result := Value; +end; + +function Int16NetworkToHost(Value: SmallInt): SmallInt; +begin + if not FByteOrderIsBigEndian then + Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8) + else + Result := Value; +end; + +function UInt64HostToNetwork(Value: TUInt64): TUInt64; +begin + if CurrentByteOrderIsBigEndian then + Result := Value + else + Result := ReverseUInt64(Value); +end; + +function UInt32HostToNetwork(Value: Cardinal): Cardinal; +begin + if not FByteOrderIsBigEndian then + Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) + or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24) + else + Result := Value; +end; + +function UInt16HostToNetwork(Value: Word): Word; +begin + if not FByteOrderIsBigEndian then + Result := ((Value and $00FF) shl 8) or ((Value and $FF00) shr 8) + else + Result := Value; +end; + +function UInt64NetworkToHost(Value: TUInt64): TUInt64; +begin + if CurrentByteOrderIsBigEndian then + Result := Value + else + Result := ReverseUInt64(Value); +end; + +function UInt32NetworkToHost(Value: Cardinal): Cardinal; +begin + if not FByteOrderIsBigEndian then + Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) + or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24) + else + Result := Value; +end; + +function UInt16NetworkToHost(Value: Word): Word; +begin + if not FByteOrderIsBigEndian then + Result := ((Value and $00FF) shl 8) or ((Value and $FF00) shr 8) + else + Result := Value; +end; + +function ReverseBitsInInt8(V: Byte): Byte; +begin + // 0 1 2 3 4 5 6 7 + V := ((V and $AA) shr 1) or ((V and $55) shl 1); + // 01 23 45 67 + V := ((V and $CC) shr 2) or ((V and $33) shl 2); + // 0123 4567 + V := (V shr 4) or (V shl 4); + Result := V; +end; + +function ReverseBitsInInt16(V: Word): Word; +begin + Result := (ReverseBitsInInt8(V and $00FF) shl 8) + or ReverseBitsInInt8((V and $FF00) shr 8); +end; + +function ReverseBitsInInt32(V: Cardinal): Cardinal; +begin + Result := (ReverseBitsInInt16(V and $0000FFFF) shl 16) + or ReverseBitsInInt16((V and $FFFF0000) shr 16); +end; + +function ReverseBitsInInt64(V: Int64): Int64; +begin + Result := (Int64(ReverseBitsInInt32(V and $00000000FFFFFFFF)) shl 32) + or ReverseBitsInInt32((V and $FFFFFFFF00000000) shr 32); +end; + +procedure ReverseMemory(Mem: Pointer; MemByteLen: Integer); +var + I, L: Integer; + P: PByteArray; + T: Byte; +begin + if (Mem = nil) or (MemByteLen < 2) then + Exit; + + L := MemByteLen div 2; + P := PByteArray(Mem); + for I := 0 to L - 1 do + begin + // I ͵ MemLen - I - 1 + T := P^[I]; + P^[I] := P^[MemByteLen - I - 1]; + P^[MemByteLen - I - 1] := T; + end; +end; + +procedure ReverseMemoryWithBits(Mem: Pointer; MemByteLen: Integer); +var + I: Integer; + P: PByteArray; +begin + if (Mem = nil) or (MemByteLen <= 0) then + Exit; + + ReverseMemory(Mem, MemByteLen); + P := PByteArray(Mem); + + for I := 0 to MemByteLen - 1 do + P^[I] := ReverseBitsInInt8(P^[I]); +end; + +procedure MemoryNetworkToHost(Mem: Pointer; MemByteLen: Integer); +begin + if not FByteOrderIsBigEndian then + ReverseMemory(Mem, MemByteLen); +end; + +procedure MemoryHostToNetwork(Mem: Pointer; MemByteLen: Integer); +begin + if not FByteOrderIsBigEndian then + ReverseMemory(Mem, MemByteLen); +end; + +// N ֽڳȵڴλ +procedure MemoryBitOperation(AMem, BMem, RMem: Pointer; N: Integer; Op: TCnBitOperation); +var + A, B, R: PCnLongWord32Array; + BA, BB, BR: PByteArray; +begin + if N <= 0 then + Exit; + + if (AMem = nil) or ((BMem = nil) and (Op <> boNot)) or (RMem = nil) then + Exit; + + A := PCnLongWord32Array(AMem); + B := PCnLongWord32Array(BMem); + R := PCnLongWord32Array(RMem); + + while (N and (not 3)) <> 0 do + begin + case Op of + boAnd: + R^[0] := A^[0] and B^[0]; + boOr: + R^[0] := A^[0] or B^[0]; + boXor: + R^[0] := A^[0] xor B^[0]; + boNot: // ʱ B + R^[0] := not A^[0]; + end; + + A := PCnLongWord32Array(TCnNativeInt(A) + SizeOf(Cardinal)); + B := PCnLongWord32Array(TCnNativeInt(B) + SizeOf(Cardinal)); + R := PCnLongWord32Array(TCnNativeInt(R) + SizeOf(Cardinal)); + + Dec(N, SizeOf(Cardinal)); + end; + + if N > 0 then + begin + BA := PByteArray(A); + BB := PByteArray(B); + BR := PByteArray(R); + + while N <> 0 do + begin + case Op of + boAnd: + BR^[0] := BA^[0] and BB^[0]; + boOr: + BR^[0] := BA^[0] or BB^[0]; + boXor: + BR^[0] := BA^[0] xor BB^[0]; + boNot: + BR^[0] := not BA^[0]; + end; + + BA := PByteArray(TCnNativeInt(BA) + SizeOf(Byte)); + BB := PByteArray(TCnNativeInt(BB) + SizeOf(Byte)); + BR := PByteArray(TCnNativeInt(BR) + SizeOf(Byte)); + Dec(N); + end; + end; +end; + +procedure MemoryAnd(AMem, BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +begin + MemoryBitOperation(AMem, BMem, ResMem, MemByteLen, boAnd); +end; + +procedure MemoryOr(AMem, BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +begin + MemoryBitOperation(AMem, BMem, ResMem, MemByteLen, boOr); +end; + +procedure MemoryXor(AMem, BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +begin + MemoryBitOperation(AMem, BMem, ResMem, MemByteLen, boXor); +end; + +procedure MemoryNot(Mem: Pointer; MemByteLen: Integer; ResMem: Pointer); +begin + MemoryBitOperation(Mem, nil, ResMem, MemByteLen, boNot); +end; + +procedure MemoryShiftLeft(AMem, BMem: Pointer; MemByteLen: Integer; BitCount: Integer); +var + I, L, N, LB, RB: Integer; + PF, PT: PByteArray; +begin + if (AMem = nil) or (MemByteLen <= 0) or (BitCount = 0) then + Exit; + + if BitCount < 0 then + begin + MemoryShiftRight(AMem, BMem, MemByteLen, -BitCount); + Exit; + end; + + if BMem = nil then + BMem := AMem; + + if (MemByteLen * 8) <= BitCount then // ̫಻ȫ 0 + begin + FillChar(BMem^, MemByteLen, 0); + Exit; + end; + + N := BitCount div 8; // λֽ + RB := BitCount mod 8; // ȥֽںʣµλ + LB := 8 - RB; // ʣµλһֽʣµλ + + PF := PByteArray(AMem); + PT := PByteArray(BMem); + + if RB = 0 then // 飬ð죬Ҫλֽ MemLen - NW + begin + Move(PF^[N], PT^[0], MemByteLen - N); + FillChar(PT^[MemByteLen - N], N, 0); + end + else + begin + // PF^[N] PT^[0] MemLen - N ֽڣֽڼн + L := MemByteLen - N; + PF := PByteArray(TCnNativeInt(PF) + N); + + for I := 1 to L do // ӵλƶȴ͵ + begin + PT^[0] := Byte(PF^[0] shl RB); + if I < L then // һֽ PF^[1] ᳬ + PT^[0] := (PF^[1] shr LB) or PT^[0]; + + PF := PByteArray(TCnNativeInt(PF) + 1); + PT := PByteArray(TCnNativeInt(PT) + 1); + end; + + // ʣµҪ 0 + if N > 0 then + FillChar(PT^[0], N, 0); + end; +end; + +procedure MemoryShiftRight(AMem, BMem: Pointer; MemByteLen: Integer; BitCount: Integer); +var + I, L, N, LB, RB: Integer; + PF, PT: PByteArray; +begin + if (AMem = nil) or (MemByteLen <= 0) or (BitCount = 0) then + Exit; + + if BitCount < 0 then + begin + MemoryShiftLeft(AMem, BMem, MemByteLen, -BitCount); + Exit; + end; + + if BMem = nil then + BMem := AMem; + + if (MemByteLen * 8) <= BitCount then // ̫಻ȫ 0 + begin + FillChar(BMem^, MemByteLen, 0); + Exit; + end; + + N := BitCount div 8; // λֽ + RB := BitCount mod 8; // ȥֽںʣµλ + LB := 8 - RB; // ʣµλһֽʣµλ + + if RB = 0 then // 飬ð죬Ҫλֽ MemLen - N + begin + PF := PByteArray(AMem); + PT := PByteArray(BMem); + + Move(PF^[0], PT^[N], MemByteLen - N); + FillChar(PT^[0], N, 0); + end + else + begin + // PF^[0] PT^[N] MemLen - N ֽڣôӸߴʼֽڼн + L := MemByteLen - N; + + PF := PByteArray(TCnNativeInt(AMem) + L - 1); + PT := PByteArray(TCnNativeInt(BMem) + MemByteLen - 1); + + for I := L downto 1 do // Ӹλλƶȴ + begin + PT^[0] := Byte(PF^[0] shr RB); + if I > 1 then // һֽ PF^[-1] ᳬ + begin + PF := PByteArray(TCnNativeInt(PF) - 1); + PT^[0] := (PF^[0] shl LB) or PT^[0]; + end + else + PF := PByteArray(TCnNativeInt(PF) - 1); + + PT := PByteArray(TCnNativeInt(PT) - 1); + end; + + // ʣµǰҪ 0 + if N > 0 then + FillChar(BMem^, N, 0); + end; +end; + +function MemoryIsBitSet(Mem: Pointer; N: Integer): Boolean; +var + P: PByte; + A, B: Integer; + V: Byte; +begin + if (Mem = nil) or (N < 0) then + raise ERangeError.Create(SRangeError); + + A := N div 8; + B := N mod 8; + P := PByte(TCnNativeInt(Mem) + A); + + V := Byte(1 shl B); + Result := (P^ and V) <> 0; +end; + +procedure MemorySetBit(Mem: Pointer; N: Integer); +var + P: PByte; + A, B: Integer; + V: Byte; +begin + if (Mem = nil) or (N < 0) then + raise ERangeError.Create(SRangeError); + + A := N div 8; + B := N mod 8; + P := PByte(TCnNativeInt(Mem) + A); + + V := Byte(1 shl B); + P^ := P^ or V; +end; + +procedure MemoryClearBit(Mem: Pointer; N: Integer); +var + P: PByte; + A, B: Integer; + V: Byte; +begin + if (Mem = nil) or (N < 0) then + raise ERangeError.Create(SRangeError); + + A := N div 8; + B := N mod 8; + P := PByte(TCnNativeInt(Mem) + A); + + V := not Byte(1 shl B); + P^ := P^ and V; +end; + +function MemoryToBinStr(Mem: Pointer; MemByteLen: Integer; Sep: Boolean): string; +var + J, L: Integer; + P: PByteArray; + B: PChar; + + procedure FillAByteToBuf(V: Byte; Buf: PChar); + const + M = $80; + var + I: Integer; + begin + for I := 0 to 7 do + begin + if (V and M) <> 0 then + Buf[I] := '1' + else + Buf[I] := '0'; + V := V shl 1; + end; + end; + +begin + Result := ''; + if (Mem = nil) or (MemByteLen <= 0) then + Exit; + + L := MemByteLen * 8; + if Sep then + L := L + MemByteLen - 1; // мÿոָ + + SetLength(Result, L); + B := PChar(@Result[1]); + P := PByteArray(Mem); + + for J := 0 to MemByteLen - 1 do + begin + FillAByteToBuf(P^[J], B); + if Sep then + begin + B[8] := ' '; + Inc(B, 9); + end + else + Inc(B, 8); + end; +end; + +procedure MemorySwap(AMem, BMem: Pointer; MemByteLen: Integer); +var + A, B: PCnLongWord32Array; + BA, BB: PByteArray; + TC: Cardinal; + TB: Byte; +begin + if (AMem = nil) or (BMem = nil) or (MemByteLen <= 0) then + Exit; + + A := PCnLongWord32Array(AMem); + B := PCnLongWord32Array(BMem); + + if A = B then + Exit; + + while (MemByteLen and (not 3)) <> 0 do + begin + TC := A^[0]; + A^[0] := B^[0]; + B^[0] := TC; + + A := PCnLongWord32Array(TCnNativeInt(A) + SizeOf(Cardinal)); + B := PCnLongWord32Array(TCnNativeInt(B) + SizeOf(Cardinal)); + + Dec(MemByteLen, SizeOf(Cardinal)); + end; + + if MemByteLen > 0 then + begin + BA := PByteArray(A); + BB := PByteArray(B); + + while MemByteLen <> 0 do + begin + TB := BA^[0]; + BA^[0] := BB^[0]; + BB^[0] :=TB; + + BA := PByteArray(TCnNativeInt(BA) + SizeOf(Byte)); + BB := PByteArray(TCnNativeInt(BB) + SizeOf(Byte)); + + Dec(MemByteLen); + end; + end; +end; + +function MemoryCompare(AMem, BMem: Pointer; MemByteLen: Integer): Integer; +var + A, B: PCnLongWord32Array; + BA, BB: PByteArray; +begin + Result := 0; + if ((AMem = nil) and (BMem = nil)) or (AMem = BMem) then // ͬһ + Exit; + + if MemByteLen <= 0 then + Exit; + + if AMem = nil then + begin + Result := -1; + Exit; + end; + if BMem = nil then + begin + Result := 1; + Exit; + end; + + A := PCnLongWord32Array(AMem); + B := PCnLongWord32Array(BMem); + + while (MemByteLen and (not 3)) <> 0 do + begin + if A^[0] > B^[0] then + begin + Result := 1; + Exit; + end + else if A^[0] < B^[0] then + begin + Result := -1; + Exit; + end; + + A := PCnLongWord32Array(TCnNativeInt(A) + SizeOf(Cardinal)); + B := PCnLongWord32Array(TCnNativeInt(B) + SizeOf(Cardinal)); + + Dec(MemByteLen, SizeOf(Cardinal)); + end; + + if MemByteLen > 0 then + begin + BA := PByteArray(A); + BB := PByteArray(B); + + while MemByteLen <> 0 do + begin + if BA^[0] > BB^[0] then + begin + Result := 1; + Exit; + end + else if BA^[0] < BB^[0] then + begin + Result := -1; + Exit; + end; + + BA := PByteArray(TCnNativeInt(BA) + SizeOf(Byte)); + BB := PByteArray(TCnNativeInt(BB) + SizeOf(Byte)); + + Dec(MemByteLen); + end; + end; +end; + +function UInt8ToBinStr(V: Byte): string; +const + M = $80; +var + I: Integer; +begin + SetLength(Result, 8 * SizeOf(V)); + for I := 1 to 8 * SizeOf(V) do + begin + if (V and M) <> 0 then + Result[I] := '1' + else + Result[I] := '0'; + V := V shl 1; + end; +end; + +function UInt16ToBinStr(V: Word): string; +const + M = $8000; +var + I: Integer; +begin + SetLength(Result, 8 * SizeOf(V)); + for I := 1 to 8 * SizeOf(V) do + begin + if (V and M) <> 0 then + Result[I] := '1' + else + Result[I] := '0'; + V := V shl 1; + end; +end; + +function UInt32ToBinStr(V: Cardinal): string; +const + M = $80000000; +var + I: Integer; +begin + SetLength(Result, 8 * SizeOf(V)); + for I := 1 to 8 * SizeOf(V) do + begin + if (V and M) <> 0 then + Result[I] := '1' + else + Result[I] := '0'; + V := V shl 1; + end; +end; + +function UInt32ToStr(V: Cardinal): string; +begin + Result := Format('%u', [V]); +end; + +function UInt64ToBinStr(V: TUInt64): string; +const + M = $8000000000000000; +var + I: Integer; +begin + SetLength(Result, 8 * SizeOf(V)); + + for I := 1 to 8 * SizeOf(V) do + begin + if (V and M) <> 0 then + Result[I] := '1' + else + Result[I] := '0'; + V := V shl 1; + end; +end; + +const + HiDigits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); +const + LoDigits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); + +const + AnsiHiDigits: array[0..15] of AnsiChar = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); +const + AnsiLoDigits: array[0..15] of AnsiChar = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); + +function HexToInt(Hex: PChar; CharLen: Integer): Integer; +var + I, Res: Integer; + C: Char; +begin + Res := 0; + for I := 0 to CharLen - 1 do + begin + C := Hex[I]; + if (C >= '0') and (C <= '9') then + Res := Res * 16 + Ord(C) - Ord('0') + else if (C >= 'A') and (C <= 'F') then + Res := Res * 16 + Ord(C) - Ord('A') + 10 + else if (C >= 'a') and (C <= 'f') then + Res := Res * 16 + Ord(C) - Ord('a') + 10 + else + raise ECnNativeException.CreateFmt(SCnErrorNotAHexPChar, [C]); + end; + Result := Res; +end; + +function HexToInt(const Hex: string): Integer; +begin + Result := HexToInt(PChar(Hex), Length(Hex)); +end; + +{$WARNINGS OFF} + +function IsHexString(const Hex: string): Boolean; +var + I, L: Integer; +begin + Result := False; + L := Length(Hex); + if (L <= 0) or ((L and 1) <> 0) then // ջżȶ + Exit; + + for I := 1 to L do + begin + // ע˴ Unicode Ȼ Warningǽ Hex[I] WideChar ֱӽض AnsiChar + // ٽжϣᵼ¡޻ޡ $66$66$66$66 ַУ + // ֱͨ WideChar ֵ ax ˫ֽڵģӼжϣ + if not (Hex[I] in ['0'..'9', 'A'..'F', 'a'..'f']) then + Exit; + end; + Result := True; +end; + +{$WARNINGS ON} + +function DataToHex(InData: Pointer; ByteLength: Integer; UseUpperCase: Boolean = True): string; +var + I: Integer; + B: Byte; +begin + Result := ''; + if ByteLength <= 0 then + Exit; + + SetLength(Result, ByteLength * 2); + if UseUpperCase then + begin + for I := 0 to ByteLength - 1 do + begin + B := PByte(TCnNativeInt(InData) + I * SizeOf(Byte))^; + Result[I * 2 + 1] := HiDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := HiDigits[B and $0F]; + end; + end + else + begin + for I := 0 to ByteLength - 1 do + begin + B := PByte(TCnNativeInt(InData) + I * SizeOf(Byte))^; + Result[I * 2 + 1] := LoDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := LoDigits[B and $0F]; + end; + end; +end; + +function HexToData(const Hex: string; OutData: Pointer): Integer; +var + I, L: Integer; + H: PChar; +begin + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); + + if OutData = nil then + begin + Result := L div 2; + Exit; + end; + + Result := 0; + H := PChar(Hex); + for I := 1 to L div 2 do + begin + PByte(TCnNativeInt(OutData) + I - 1)^ := Byte(HexToInt(@H[(I - 1) * 2], 2)); + Inc(Result); + end; +end; + +function StringToHex(const Data: string; UseUpperCase: Boolean): string; +var + I, L: Integer; + B: Byte; + Buffer: PChar; +begin + Result := ''; + L := Length(Data); + if L = 0 then + Exit; + + SetLength(Result, L * 2); + Buffer := @Data[1]; + + if UseUpperCase then + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I * SizeOf(Char))^; + Result[I * 2 + 1] := HiDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := HiDigits[B and $0F]; + end; + end + else + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I * SizeOf(Char))^; + Result[I * 2 + 1] := LoDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := LoDigits[B and $0F]; + end; + end; +end; + +function HexToString(const Hex: string): string; +var + I, L: Integer; + H: PChar; +begin + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); + + SetLength(Result, L div 2); + H := PChar(Hex); + for I := 1 to L div 2 do + Result[I] := Chr(HexToInt(@H[(I - 1) * 2], 2)); +end; + +function HexToAnsiStr(const Hex: AnsiString): AnsiString; +var + I, L: Integer; + S: string; +begin + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHexAnsi, [L]); + + SetLength(Result, L div 2); + for I := 1 to L div 2 do + begin + S := string(Copy(Hex, I * 2 - 1, 2)); + Result[I] := AnsiChar(Chr(HexToInt(S))); + end; +end; + +function AnsiStrToHex(const Data: AnsiString; UseUpperCase: Boolean): AnsiString; +var + I, L: Integer; + B: Byte; + Buffer: PAnsiChar; +begin + Result := ''; + L := Length(Data); + if L = 0 then + Exit; + + SetLength(Result, L * 2); + Buffer := @Data[1]; + + if UseUpperCase then + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I)^; + Result[I * 2 + 1] := AnsiHiDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := AnsiHiDigits[B and $0F]; + end; + end + else + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I)^; + Result[I * 2 + 1] := AnsiLoDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := AnsiLoDigits[B and $0F]; + end; + end; +end; + +function BytesToHex(Data: TBytes; UseUpperCase: Boolean): string; +var + I, L: Integer; + B: Byte; + Buffer: PAnsiChar; +begin + Result := ''; + L := Length(Data); + if L = 0 then + Exit; + + SetLength(Result, L * 2); + Buffer := @Data[0]; + + if UseUpperCase then + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I)^; + Result[I * 2 + 1] := HiDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := HiDigits[B and $0F]; + end; + end + else + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I)^; + Result[I * 2 + 1] := LoDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := LoDigits[B and $0F]; + end; + end; +end; + +function HexToBytes(const Hex: string): TBytes; +var + I, L: Integer; + H: PChar; +begin + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); + + SetLength(Result, L div 2); + H := PChar(Hex); + + for I := 1 to L div 2 do + Result[I - 1] := Byte(HexToInt(@H[(I - 1) * 2], 2)); +end; + +function StreamToHex(Stream: TStream; UseUpperCase: Boolean): string; +var + B: Byte; + I: Integer; +begin + Result := ''; + if Stream.Size > 0 then + begin + Stream.Position := 0; + SetLength(Result, Stream.Size * 2); + I := 1; + if UseUpperCase then + begin + while Stream.Read(B, 1) = 1 do + begin + Result[I] := HiDigits[(B shr 4) and $0F]; + Inc(I); + Result[I] := HiDigits[B and $0F]; + Inc(I); + end; + end + else + begin + while Stream.Read(B, 1) = 1 do + begin + Result[I] := LoDigits[(B shr 4) and $0F]; + Inc(I); + Result[I] := LoDigits[B and $0F]; + Inc(I); + end; + end; + end; +end; + +function HexToStream(const Hex: string; Stream: TStream): Integer; +var + I, L: Integer; + H: PChar; + B: Byte; +begin + Result := 0; + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); + + H := PChar(Hex); + for I := 1 to L div 2 do + begin + B := Byte(HexToInt(@H[(I - 1) * 2], 2)); + Inc(Result, Stream.Write(B, 1)); + end; +end; + +procedure ReverseBytes(Data: TBytes); +var + I, L, M: Integer; + T: Byte; +begin + if (Data = nil) or (Length(Data) <= 1) then + Exit; + L := Length(Data); + M := L div 2; + for I := 0 to M - 1 do + begin + // I L - I - 1 + T := Data[I]; + Data[I] := Data[L - I - 1]; + Data[L - I - 1] := T; + end; +end; + +function CloneBytes(Data: TBytes): TBytes; +begin + if Length(Data) = 0 then + Result := nil + else + begin + SetLength(Result, Length(Data)); + Move(Data[0], Result[0], Length(Data)); + end; +end; + +function StreamToBytes(Stream: TStream): TBytes; +begin + Result := nil; + if (Stream <> nil) and (Stream.Size > 0) then + begin + SetLength(Result, Stream.Size); + Stream.Position := 0; + Stream.Read(Result[0], Stream.Size); + end; +end; + +function BytesToStream(Data: TBytes; OutStream: TStream): Integer; +begin + Result := 0; + if (Data <> nil) and (Length(Data) > 0) and (OutStream <> nil) then + begin + OutStream.Size := 0; + Result := OutStream.Write(Data[0], Length(Data)); + end; +end; + +function AnsiToBytes(const Str: AnsiString): TBytes; +begin + SetLength(Result, Length(Str)); + if Length(Str) > 0 then + Move(Str[1], Result[0], Length(Str)); +end; + +function BytesToAnsi(Data: TBytes): AnsiString; +begin + SetLength(Result, Length(Data)); + if Length(Data) > 0 then + Move(Data[0], Result[1], Length(Data)); +end; + +function BytesToString(Data: TBytes): string; +var + I: Integer; +begin + SetLength(Result, Length(Data)); + for I := 1 to Length(Data) do + Result[I] := Chr(Data[I - 1]); +end; + +function MemoryToString(Mem: Pointer; MemByteLen: Integer): string; +var + P: PByteArray; + I: Integer; +begin + if (Mem = nil) or (MemByteLen <= 0) then + begin + Result := ''; + Exit; + end; + + P := PByteArray(Mem); + SetLength(Result, MemByteLen); + for I := 1 to MemByteLen do + Result[I] := Chr(P^[I - 1]); +end; + +function BitsToString(Bits: TBits): string; +var + I: Integer; +begin + if (Bits = nil) or (Bits.Size = 0) then + Result := '' + else + begin + SetLength(Result, Bits.Size); + for I := 0 to Bits.Size - 1 do + begin + if Bits.Bits[I] then + Result[I + 1] := '1' + else + Result[I + 1] := '0'; + end; + end; +end; + +function ConcatBytes(A, B: TBytes): TBytes; +begin + // XE7 ҲֱӣΪ A B Ϊʱ᷵һֽ + if (A = nil) or (Length(A) = 0) then + begin + SetLength(Result, Length(B)); + if Length(B) > 0 then + Move(B[0], Result[0], Length(B)); + end + else if (B = nil) or (Length(B) = 0) then + begin + SetLength(Result, Length(A)); + if Length(A) > 0 then + Move(A[0], Result[0], Length(A)); + end + else + begin + SetLength(Result, Length(A) + Length(B)); + Move(A[0], Result[0], Length(A)); + Move(B[0], Result[Length(A)], Length(B)); + end; +end; + +function NewBytesFromMemory(Data: Pointer; DataByteLen: Integer): TBytes; +begin + if (Data = nil) or (DataByteLen <= 0) then + Result := nil + else + begin + SetLength(Result, DataByteLen); + Move(Data^, Result[0], DataByteLen); + end; +end; + +function CompareBytes(A, B: TBytes): Boolean; +var + L: Integer; +begin + Result := False; + + L := Length(A); + if Length(B) <> L then // Ȳ˳ + Exit; + + if L = 0 then // + Result := True // 綼 0 + else + Result := CompareMem(@A[0], @B[0], L); +end; + +function CompareBytes(A, B: TBytes; MaxLength: Integer): Boolean; +var + LA, LB: Integer; +begin + Result := False; + + LA := Length(A); + LB := Length(B); + + if LA > MaxLength then + LA := MaxLength; + if LB > MaxLength then + LB := MaxLength; + + if LA <> LB then + Exit; + + if LA = 0 then + Result := True + else + Result := CompareMem(@A[0], @B[0], LA); +end; + +function MoveMost(const Source; var Dest; ByteLen, MostLen: Integer): Integer; +begin + if (MostLen <= 0) or (ByteLen <= 0) then + begin + Result := 0; + Exit; + end; + + if ByteLen > MostLen then + ByteLen := MostLen + else if ByteLen < MostLen then + begin + FillChar(Dest, MostLen, 0); + + // TODO: ҪΪ FillChar(Dest + ByteLen, MostLen - ByteLen, 0); ֻ䲻IJ + end; + + Move(Source, Dest, ByteLen); + Result := ByteLen; +end; + +// =============================== =================================== + +function SarInt8(var V: Byte; ShiftCount: Integer): Byte; +begin + Result := V shr ShiftCount; + if (V and $80) <> 0 then + Result := Result or $80; +end; + +function SarInt16(var V: Word; ShiftCount: Integer): Word; +begin + Result := V shr ShiftCount; + if (V and $8000) <> 0 then + Result := Result or $8000; +end; + +function SarInt32(var V: Cardinal; ShiftCount: Integer): Cardinal; +begin + Result := V shr ShiftCount; + if (V and $80000000) <> 0 then + Result := Result or $80000000; +end; + +function SarInt64(var V: TUInt64; ShiftCount: Integer): TUInt64; +begin + Result := V shr ShiftCount; + if (V and $8000000000000000) <> 0 then + Result := Result or $8000000000000000; +end; + +procedure ConstTimeConditionalSwap8(CanSwap: Boolean; var A, B: Byte); +var + T, V: Byte; +begin + T := ConstTimeExpandBoolean8(CanSwap); + V := (A xor B) and T; + A := A xor V; + B := B xor V; +end; + +procedure ConstTimeConditionalSwap16(CanSwap: Boolean; var A, B: Word); +var + T, V: Word; +begin + T := ConstTimeExpandBoolean16(CanSwap); + V := (A xor B) and T; + A := A xor V; + B := B xor V; +end; + +procedure ConstTimeConditionalSwap32(CanSwap: Boolean; var A, B: Cardinal); +var + T, V: Cardinal; +begin + T := ConstTimeExpandBoolean32(CanSwap); + V := (A xor B) and T; + A := A xor V; + B := B xor V; +end; + +procedure ConstTimeConditionalSwap64(CanSwap: Boolean; var A, B: TUInt64); +var + T, V: TUInt64; +begin + T := ConstTimeExpandBoolean64(CanSwap); + V := (A xor B) and T; + A := A xor V; + B := B xor V; +end; + +function ConstTimeEqual8(A, B: Byte): Boolean; +var + R: Byte; +begin + R := not (A xor B); // + R := R and (R shr 4); // һһ + R := R and (R shr 2); // һλ 0 + R := R and (R shr 1); // 0 + Result := Boolean(R); // ֻȫ 1 1 +end; + +function ConstTimeEqual16(A, B: Word): Boolean; +begin + Result := ConstTimeEqual8(Byte(A shr 8), Byte(B shr 8)) + and ConstTimeEqual8(Byte(A and $FF), Byte(B and $FF)); +end; + +function ConstTimeEqual32(A, B: Cardinal): Boolean; +begin + Result := ConstTimeEqual16(Word(A shr 16), Word(B shr 16)) + and ConstTimeEqual16(Word(A and $FFFF), Word(B and $FFFF)); +end; + +function ConstTimeEqual64(A, B: TUInt64): Boolean; +begin + Result := ConstTimeEqual32(Cardinal(A shr 32), Cardinal(B shr 32)) + and ConstTimeEqual32(Cardinal(A and $FFFFFFFF), Cardinal(B and $FFFFFFFF)); +end; + +function ConstTimeBytesEqual(A, B: TBytes): Boolean; +var + I: Integer; +begin + Result := False; + if Length(A) <> Length(B) then + Exit; + + Result := True; + for I := 0 to Length(A) - 1 do // ÿֽڶȽϣͬ˳ + Result := Result and (ConstTimeEqual8(A[I], B[I])); +end; + +function ConstTimeExpandBoolean8(V: Boolean): Byte; +begin + Result := Byte(V); + Result := not Result; // V True 0˲ R Ǵ $FFR ͷ 0 + Result := Result and (Result shr 4); // һһ + Result := Result and (Result shr 2); // һλ 0 + Result := Result and (Result shr 1); // 00000000 00000001 + Result := Result or (Result shl 1); // True õ 00000000False õ 00000001λ + Result := Result or (Result shl 2); + Result := Result or (Result shl 4); // ȫ 0 ȫ 1 + Result := not Result; // ȫ 1 ȫ 0 +end; + +function ConstTimeExpandBoolean16(V: Boolean): Word; +var + R: Byte; +begin + R := ConstTimeExpandBoolean8(V); + Result := R; + Result := (Result shl 8) or R; // ֽȫ 1 ȫ 0 ˫ֽ +end; + +function ConstTimeExpandBoolean32(V: Boolean): Cardinal; +var + R: Word; +begin + R := ConstTimeExpandBoolean16(V); + Result := R; + Result := (Result shl 16) or R; // ˫ֽȫ 1 ȫ 0 ֽ +end; + +function ConstTimeExpandBoolean64(V: Boolean): TUInt64; +var + R: Cardinal; +begin + R := ConstTimeExpandBoolean32(V); + Result := R; + Result := (Result shl 32) or R; // ֽȫ 1 ȫ 0 ɰֽ +end; + +function ConstTimeConditionalSelect8(Condition: Boolean; A, B: Byte): Byte; +begin + ConstTimeConditionalSwap8(Condition, A, B); + Result := B; +end; + +function ConstTimeConditionalSelect16(Condition: Boolean; A, B: Word): Word; +begin + ConstTimeConditionalSwap16(Condition, A, B); + Result := B; +end; + +function ConstTimeConditionalSelect32(Condition: Boolean; A, B: Cardinal): Cardinal; +begin + ConstTimeConditionalSwap32(Condition, A, B); + Result := B; +end; + +function ConstTimeConditionalSelect64(Condition: Boolean; A, B: TUInt64): TUInt64; +begin + ConstTimeConditionalSwap64(Condition, A, B); + Result := B; +end; + +{$IFDEF MSWINDOWS} + +{$IFDEF CPUX64} + +// 64 λ IDIV IDIV ָʵ֣ A RCX B EDX/RDX DivRes ַ R8 ModRes ַ R9 +procedure Int64DivInt32Mod(A: Int64; B: Integer; var DivRes, ModRes: Integer); assembler; +asm + PUSH RCX // RCX A + MOV RCX, RDX // B RCX + POP RAX // A RAX + XOR RDX, RDX // 64 λ + IDIV RCX + MOV [R8], EAX // ̷ R8 ָ DivRes + MOV [R9], EDX // R9 ָ ModRes +end; + +procedure UInt64DivUInt32Mod(A: TUInt64; B: Cardinal; var DivRes, ModRes: Cardinal); assembler; +asm + PUSH RCX // RCX A + MOV RCX, RDX // B RCX + POP RAX // A RAX + XOR RDX, RDX // 64 λ + DIV RCX + MOV [R8], EAX // ̷ R8 ָ DivRes + MOV [R9], EDX // R9 ָ ModRes +end; + +// 64 λ IDIV IDIV ָʵ֣ALo RCXAHi RDXB R8DivRes ĵַ R9 +procedure Int128DivInt64Mod(ALo, AHi: Int64; B: Int64; var DivRes, ModRes: Int64); assembler; +asm + MOV RAX, RCX // ALo RAXAHi Ѿ RDX + MOV RCX, R8 // B RCX + IDIV RCX + MOV [R9], RAX // ̷ R9 ָ DivRes + MOV RAX, [RBP + $30] // ModRes ַ RAX + MOV [RAX], RDX // RAX ָ ModRes +end; + +procedure UInt128DivUInt64Mod(ALo, AHi: UInt64; B: UInt64; var DivRes, ModRes: UInt64); assembler; +asm + MOV RAX, RCX // ALo RAXAHi Ѿ RDX + MOV RCX, R8 // B RCX + DIV RCX + MOV [R9], RAX // ̷ R9 ָ DivRes + MOV RAX, [RBP + $30] // ModRes ַ RAX + MOV [RAX], RDX // RAX ָ ModRes +end; + +{$ELSE} + +// 32 λ IDIV IDIV ָʵ֣ A ڶջϣB EAXDivRes ַ EDXModRes ַ ECX +procedure Int64DivInt32Mod(A: Int64; B: Integer; var DivRes, ModRes: Integer); assembler; +asm + PUSH ECX // ECX ModRes ַȱ + MOV ECX, B // B EAX УƵ ECX + PUSH EDX // DivRes ĵַ EDX УҲ + MOV EAX, [EBP + $8] // A Lo + MOV EDX, [EBP + $C] // A Hi + IDIV ECX + POP ECX // ECXõ DivRes ַ + MOV [ECX], EAX + POP ECX // ECXõ ModRes ַ + MOV [ECX], EDX +end; + +procedure UInt64DivUInt32Mod(A: TUInt64; B: Cardinal; var DivRes, ModRes: Cardinal); assembler; +asm + PUSH ECX // ECX ModRes ַȱ + MOV ECX, B // B EAX УƵ ECX + PUSH EDX // DivRes ĵַ EDX УҲ + MOV EAX, [EBP + $8] // A Lo + MOV EDX, [EBP + $C] // A Hi + DIV ECX + POP ECX // ECXõ DivRes ַ + MOV [ECX], EAX + POP ECX // ECXõ ModRes ַ + MOV [ECX], EDX +end; + +// 32 λµʵ +procedure Int128DivInt64Mod(ALo, AHi: Int64; B: Int64; var DivRes, ModRes: Int64); +var + C: Integer; +begin + if B = 0 then + raise EDivByZero.Create(SDivByZero); + + if (AHi = 0) or (AHi = $FFFFFFFFFFFFFFFF) then // 64 λΪ 0 ֵֵ + begin + DivRes := ALo div B; + ModRes := ALo mod B; + end + else + begin + if B < 0 then // Ǹ + begin + Int128DivInt64Mod(ALo, AHi, -B, DivRes, ModRes); + DivRes := -DivRes; + Exit; + end; + + if AHi < 0 then // Ǹ + begin + // AHi, ALo 󷴼 1Եõֵ + AHi := not AHi; + ALo := not ALo; +{$IFDEF SUPPORT_UINT64} + UInt64Add(UInt64(ALo), UInt64(ALo), 1, C); +{$ELSE} + UInt64Add(ALo, ALo, 1, C); +{$ENDIF} + if C > 0 then + AHi := AHi + C; + + // ת + Int128DivInt64Mod(ALo, AHi, B, DivRes, ModRes); + + // ٵ + if ModRes = 0 then + DivRes := -DivRes + else + begin + DivRes := -DivRes - 1; + ModRes := B - ModRes; + end; + Exit; + end; + + // ȫ󣬰޷ +{$IFDEF SUPPORT_UINT64} + UInt128DivUInt64Mod(TUInt64(ALo), TUInt64(AHi), TUInt64(B), TUInt64(DivRes), TUInt64(ModRes)); +{$ELSE} + UInt128DivUInt64Mod(ALo, AHi, B, DivRes, ModRes); +{$ENDIF} + end; +end; + +procedure UInt128DivUInt64Mod(ALo, AHi: TUInt64; B: TUInt64; var DivRes, ModRes: TUInt64); +var + I, Cnt: Integer; + Q, R: TUInt64; +begin + if B = 0 then + raise EDivByZero.Create(SDivByZero); + + if AHi = 0 then + begin + DivRes := UInt64Div(ALo, B); + ModRes := UInt64Mod(ALo, B); + end + else + begin + // иλеλզ죿жǷ AHi >= BʾҪ 64 λ + if UInt64Compare(AHi, B) >= 0 then + raise EIntOverflow.Create(SIntOverflow); + + Q := 0; + R := 0; + Cnt := GetUInt64LowBits(AHi) + 64; + for I := Cnt downto 0 do + begin + R := R shl 1; + if IsUInt128BitSet(ALo, AHi, I) then // ĵ I λǷ 0 + R := R or 1 + else + R := R and TUInt64(not 1); + + if UInt64Compare(R, B) >= 0 then + begin + R := R - B; + Q := Q or (TUInt64(1) shl I); + end; + end; + DivRes := Q; + ModRes := R; + end; +end; + +{$ENDIF} + +{$ENDIF} + +{$IFDEF SUPPORT_UINT64} + +// ֻҪ֧ 64 λ޷ 32/64 λ Intel ARM Delphi FPCʲôϵͳ + +function UInt64Mod(A, B: TUInt64): TUInt64; +begin + Result := A mod B; +end; + +function UInt64Div(A, B: TUInt64): TUInt64; +begin + Result := A div B; +end; + +{$ELSE} +{ + ֧ UInt64 ĵͰ汾 Delphi Int64 A mod/div B + + õջ˳ A ĸλA ĵλB ĸλB ĵλ push ϲ뺯 + ESP ǷصַESP+4 B ĵλESP + 8 B ĸλESP + C A ĵλESP + 10 A ĸλ + push esp ESP 4Ȼ mov ebp esp֮ EBP ѰַȫҪ 4 + + System.@_llumod ҪڸսʱEAX <- A ĵλEDX <- A ĸλSystem Դע EAX/EDX дˣ + [ESP + 8]Ҳ EBP + C<- B ĸλ[ESP + 4] Ҳ EBP + 8<- B ĵλ + + CALL ǰľƴ롣UInt64 Div Ҳ +} +function UInt64Mod(A, B: TUInt64): TUInt64; +asm + // PUSH ESP ESP 4Ҫ + MOV EAX, [EBP + $10] // A Lo + MOV EDX, [EBP + $14] // A Hi + PUSH DWORD PTR[EBP + $C] // B Hi + PUSH DWORD PTR[EBP + $8] // B Lo + CALL System.@_llumod; +end; + +function UInt64Div(A, B: TUInt64): TUInt64; +asm + // PUSH ESP ESP 4Ҫ + MOV EAX, [EBP + $10] // A Lo + MOV EDX, [EBP + $14] // A Hi + PUSH DWORD PTR[EBP + $C] // B Hi + PUSH DWORD PTR[EBP + $8] // B Lo + CALL System.@_lludiv; +end; + +{$ENDIF} + +{$IFDEF SUPPORT_UINT64} + +// ֻҪ֧ 64 λ޷ 32/64 λ Intel ARM Delphi FPCʲôϵͳ + +function UInt64Mul(A, B: Cardinal): TUInt64; +begin + Result := TUInt64(A) * B; +end; + +{$ELSE} // ֻеͰ汾 Delphi Win32 x86 + +{ + ޷ 32 λˣֱʹ Int64 ģ 64 λ޷ + + üĴԼ A -> EAXB -> EDXʹöջ + System.@_llmul ҪڸսʱEAX <- A ĵλEDX <- A ĸλ 0 + [ESP + 8]Ҳ EBP + C<- B ĸλ 0[ESP + 4] Ҳ EBP + 8<- B ĵλ +} +function UInt64Mul(A, B: Cardinal): TUInt64; +asm + PUSH 0 // PUSH B λ 0 + PUSH EDX // PUSH B λ + // EAX A λѾ + XOR EDX, EDX // EDX A λ 0 + CALL System.@_llmul; // EAX 32 λEDX 32 λ +end; + +{$ENDIF} + +// ޷ 64 λӣ ResLo ResHi +procedure UInt64AddUInt64(A, B: TUInt64; var ResLo, ResHi: TUInt64); +var + X, Y, Z, T, R0L, R0H, R1L, R1H: Cardinal; + R0, R1, R01, R12: TUInt64; +begin + // ˼룺2^32 ϵ M (xM+y) + (zM+t) = (x+z) M + (y+t) + // y+t R0 ռ 01x+z R1 ռ 12 R0, R1 ٲӳ R01, R12 + if IsUInt64AddOverflow(A, B) then + begin + X := Int64Rec(A).Hi; + Y := Int64Rec(A).Lo; + Z := Int64Rec(B).Hi; + T := Int64Rec(B).Lo; + + R0 := TUInt64(Y) + TUInt64(T); + R1 := TUInt64(X) + TUInt64(Z); + + R0L := Int64Rec(R0).Lo; + R0H := Int64Rec(R0).Hi; + R1L := Int64Rec(R1).Lo; + R1H := Int64Rec(R1).Hi; + + R01 := TUInt64(R0H) + TUInt64(R1L); + R12 := TUInt64(R1H) + TUInt64(Int64Rec(R01).Hi); + + Int64Rec(ResLo).Lo := R0L; + Int64Rec(ResLo).Hi := Int64Rec(R01).Lo; + Int64Rec(ResHi).Lo := Int64Rec(R12).Lo; + Int64Rec(ResHi).Hi := Int64Rec(R12).Hi; + end + else + begin + ResLo := A + B; + ResHi := 0; + end; +end; + +{$IFDEF WIN64} // ע Linux 64 ²֧ ASMֻ WIN64 + +// 64 λ޷ 64 λˣ ResLo ResHi Уֱûʵ֣һ +procedure UInt64MulUInt64(A, B: UInt64; var ResLo, ResHi: UInt64); assembler; +asm + PUSH RAX + MOV RAX, RCX + MUL RDX // ޷ţзŵ IMUL + MOV [R8], RAX + MOV [R9], RDX + POP RAX +end; + +{$ELSE} + +// ޷ 64 λˣ ResLo ResHi +procedure UInt64MulUInt64(A, B: TUInt64; var ResLo, ResHi: TUInt64); +var + X, Y, Z, T: Cardinal; + YT, XT, ZY, ZX: TUInt64; + P, R1Lo, R1Hi, R2Lo, R2Hi: TUInt64; +begin + // ˼룺2^32 ϵ M (xM+y)*(zM+t) = xzM^2 + (xt+yz)M + yt + // ϵ UInt64xz ռ 234xt+yz ռ 123yt ռ 01Ȼۼ + X := Int64Rec(A).Hi; + Y := Int64Rec(A).Lo; + Z := Int64Rec(B).Hi; + T := Int64Rec(B).Lo; + + YT := UInt64Mul(Y, T); + XT := UInt64Mul(X, T); + ZY := UInt64Mul(Y, Z); + ZX := UInt64Mul(X, Z); + + Int64Rec(ResLo).Lo := Int64Rec(YT).Lo; + + P := Int64Rec(YT).Hi; + UInt64AddUInt64(P, XT, R1Lo, R1Hi); + UInt64AddUInt64(ZY, R1Lo, R2Lo, R2Hi); + + Int64Rec(ResLo).Hi := Int64Rec(R2Lo).Lo; + + P := TUInt64(Int64Rec(R2Lo).Hi) + TUInt64(Int64Rec(ZX).Lo); + + Int64Rec(ResHi).Lo := Int64Rec(P).Lo; + Int64Rec(ResHi).Hi := Int64Rec(R1Hi).Lo + Int64Rec(R2Hi).Lo + Int64Rec(ZX).Hi + Int64Rec(P).Hi; +end; + +{$ENDIF} + +{$HINTS OFF} + +function _ValUInt64(const S: string; var Code: Integer): TUInt64; +const + FirstIndex = 1; +var + I: Integer; + Dig: Integer; + Sign: Boolean; + Empty: Boolean; +begin + I := FirstIndex; + Dig := 0; + Result := 0; + + if S = '' then + begin + Code := 1; + Exit; + end; + + while S[I] = Char(' ') do + Inc(I); + Sign := False; + + if S[I] = Char('-') then + begin + Sign := True; + Inc(I); + end + else if S[I] = Char('+') then + Inc(I); + Empty := True; + + if (S[I] = Char('$')) or (UpCase(S[I]) = Char('X')) + or ((S[I] = Char('0')) and (I < Length(S)) and (UpCase(S[I+1]) = Char('X'))) then + begin + if S[I] = Char('0') then + Inc(I); + Inc(I); + while True do + begin + case Char(S[I]) of + Char('0').. Char('9'): Dig := Ord(S[I]) - Ord('0'); + Char('A').. Char('F'): Dig := Ord(S[I]) - (Ord('A') - 10); + Char('a').. Char('f'): Dig := Ord(S[I]) - (Ord('a') - 10); + else + Break; + end; + + if Result > (CN_MAX_TUINT64 shr 4) then + Break; + if Sign and (Dig <> 0) then + Break; + + Result := Result shl 4 + TUInt64(Dig); + Inc(I); + Empty := False; + end; + end + else + begin + while True do + begin + case Char(S[I]) of + Char('0').. Char('9'): Dig := Ord(S[I]) - Ord('0'); + else + Break; + end; + + if Result > UInt64Div(CN_MAX_TUINT64, 10) then + Break; + if Sign and (Dig <> 0) then + Break; + + Result := Result * 10 + TUInt64(Dig); + Inc(I); + Empty := False; + end; + end; + + if (S[I] <> Char(#0)) or Empty then + Code := I + 1 - FirstIndex + else + Code := 0; +end; + +{$HINTS ON} + +function UInt64ToHex(N: TUInt64): string; +const + Digits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); + + function HC(B: Byte): string; + begin + Result := string(Digits[(B shr 4) and $0F] + Digits[B and $0F]); + end; + +begin + Result := + HC(Byte((N and $FF00000000000000) shr 56)) + + HC(Byte((N and $00FF000000000000) shr 48)) + + HC(Byte((N and $0000FF0000000000) shr 40)) + + HC(Byte((N and $000000FF00000000) shr 32)) + + HC(Byte((N and $00000000FF000000) shr 24)) + + HC(Byte((N and $0000000000FF0000) shr 16)) + + HC(Byte((N and $000000000000FF00) shr 8)) + + HC(Byte((N and $00000000000000FF))); +end; + +function UInt64ToStr(N: TUInt64): string; +begin + Result := Format('%u', [N]); +end; + +function StrToUInt64(const S: string): TUInt64; +{$IFNDEF DELPHIXE6_UP} +var + E: Integer; +{$ENDIF} +begin +{$IFDEF DELPHIXE6_UP} + Result := SysUtils.StrToUInt64(S); // StrToUInt64 only exists under XE6 or above +{$ELSE} + Result := _ValUInt64(S, E); + if E <> 0 then raise EConvertError.CreateResFmt(@SInvalidInteger, [S]); +{$ENDIF} +end; + +function UInt64Compare(A, B: TUInt64): Integer; +{$IFNDEF SUPPORT_UINT64} +var + HiA, HiB, LoA, LoB: Cardinal; +{$ENDIF} +begin +{$IFDEF SUPPORT_UINT64} + if A > B then + Result := 1 + else if A < B then + Result := -1 + else + Result := 0; +{$ELSE} + HiA := (A and $FFFFFFFF00000000) shr 32; + HiB := (B and $FFFFFFFF00000000) shr 32; + if HiA > HiB then + Result := 1 + else if HiA < HiB then + Result := -1 + else + begin + LoA := Cardinal(A and $00000000FFFFFFFF); + LoB := Cardinal(B and $00000000FFFFFFFF); + if LoA > LoB then + Result := 1 + else if LoA < LoB then + Result := -1 + else + Result := 0; + end; +{$ENDIF} +end; + +function UInt64Sqrt(N: TUInt64): TUInt64; +var + Rem, Root: TUInt64; + I: Integer; +begin + Result := 0; + if N = 0 then + Exit; + + if UInt64Compare(N, 4) < 0 then + begin + Result := 1; + Exit; + end; + + Rem := 0; + Root := 0; + + for I := 0 to 31 do + begin + Root := Root shl 1; + Inc(Root); + + Rem := Rem shl 2; + Rem := Rem or (N shr 62); + N := N shl 2; + + if UInt64Compare(Root, Rem) <= 0 then + begin + Rem := Rem - Root; + Inc(Root); + end + else + Dec(Root); + end; + Result := Root shr 1; +end; + +function UInt32IsNegative(N: Cardinal): Boolean; +begin + Result := (N and (1 shl 31)) <> 0; +end; + +function UInt64IsNegative(N: TUInt64): Boolean; +begin +{$IFDEF SUPPORT_UINT64} + Result := (N and (UInt64(1) shl 63)) <> 0; +{$ELSE} + Result := N < 0; +{$ENDIF} +end; + +// UInt64 ijһλ 1λ Index 0 ʼ +procedure UInt64SetBit(var B: TUInt64; Index: Integer); +begin + B := B or (TUInt64(1) shl Index); +end; + +// UInt64 ijһλ 0λ Index 0 ʼ +procedure UInt64ClearBit(var B: TUInt64; Index: Integer); +begin + B := B and not (TUInt64(1) shl Index); +end; + +// UInt64 ĵڼλǷ 10 ʼ +function GetUInt64BitSet(B: TUInt64; Index: Integer): Boolean; +begin + B := B and (TUInt64(1) shl Index); + Result := B <> 0; +end; + +// UInt64 1 ߶λǵڼλλ 0û 1 -1 +function GetUInt64HighBits(B: TUInt64): Integer; +begin + if B = 0 then + begin + Result := -1; + Exit; + end; + + Result := 1; + if B shr 32 = 0 then + begin + Inc(Result, 32); + B := B shl 32; + end; + if B shr 48 = 0 then + begin + Inc(Result, 16); + B := B shl 16; + end; + if B shr 56 = 0 then + begin + Inc(Result, 8); + B := B shl 8; + end; + if B shr 60 = 0 then + begin + Inc(Result, 4); + B := B shl 4; + end; + if B shr 62 = 0 then + begin + Inc(Result, 2); + B := B shl 2; + end; + Result := Result - Integer(B shr 63); // õǰ 0 + Result := 63 - Result; +end; + +// Cardinal 1 ߶λǵڼλλ 0û 1 -1 +function GetUInt32HighBits(B: Cardinal): Integer; +begin + if B = 0 then + begin + Result := -1; + Exit; + end; + + Result := 1; + if B shr 16 = 0 then + begin + Inc(Result, 16); + B := B shl 16; + end; + if B shr 24 = 0 then + begin + Inc(Result, 8); + B := B shl 8; + end; + if B shr 28 = 0 then + begin + Inc(Result, 4); + B := B shl 4; + end; + if B shr 30 = 0 then + begin + Inc(Result, 2); + B := B shl 2; + end; + Result := Result - Integer(B shr 31); // õǰ 0 + Result := 31 - Result; +end; + +function GetUInt16HighBits(B: Word): Integer; +begin + if B = 0 then + begin + Result := -1; + Exit; + end; + + Result := 1; + if B shr 8 = 0 then + begin + Inc(Result, 8); + B := B shl 8; + end; + if B shr 12 = 0 then + begin + Inc(Result, 4); + B := B shl 4; + end; + if B shr 14 = 0 then + begin + Inc(Result, 2); + B := B shl 2; + end; + Result := Result - Integer(B shr 15); // õǰ 0 + Result := 15 - Result; +end; + +function GetUInt8HighBits(B: Byte): Integer; +begin + if B = 0 then + begin + Result := -1; + Exit; + end; + + Result := 1; + if B shr 4 = 0 then + begin + Inc(Result, 4); + B := B shl 4; + end; + if B shr 6 = 0 then + begin + Inc(Result, 2); + B := B shl 2; + end; + Result := Result - Integer(B shr 7); // õǰ 0 + Result := 7 - Result; +end; + +// Int64 1 Ͷλǵڼλλ 0û 1 -1 +function GetUInt64LowBits(B: TUInt64): Integer; +var + Y: TUInt64; + N: Integer; +begin + Result := -1; + if B = 0 then + Exit; + + N := 63; + Y := B shl 32; + if Y <> 0 then + begin + Dec(N, 32); + B := Y; + end; + Y := B shl 16; + if Y <> 0 then + begin + Dec(N, 16); + B := Y; + end; + Y := B shl 8; + if Y <> 0 then + begin + Dec(N, 8); + B := Y; + end; + Y := B shl 4; + if Y <> 0 then + begin + Dec(N, 4); + B := Y; + end; + Y := B shl 2; + if Y <> 0 then + begin + Dec(N, 2); + B := Y; + end; + B := B shl 1; + Result := N - Integer(B shr 63); +end; + +// Cardinal 1 Ͷλǵڼλλ 0û 1 -1 +function GetUInt32LowBits(B: Cardinal): Integer; +var + Y, N: Integer; +begin + Result := -1; + if B = 0 then + Exit; + + N := 31; + Y := B shl 16; + if Y <> 0 then + begin + Dec(N, 16); + B := Y; + end; + Y := B shl 8; + if Y <> 0 then + begin + Dec(N, 8); + B := Y; + end; + Y := B shl 4; + if Y <> 0 then + begin + Dec(N, 4); + B := Y; + end; + Y := B shl 2; + if Y <> 0 then + begin + Dec(N, 2); + B := Y; + end; + B := B shl 1; + Result := N - Integer(B shr 31); +end; + +// Word 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 +function GetUInt16LowBits(B: Word): Integer; +var + Y, N: Integer; +begin + Result := -1; + if B = 0 then + Exit; + + N := 15; + Y := B shl 8; + if Y <> 0 then + begin + Dec(N, 8); + B := Y; + end; + Y := B shl 4; + if Y <> 0 then + begin + Dec(N, 4); + B := Y; + end; + Y := B shl 2; + if Y <> 0 then + begin + Dec(N, 2); + B := Y; + end; + B := B shl 1; + Result := N - Integer(B shr 15); +end; + +// Byte 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 +function GetUInt8LowBits(B: Byte): Integer; +var + N: Integer; +begin + Result := -1; + if B = 0 then + Exit; + + N := 7; + if B shr 4 = 0 then + begin + Dec(N, 4); + B := B shl 4; + end; + if B shr 6 = 0 then + begin + Dec(N, 2); + B := B shl 2; + end; + B := B shl 1; + Result := N - Integer(B shr 7); +end; + +// װ Int64 Modֵʱȡģģ +function Int64Mod(M, N: Int64): Int64; +begin + if M > 0 then + Result := M mod N + else + Result := N - ((-M) mod N); +end; + +// жһ 32 λ޷Ƿ 2 +function IsUInt32PowerOf2(N: Cardinal): Boolean; +begin + Result := (N and (N - 1)) = 0; +end; + +// жһ 64 λ޷Ƿ 2 +function IsUInt64PowerOf2(N: TUInt64): Boolean; +begin + Result := (N and (N - 1)) = 0; +end; + +// õһָ 32 λ޷ȵ 2 ݣ򷵻 0 +function GetUInt32PowerOf2GreaterEqual(N: Cardinal): Cardinal; +begin + Result := N - 1; + Result := Result or (Result shr 1); + Result := Result or (Result shr 2); + Result := Result or (Result shr 4); + Result := Result or (Result shr 8); + Result := Result or (Result shr 16); + Inc(Result); +end; + +// õһָ 64 λ޷ 2 ݣ򷵻 0 +function GetUInt64PowerOf2GreaterEqual(N: TUInt64): TUInt64; +begin + Result := N - 1; + Result := Result or (Result shr 1); + Result := Result or (Result shr 2); + Result := Result or (Result shr 4); + Result := Result or (Result shr 8); + Result := Result or (Result shr 16); + Result := Result or (Result shr 32); + Inc(Result); +end; + +// ж 32 λзǷ 32 λз +function IsInt32AddOverflow(A, B: Integer): Boolean; +var + C: Integer; +begin + C := A + B; + Result := ((A > 0) and (B > 0) and (C < 0)) or // ͬҽ˵ + ((A < 0) and (B < 0) and (C > 0)); +end; + +// ж 32 λ޷Ƿ 32 λ޷ +function IsUInt32AddOverflow(A, B: Cardinal): Boolean; +begin + Result := (A + B) < A; // ޷ӣֻҪСһ˵ +end; + +// ж 64 λзǷ 64 λз +function IsInt64AddOverflow(A, B: Int64): Boolean; +var + C: Int64; +begin + C := A + B; + Result := ((A > 0) and (B > 0) and (C < 0)) or // ͬҽ˵ + ((A < 0) and (B < 0) and (C > 0)); +end; + +// ж 64 λ޷Ƿ 64 λ޷ +function IsUInt64AddOverflow(A, B: TUInt64): Boolean; +begin + Result := UInt64Compare(A + B, A) < 0; // ޷ӣֻҪСһ˵ +end; + +function IsUInt64SubOverflowInt32(A: TUInt64; B: TUInt64): Boolean; +var + GT: Boolean; + R: TUInt64; +begin + GT := UInt64Compare(A, B) >= 0; // GT ʾ A >= B + if GT then + begin + R := A - B; + // ж 64 λ޷ŷΧ R Ƿ񳬹 MaxInt32 + Result := UInt64Compare(R, TUInt64(CN_MAX_INT32)) > 0; + end + else + begin + R := B - A; + // ж 64 λзŷΧ -R ǷС MinInt32Ҳж 64 λ޷ R Ƿ񳬹 MinInt32 ޷ʽ + Result := UInt64Compare(R, CN_MIN_INT32_IN_INT64) > 0; + end; +end; + +// 64 λ޷ӣA + B => R 1 λ +procedure UInt64Add(var R: TUInt64; A, B: TUInt64; out Carry: Integer); +begin + R := A + B; + if UInt64Compare(R, A) < 0 then // ޷ӣֻҪСһ˵ + Carry := 1 + else + Carry := 0; +end; + +// 64 λ޷A - B => Rнλ 1 λ +procedure UInt64Sub(var R: TUInt64; A, B: TUInt64; out Carry: Integer); +begin + R := A - B; + if UInt64Compare(R, A) > 0 then // ޷ֻҪڱ˵λ + Carry := 1 + else + Carry := 0; +end; + +// ж 32 λзǷ 32 λз +function IsInt32MulOverflow(A, B: Integer): Boolean; +var + T: Integer; +begin + T := A * B; + Result := (B <> 0) and ((T div B) <> A); +end; + +// ж 32 λ޷Ƿ 32 λ޷ +function IsUInt32MulOverflow(A, B: Cardinal): Boolean; +var + T: TUInt64; +begin + T := TUInt64(A) * TUInt64(B); + Result := (T = Cardinal(T)); +end; + +// ж 32 λ޷Ƿ 64 λзδҲ False ʱR ֱӷؽ +function IsUInt32MulOverflowInt64(A, B: Cardinal; out R: TUInt64): Boolean; +var + T: Int64; +begin + T := Int64(A) * Int64(B); + Result := T < 0; // Int64 ֵ˵ + if not Result then + R := TUInt64(T); +end; + +// ж 64 λзǷ 64 λз +function IsInt64MulOverflow(A, B: Int64): Boolean; +var + T: Int64; +begin + T := A * B; + Result := (B <> 0) and ((T div B) <> A); +end; + +// ָת֧ͣ 32/64 λ +function PointerToInteger(P: Pointer): Integer; +begin +{$IFDEF CPU64BITS} + // ôд Pointer ĵ 32 λ Integer + Result := Integer(P); +{$ELSE} + Result := Integer(P); +{$ENDIF} +end; + +// תָ֧ͣ 32/64 λ +function IntegerToPointer(I: Integer): Pointer; +begin +{$IFDEF CPU64BITS} + // ôд Pointer ĵ 32 λ Integer + Result := Pointer(I); +{$ELSE} + Result := Pointer(I); +{$ENDIF} +end; + +// Int64 Χĺ࣬Ҫ N 0 +function Int64NonNegativeAddMod(A, B, N: Int64): Int64; +begin + if IsInt64AddOverflow(A, B) then // Int64 + begin + if A > 0 then + begin + // A B 0 UInt64 ȡģδ UInt64 ޣע N δ Int64 ȡģС Int64 ޣɸֵ + Result := UInt64NonNegativeAddMod(A, B, N); + end + else + begin + // A B С 0ȡ UInt64 ȡģĺδ UInt64 ޣģٱһ +{$IFDEF SUPPORT_UINT64} + Result := UInt64(N) - UInt64NonNegativeAddMod(-A, -B, N); +{$ELSE} + Result := N - UInt64NonNegativeAddMod(-A, -B, N); +{$ENDIF} + end; + end + else // ֱӼ + Result := Int64NonNegativeMod(A + B, N); +end; + +// UInt64 Χĺ࣬Ҫ N 0 +function UInt64NonNegativeAddMod(A, B, N: TUInt64): TUInt64; +var + C, D: TUInt64; +begin + if IsUInt64AddOverflow(A, B) then // + begin + C := UInt64Mod(A, N); // ͸ģ + D := UInt64Mod(B, N); + if IsUInt64AddOverflow(C, D) then + begin + // ˵ģ󣬸ģûá + // һڵ 2^63N 2^63 + 1 + // = + 2^64 + // mod N = mod N + (2^64 - 1) mod N) + 1 + // N 2^63 + 1 2^64 - 2ǰӲֱӺһģ + Result := UInt64Mod(UInt64Mod(A + B, N) + UInt64Mod(CN_MAX_TUINT64, N) + 1, N); + end + else + Result := UInt64Mod(C + D, N); + end + else + begin + Result := UInt64Mod(A + B, N); + end; +end; + +function Int64NonNegativeMulMod(A, B, N: Int64): Int64; +var + Neg: Boolean; +begin + if N <= 0 then + raise EDivByZero.Create(SDivByZero); + + // ΧСֱ + if not IsInt64MulOverflow(A, B) then + begin + Result := A * B mod N; + if Result < 0 then + Result := Result + N; + Exit; + end; + + // ŵ + Result := 0; + if (A = 0) or (B = 0) then + Exit; + + Neg := False; + if (A < 0) and (B > 0) then + begin + A := -A; + Neg := True; + end + else if (A > 0) and (B < 0) then + begin + B := -B; + Neg := True; + end + else if (A < 0) and (B < 0) then + begin + A := -A; + B := -B; + end; + + // λѭ + while B <> 0 do + begin + if (B and 1) <> 0 then + Result := ((Result mod N) + (A mod N)) mod N; + + A := A shl 1; + if A >= N then + A := A mod N; + + B := B shr 1; + end; + + if Neg then + Result := N - Result; +end; + +function UInt64NonNegativeMulMod(A, B, N: TUInt64): TUInt64; +begin + Result := 0; + if (UInt64Compare(A, CN_MAX_UINT32) <= 0) and (UInt64Compare(B, CN_MAX_UINT32) <= 0) then + begin + Result := UInt64Mod(A * B, N); // 㹻СĻֱӳ˺ģ + end + else + begin + while B <> 0 do + begin + if (B and 1) <> 0 then + Result := UInt64NonNegativeAddMod(Result, A, N); + + A := UInt64NonNegativeAddMod(A, A, N); + // ôͳ㷨 A := A shl 1 N mod NΪ + + B := B shr 1; + end; + end; +end; + +// װķǸຯҲΪʱӸ豣֤ P 0 +function Int64NonNegativeMod(N: Int64; P: Int64): Int64; +begin + if P <= 0 then + raise EDivByZero.Create(SDivByZero); + + Result := N mod P; + if Result < 0 then + Inc(Result, P); +end; + +// Int64 ķǸָ +function Int64NonNegativPower(N: Int64; Exp: Integer): Int64; +var + T: Int64; +begin + if Exp < 0 then + raise ERangeError.Create(SRangeError) + else if Exp = 0 then + begin + if N <> 0 then + Result := 1 + else + raise EDivByZero.Create(SDivByZero); + end + else if Exp = 1 then + Result := N + else + begin + Result := 1; + T := N; + + while Exp > 0 do + begin + if (Exp and 1) <> 0 then + Result := Result * T; + + Exp := Exp shr 1; + T := T * T; + end; + end; +end; + +function Int64NonNegativeRoot(N: Int64; Exp: Integer): Int64; +var + I: Integer; + X: Int64; + X0, X1: Extended; +begin + if (Exp < 0) or (N < 0) then + raise ERangeError.Create(SRangeError) + else if Exp = 0 then + raise EDivByZero.Create(SDivByZero) + else if (N = 0) or (N = 1) then + Result := N + else if Exp = 2 then + Result := UInt64Sqrt(N) + else + begin + // ţٵ + I := GetUInt64HighBits(N) + 1; // õԼ Log2 N ֵ + I := (I div Exp) + 1; + X := 1 shl I; // õһϴ X0 ֵΪʼֵ + + X0 := X; + X1 := X0 - (Power(X0, Exp) - N) / (Exp * Power(X0, Exp - 1)); + + while True do + begin + if (Trunc(X0) = Trunc(X1)) and (Abs(X0 - X1) < 0.001) then + begin + Result := Trunc(X1); // Trunc ֻ֧ Int64˻ + Exit; + end; + + X0 := X1; + X1 := X0 - (Power(X0, Exp) - N) / (Exp * Power(X0, Exp - 1)); + end; + end; +end; + +function UInt64NonNegativPower(N: TUInt64; Exp: Integer): TUInt64; +var + T, RL, RH: TUInt64; +begin + if Exp < 0 then + raise ERangeError.Create(SRangeError) + else if Exp = 0 then + begin + if N <> 0 then + Result := 1 + else + raise EDivByZero.Create(SDivByZero); + end + else if Exp = 1 then + Result := N + else + begin + Result := 1; + T := N; + + while Exp > 0 do + begin + if (Exp and 1) <> 0 then + begin + UInt64MulUInt64(Result, T, RL, RH); + Result := RL; + end; + + Exp := Exp shr 1; + UInt64MulUInt64(T, T, RL, RH); + T := RL; + end; + end; +end; + +function UInt64NonNegativeRoot(N: TUInt64; Exp: Integer): TUInt64; +var + I: Integer; + X: TUInt64; + XN, X0, X1: Extended; +begin + if Exp < 0 then + raise ERangeError.Create(SRangeError) + else if Exp = 0 then + raise EDivByZero.Create(SDivByZero) + else if (N = 0) or (N = 1) then + Result := N + else if Exp = 2 then + Result := UInt64Sqrt(N) + else + begin + // ţٵ + I := GetUInt64HighBits(N) + 1; // õԼ Log2 N ֵ + I := (I div Exp) + 1; + X := 1 shl I; // õһϴ X0 ֵΪʼֵ + + X0 := UInt64ToExtended(X); + XN := UInt64ToExtended(N); + X1 := X0 - (Power(X0, Exp) - XN) / (Exp * Power(X0, Exp - 1)); + + while True do + begin + if (ExtendedToUInt64(X0) = ExtendedToUInt64(X1)) and (Abs(X0 - X1) < 0.001) then + begin + Result := ExtendedToUInt64(X1); + Exit; + end; + + X0 := X1; + X1 := X0 - (Power(X0, Exp) - XN) / (Exp * Power(X0, Exp - 1)); + end; + end; +end; + +function IsUInt128BitSet(Lo, Hi: TUInt64; N: Integer): Boolean; +begin + if N < 64 then + Result := (Lo and (TUInt64(1) shl N)) <> 0 + else + begin + Dec(N, 64); + Result := (Hi and (TUInt64(1) shl N)) <> 0; + end; +end; + +procedure SetUInt128Bit(var Lo, Hi: TUInt64; N: Integer); +begin + if N < 64 then + Lo := Lo or (TUInt64(1) shl N) + else + begin + Dec(N, 64); + Hi := Hi or (TUInt64(1) shl N); + end; +end; + +procedure ClearUInt128Bit(var Lo, Hi: TUInt64; N: Integer); +begin + if N < 64 then + Lo := Lo and not (TUInt64(1) shl N) + else + begin + Dec(N, 64); + Hi := Hi and not (TUInt64(1) shl N); + end; +end; + +function UnsignedAddWithLimitRadix(A, B, C: Cardinal; var R: Cardinal; + L, H: Cardinal): Cardinal; +begin + R := A + B + C; + if R > H then // нλ + begin + A := H - L + 1; // õ + B := R - L; // õ L ֵ + + Result := B div A; // Ƶĵڼͽ + R := L + (B mod A); // ȥƺ + end + else + Result := 0; +end; + +procedure InternalQuickSort(Mem: Pointer; L, R: Integer; ElementByteSize: Integer; + CompareProc: TCnMemSortCompareProc); +var + I, J, P: Integer; +begin + repeat + I := L; + J := R; + P := (L + R) shr 1; + repeat + while CompareProc(Pointer(TCnNativeInt(Mem) + I * ElementByteSize), + Pointer(TCnNativeInt(Mem) + P * ElementByteSize), ElementByteSize) < 0 do + Inc(I); + while CompareProc(Pointer(TCnNativeInt(Mem) + J * ElementByteSize), + Pointer(TCnNativeInt(Mem) + P * ElementByteSize), ElementByteSize) > 0 do + Dec(J); + + if I <= J then + begin + MemorySwap(Pointer(TCnNativeInt(Mem) + I * ElementByteSize), + Pointer(TCnNativeInt(Mem) + J * ElementByteSize), ElementByteSize); + + if P = I then + P := J + else if P = J then + P := I; + Inc(I); + Dec(J); + end; + until I > J; + + if L < J then + InternalQuickSort(Mem, L, J, ElementByteSize, CompareProc); + L := I; + until I >= R; +end; + +function DefaultCompareProc(P1, P2: Pointer; ElementByteSize: Integer): Integer; +begin + Result := MemoryCompare(P1, P2, ElementByteSize); +end; + +procedure MemoryQuickSort(Mem: Pointer; ElementByteSize: Integer; + ElementCount: Integer; CompareProc: TCnMemSortCompareProc); +begin + if (Mem <> nil) and (ElementCount > 0) and (ElementCount > 0) then + begin + if Assigned(CompareProc) then + InternalQuickSort(Mem, 0, ElementCount - 1, ElementByteSize, CompareProc) + else + InternalQuickSort(Mem, 0, ElementCount - 1, ElementByteSize, DefaultCompareProc); + end; +end; + +{$IFDEF COMPILER5} + +function BoolToStr(Value: Boolean; UseBoolStrs: Boolean): string; +begin + if UseBoolStrs then + begin + if Value then + Result := 'True' + else + Result := 'False'; + end + else + begin + if Value then + Result := '-1' + else + Result := '0'; + end; +end; + +{$ENDIF} + +// =========================== ѭλ ==================================== + +function RotateLeft16(A: Word; N: Integer): Word; +begin + Result := (A shl N) or (A shr (16 - N)); +end; + +function RotateRight16(A: Word; N: Integer): Word; +begin + Result := (A shr N) or (A shl (16 - N)); +end; + +function RotateLeft32(A: Cardinal; N: Integer): Cardinal; +begin + Result := (A shl N) or (A shr (32 - N)); +end; + +function RotateRight32(A: Cardinal; N: Integer): Cardinal; +begin + Result := (A shr N) or (A shl (32 - N)); +end; + +function RotateLeft64(A: TUInt64; N: Integer): TUInt64; +begin + Result := (A shl N) or (A shr (64 - N)); +end; +function RotateRight64(A: TUInt64; N: Integer): TUInt64; +begin + Result := (A shr N) or (A shl (64 - N)); +end; + +initialization + FByteOrderIsBigEndian := CurrentByteOrderIsBigEndian; + +end. diff --git a/CnPack/Crypto/CnPemUtils.dcu b/CnPack/Crypto/CnPemUtils.dcu new file mode 100644 index 0000000000000000000000000000000000000000..b14a181ea709064b3476fff66071bca6173099f8 GIT binary patch literal 16968 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 HV0HfoxNO-h literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnPemUtils.pas b/CnPack/Crypto/CnPemUtils.pas new file mode 100644 index 0000000..f4d5719 --- /dev/null +++ b/CnPack/Crypto/CnPemUtils.pas @@ -0,0 +1,1219 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnPemUtils; +{* |
+================================================================================
+* ƣ
+* ԪƣPEM ʽ뵥Ԫ
+* ԪߣCnPack 
+*     עԪʵ PEM ʽĶȡ뱣棬ӽܻơ
+*           Ҳʵ PKCS1/PKCS5/PKCS7/ISO10126 ȶ봦ơ
+*           ע֧ PKCS12 淶֤鼰Կװʽ
+* ƽ̨WinXP + Delphi 5.0
+* ݲԣδ
+*   õԪ豾ػ
+* ޸ļ¼2024.05.27 V1.6
+*                ISO10126 Ĵ
+*           2023.12.14 V1.5
+*                SaveMemoryToPemStream δ
+*           2022.03.09 V1.4
+*                PKCS5 Ĵ
+*           2021.05.14 V1.3
+*               ĸ PKCS7 Ĵ
+*           2020.03.27 V1.2
+*               ģ Openssl ʵ PEM ļд룬ֲֻּ֧㷨
+*               Ŀǰд des/3des/aes128/192/256 PKCS7 룬 Openssl 1.0.2g
+*           2020.03.23 V1.1
+*               ģ Openssl ʵ PEM ļܶȡֲֻּ֧㷨
+*               Ŀǰȡ des/3des/aes128/192/256 PKCS7 룬 Openssl 1.0.2g
+*           2020.03.18 V1.0
+*               Ԫ CnRSA ж
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, CnNative, CnRandom, CnKDF, CnBase64, CnAES, CnDES; + +const + CN_PKCS1_BLOCK_TYPE_PRIVATE_00 = 00; + {* PKCS1 ʱĿֵֶһĬӦ RSA ˽Կܳ} + + CN_PKCS1_BLOCK_TYPE_PRIVATE_FF = 01; + {* PKCS1 ʱĿֵֶĬӦ RSA ˽Կǩ} + + CN_PKCS1_BLOCK_TYPE_PUBLIC_RANDOM = 02; + {* PKCS1 ʱĿֵֶĬӦ RSA ĹԿܳ} + +type + TCnKeyHashMethod = (ckhMd5, ckhSha256); + {* PEM ʽֵ֧Ӵ} + + TCnKeyEncryptMethod = (ckeNone, ckeDES, cke3DES, ckeAES128, ckeAES192, ckeAES256); + {* PEM ʽֵ֧ļ} + +// ======================= PEM ļдּ֧ӽ ======================== + +function LoadPemFileToMemory(const FileName: string; const ExpectHead: string; + const ExpectTail: string; MemoryStream: TMemoryStream; const Password: string = ''; + KeyHashMethod: TCnKeyHashMethod = ckhMd5): Boolean; +{* PEM ʽļָ֤ͷβʵݲܽ Base64 롣 + + + const FileName: string - ļ + const ExpectHead: string - ͷ + const ExpectTail: string - β + MemoryStream: TMemoryStream - ڴ + const Password: string - ļܣڴṩ + KeyHashMethod: TCnKeyHashMethod - ļʹõӴ + + ֵBoolean - ضǷɹ +} + +function LoadPemStreamToMemory(Stream: TStream; const ExpectHead: string; + const ExpectTail: string; MemoryStream: TMemoryStream; const Password: string = ''; + KeyHashMethod: TCnKeyHashMethod = ckhMd5): Boolean; +{* PEM ʽļָ֤ͷβʵݲܽ Base64 롣 + + + Stream: TStream - + const ExpectHead: string - ͷ + const ExpectTail: string - β + MemoryStream: TMemoryStream - ڴ + const Password: string - ܣڴṩ + KeyHashMethod: TCnKeyHashMethod - ʹõӴ + + ֵBoolean - ضǷɹ +} + +function SaveMemoryToPemFile(const FileName: string; const Head: string; const Tail: string; + MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod = ckeNone; + KeyHashMethod: TCnKeyHashMethod = ckhMd5; const Password: string = ''; Append: Boolean = False): Boolean; +{* Stream ݽ Base64 ܷвļͷβдļAppend Ϊ True ʱʾ׷ӡ + + + const FileName: string - дļ + const Head: string - дͷ + const Tail: string - дβ + MemoryStream: TMemoryStream - д + KeyEncryptMethod: TCnKeyEncryptMethod - üͣĬϲ + KeyHashMethod: TCnKeyHashMethod - Ӵ + const Password: string - 룬򴫿 + Append: Boolean - Ƿ׷ӵķʽд + + ֵBoolean - Ƿдɹ +} + +function SaveMemoryToPemStream(Stream: TStream; const Head: string; const Tail: string; + MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod = ckeNone; + KeyHashMethod: TCnKeyHashMethod = ckhMd5; const Password: string = ''; Append: Boolean = False): Boolean; +{* Stream ݽ Base64 ܷвͷβдAppend Ϊ True ʱʾ׷ӡ + + + Stream: TStream - д + const Head: string - дͷ + const Tail: string - дβ + MemoryStream: TMemoryStream - д + KeyEncryptMethod: TCnKeyEncryptMethod - üͣĬϲ + KeyHashMethod: TCnKeyHashMethod - ӴͣĬϲӴ + const Password: string - 룬򴫿 + Append: Boolean - Ƿ׷ӵķʽд + + ֵBoolean - Ƿдɹ +} + +// ===================== PKCS1 / PKCS7 Padding 봦 ==================== + +function AddPKCS1Padding(PaddingType: Integer; BlockSize: Integer; Data: Pointer; + DataByteLen: Integer; OutStream: TStream): Boolean; +{* ݿ鲹д Stream Уسɹڲô롣 + PaddingType ȡ 012BlockLen ֽ 128 ȡʽ + EB = 00 || BT || PS || 00 || D + 00 ǰ涨ֽڣBT 1 ֽڵ PaddingType0 1 2 ֱ 00 FF + PS Ķֽݣ 00 ǹ涨Ľβֽڡ + + + PaddingType: Integer - ͣȡ 0 1 2 + BlockSize: Integer - ֽڳ + Data: Pointer - ݿĵַ + DataByteLen: Integer - ݿֽڳ + OutStream: TStream - + + ֵBoolean - ضǷӳɹ +} + +function RemovePKCS1Padding(InData: Pointer; InDataByteLen: Integer; OutBuf: Pointer; + out OutByteLen: Integer): Boolean; +{* ȥݿ PKCS1 PaddingسɹOutBuf ָĿóб֤ + ɹOutLen ԭݳȡ + + + InData: Pointer - ȥݿĵַ + InDataByteLen: Integer - ȥݿֽڳ + OutBuf: Pointer - ȥݵ䳤ȱ㹻 + out OutByteLen: Integer - ȥݳ + + ֵBoolean - ضǷȥɹ +} + +function GetPKCS7PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; +{* ԭʼ鳤ȼ PKCS7 ijȡ + + + OrignalByteLen: Integer - ԭʼֽڳ + BlockSize: Integer - PKCS7 ֽڳ + + ֵInteger - PKCS7 ֽڳ +} + +procedure AddPKCS7Padding(Stream: TMemoryStream; BlockSize: Integer); +{* ĩβ PKCS7 涨䡰ݡ + + + Stream: TMemoryStream - ڴݣݽ׷дβ + BlockSize: Integer - PKCS7 ֽڳ + + ֵޣ +} + +procedure RemovePKCS7Padding(Stream: TMemoryStream); +{* ȥ PKCS7 涨ĩβ䡰ݡ + + + Stream: TMemoryStream - ȥڴ + + ֵޣ} + +function StrAddPKCS7Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; +{* ַĩβ PKCS7 涨䡰ݡ + + + const Str: AnsiString - ַ + BlockSize: Integer - PKCS7 ֽڳ + + ֵAnsiString - ضַ +} + +function StrRemovePKCS7Padding(const Str: AnsiString): AnsiString; +{* ȥ PKCS7 涨ַĩβ䡰ݡ + + + const Str: AnsiString - ȥַ + + ֵAnsiString - ȥַ +} + +procedure BytesAddPKCS7Padding(var Data: TBytes; BlockSize: Integer); +{* ֽĩβ PKCS7 涨䡰ݡ + + + var Data: TBytes - ֽ飬ݽ׷β + BlockSize: Integer - PKCS7 ֽڳ + + ֵޣ +} + +procedure BytesRemovePKCS7Padding(var Data: TBytes); +{* ȥ PKCS7 涨ֽĩβ䡰ݡ + + + var Data: TBytes - ȥֽ + + ֵޣ +} + +procedure AddPKCS5Padding(Stream: TMemoryStream); +{* ĩβ PKCS5 涨䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + Stream: TMemoryStream - ڴݽ׷β + + ֵޣ +} + +procedure RemovePKCS5Padding(Stream: TMemoryStream); +{* ȥ PKCS7 涨ĩβ䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + Stream: TMemoryStream - ȥڴ + + ֵޣ +} + +function StrAddPKCS5Padding(const Str: AnsiString): AnsiString; +{* ַĩβ PKCS5 涨䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + const Str: AnsiString - ַ + + ֵAnsiString - ضַ +} + +function StrRemovePKCS5Padding(const Str: AnsiString): AnsiString; +{* ȥ PKCS5 涨ַĩβ䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + const Str: AnsiString - ȥַ + + ֵAnsiString - ȥַ +} + +procedure BytesAddPKCS5Padding(var Data: TBytes); +{* ֽĩβ PKCS5 涨䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + var Data: TBytes - ֽ飬ݽ׷β + + ֵޣ +} + +procedure BytesRemovePKCS5Padding(var Data: TBytes); +{* ȥ PKCS7 涨ֽĩβ䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + var Data: TBytes - ȥֽ + + ֵޣ +} + +function GetISO10126PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; +{* ԭʼ鳤ȼ ISO10126Padding ijȡ + + + OrignalByteLen: Integer - ԭʼֽڳ + BlockSize: Integer - ISO10126 ֽڳ + + ֵInteger - PKCS7 ֽڳ +} + +procedure AddISO10126Padding(Stream: TMemoryStream; BlockSize: Integer); +{* ĩβ ISO10126Padding 涨䡰ͼݡ + + + Stream: TMemoryStream - ڴݽ׷β + BlockSize: Integer - ISO10126 ֽڳ + + ֵޣ +} + +procedure RemoveISO10126Padding(Stream: TMemoryStream); +{* ȥ ISO10126Padding 涨ĩβ䡰ͼݡ + + + Stream: TMemoryStream - ȥڴ + + ֵޣ +} + +function StrAddISO10126Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; +{* ַĩβ ISO10126Padding 涨䡰ͼݡ + + + const Str: AnsiString - ַ + BlockSize: Integer - ISO10126 ֽڴС + + ֵAnsiString - ضַ +} + +function StrRemoveISO10126Padding(const Str: AnsiString): AnsiString; +{* ȥ ISO10126Padding 涨ַĩβ䡰ͼݡ + + + const Str: AnsiString - ȥַ + + ֵAnsiString - ȥַ +} + +procedure BytesAddISO10126Padding(var Data: TBytes; BlockSize: Integer); +{* ֽĩβ ISO10126Padding 涨䡰ͼݡ + + + var Data: TBytes - ֽ飬ݽ׷β + BlockSize: Integer - ISO10126 ֽڳ + + ֵޣ +} + +procedure BytesRemoveISO10126Padding(var Data: TBytes); +{* ȥ ISO10126Padding 涨ֽĩβ䡰ͼݡ + + + var Data: TBytes - ȥֽ + + ֵޣ +} + +implementation + +const + PKCS1_PADDING_SIZE = 11; // һǰ 00һֽڡ 8 ֽ䣬һ 00 β + PKCS5_BLOCK_SIZE = 8; + + ENC_HEAD_PROCTYPE = 'Proc-Type:'; + ENC_HEAD_PROCTYPE_NUM = '4'; + ENC_HEAD_ENCRYPTED = 'ENCRYPTED'; + ENC_HEAD_DEK = 'DEK-Info:'; + + ENC_TYPE_AES128 = 'AES-128'; + ENC_TYPE_AES192 = 'AES-192'; + ENC_TYPE_AES256 = 'AES-256'; + ENC_TYPE_DES = 'DES'; + ENC_TYPE_3DES = 'DES-EDE3'; + + ENC_BLOCK_CBC = 'CBC'; + + ENC_TYPE_STRS: array[TCnKeyEncryptMethod] of string = + ('', ENC_TYPE_DES, ENC_TYPE_3DES, ENC_TYPE_AES128, ENC_TYPE_AES192, ENC_TYPE_AES256); + + ENC_TYPE_BLOCK_SIZE: array[TCnKeyEncryptMethod] of Byte = + (0, 8, 8, 16, 16, 16); + +function Min(A, B: Integer): Integer; +begin + if A < B then + Result := A + else + Result := B; +end; + +function AddPKCS1Padding(PaddingType, BlockSize: Integer; Data: Pointer; + DataByteLen: Integer; OutStream: TStream): Boolean; +var + I: Integer; + B, F: Byte; +begin + Result := False; + if (Data = nil) or (DataByteLen <= 0) then + Exit; + + // + if DataByteLen > BlockSize - PKCS1_PADDING_SIZE then + Exit; + + B := 0; + OutStream.Write(B, 1); // дǰֽ 00 + B := PaddingType; + F := BlockSize - DataByteLen - 3; // 3 ʾһǰ 00һֽڡһ 00 β + + OutStream.Write(B, 1); + case PaddingType of + CN_PKCS1_BLOCK_TYPE_PRIVATE_00: + begin + B := 0; + for I := 1 to F do + OutStream.Write(B, 1); + end; + CN_PKCS1_BLOCK_TYPE_PRIVATE_FF: + begin + B := $FF; + for I := 1 to F do + OutStream.Write(B, 1); + end; + CN_PKCS1_BLOCK_TYPE_PUBLIC_RANDOM: + begin + Randomize; + for I := 1 to F do + begin + B := Trunc(Random(255)); + if B = 0 then + Inc(B); + OutStream.Write(B, 1); + end; + end; + else + Exit; + end; + + B := 0; + OutStream.Write(B, 1); + OutStream.Write(Data^, DataByteLen); + Result := True; +end; + +function RemovePKCS1Padding(InData: Pointer; InDataByteLen: Integer; OutBuf: Pointer; + out OutByteLen: Integer): Boolean; +var + P: PAnsiChar; + I, J, Start: Integer; +begin + Result := False; + OutByteLen := 0; + I := 0; + + P := PAnsiChar(InData); + while P[I] = #0 do // ַһ #0Ѿȥ + Inc(I); + + if I >= InDataByteLen then + Exit; + + Start := 0; + case Ord(P[I]) of + CN_PKCS1_BLOCK_TYPE_PRIVATE_00: + begin + // P[I + 1] ʼѰҷ 00 + J := I + 1; + while J < InDataByteLen do + begin + if P[J] <> #0 then + begin + Start := J; + Break; + end; + Inc(J); + end; + end; + CN_PKCS1_BLOCK_TYPE_PRIVATE_FF, + CN_PKCS1_BLOCK_TYPE_PUBLIC_RANDOM: + begin + // P[I + 1] ʼѰҵһ 00 ı + J := I + 1; + while J < InDataByteLen do + begin + if P[J] = #0 then + begin + Start := J; + Break; + end; + Inc(J); + end; + + if Start <> 0 then + Inc(Start); + end; + end; + + if Start > 0 then + begin + Move(P[Start], OutBuf^, InDataByteLen - Start); + OutByteLen := InDataByteLen - Start; + Result := True; + end; +end; + +function GetPKCS7PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; +var + R: Byte; +begin + R := OrignalByteLen mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + Result := OrignalByteLen + R; +end; + +procedure AddPKCS7Padding(Stream: TMemoryStream; BlockSize: Integer); +var + R: Byte; + Buf: array[0..255] of Byte; +begin + R := Stream.Size mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + FillChar(Buf[0], R, R); + Stream.Position := Stream.Size; + Stream.Write(Buf[0], R); +end; + +procedure RemovePKCS7Padding(Stream: TMemoryStream); +var + L: Byte; + Len: Cardinal; + Mem: Pointer; +begin + // ȥ Stream ĩβ 9 9 Padding + if Stream.Size > 1 then + begin + Stream.Position := Stream.Size - 1; + Stream.Read(L, 1); + + if Stream.Size - L < 0 then // ߴ粻ף + Exit; + + Len := Stream.Size - L; + Mem := GetMemory(Len); + if Mem <> nil then + begin + Move(Stream.Memory^, Mem^, Len); + Stream.Clear; + Stream.Write(Mem^, Len); + FreeMemory(Mem); + end; + end; +end; + +function StrAddPKCS7Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; +var + I, L: Integer; + R: Byte; +begin + L := Length(Str); + R := L mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + SetLength(Result, L + R); + if L > 0 then + Move(Str[1], Result[1], L); + + for I := 1 to R do + Result[L + I] := AnsiChar(R); +end; + +function StrRemovePKCS7Padding(const Str: AnsiString): AnsiString; +var + L: Integer; + V: Byte; +begin + Result := Str; + if Result = '' then + Exit; + + L := Length(Result); + V := Ord(Result[L]); // ĩǼʾ˼ + + if V <= L then + Delete(Result, L - V + 1, V); +end; + +procedure AddPKCS5Padding(Stream: TMemoryStream); +begin + AddPKCS7Padding(Stream, PKCS5_BLOCK_SIZE); +end; + +procedure RemovePKCS5Padding(Stream: TMemoryStream); +begin + RemovePKCS7Padding(Stream); +end; + +function StrAddPKCS5Padding(const Str: AnsiString): AnsiString; +begin + Result := StrAddPKCS7Padding(Str, PKCS5_BLOCK_SIZE); +end; + +function StrRemovePKCS5Padding(const Str: AnsiString): AnsiString; +begin + Result := StrRemovePKCS7Padding(Str); +end; + +procedure BytesAddPKCS7Padding(var Data: TBytes; BlockSize: Integer); +var + R: Byte; + L, I: Integer; +begin + L := Length(Data); + R := L mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + SetLength(Data, L + R); + for I := 0 to R - 1 do + Data[L + I] := R; +end; + +procedure BytesRemovePKCS7Padding(var Data: TBytes); +var + L: Integer; + V: Byte; +begin + L := Length(Data); + if L = 0 then + Exit; + + V := Ord(Data[L - 1]); // ĩǼʾ˼ֽ + + if V <= L then + SetLength(Data, L - V); +end; + +procedure BytesAddPKCS5Padding(var Data: TBytes); +begin + BytesAddPKCS7Padding(Data, PKCS5_BLOCK_SIZE); +end; + +procedure BytesRemovePKCS5Padding(var Data: TBytes); +begin + BytesRemovePKCS7Padding(Data); +end; + +function GetISO10126PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; +begin + Result := GetPKCS7PaddingByteLength(OrignalByteLen, BlockSize); // Ϊֱͬӵ +end; + +procedure AddISO10126Padding(Stream: TMemoryStream; BlockSize: Integer); +var + R: Byte; + Buf: array[0..255] of Byte; +begin + R := Stream.Size mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + FillChar(Buf[0], R, 0); + Buf[R - 1] := R; + Stream.Position := Stream.Size; + Stream.Write(Buf[0], R); +end; + +procedure RemoveISO10126Padding(Stream: TMemoryStream); +begin + RemovePKCS7Padding(Stream); // Ϊֱͬӵ +end; + +function StrAddISO10126Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; +var + I, L: Integer; + R: Byte; +begin + L := Length(Str); + R := L mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + SetLength(Result, L + R); + if L > 0 then + Move(Str[1], Result[1], L); + + if R > 1 then + begin + for I := 1 to R - 1 do + Result[L + I] := #0; + end; + Result[L + R] := AnsiChar(R); +end; + +function StrRemoveISO10126Padding(const Str: AnsiString): AnsiString; +begin + Result := StrRemovePKCS7Padding(Str); // Ϊֱͬӵ +end; + +procedure BytesAddISO10126Padding(var Data: TBytes; BlockSize: Integer); +var + R: Byte; + L, I: Integer; +begin + L := Length(Data); + R := L mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + SetLength(Data, L + R); + if R > 1 then + begin + for I := 0 to R - 2 do + Data[L + I] := 0; + end; + Data[L - 1 + R] := R; +end; + +procedure BytesRemoveISO10126Padding(var Data: TBytes); +begin + BytesRemovePKCS7Padding(Data); // Ϊֱͬӵ +end; + +function EncryptPemStream(KeyHash: TCnKeyHashMethod; KeyEncrypt: TCnKeyEncryptMethod; + Stream: TStream; const Password: string; out EncryptedHead: string): Boolean; +const + CRLF = #13#10; +var + ES: TMemoryStream; + Keys: array[0..31] of Byte; //  Key Ҳֻ 32 ֽ + IvStr: AnsiString; + HexIv: string; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AesIv: TCnAESBuffer; + DesKey: TCnDESKey; + Des3Key: TCn3DESKey; + DesIv: TCnDESIv; +begin + Result := False; + + // + if (KeyEncrypt = ckeNone) or (Password = '') then + Exit; + + // Iv + SetLength(IvStr, ENC_TYPE_BLOCK_SIZE[KeyEncrypt]); + CnRandomFillBytes(@(IvStr[1]), ENC_TYPE_BLOCK_SIZE[KeyEncrypt]); + HexIv := DataToHex(@(IvStr[1]), ENC_TYPE_BLOCK_SIZE[KeyEncrypt], True); // Ҫд + + EncryptedHead := ENC_HEAD_PROCTYPE + ' ' + ENC_HEAD_PROCTYPE_NUM + ',' + ENC_HEAD_ENCRYPTED + CRLF; + EncryptedHead := EncryptedHead + ENC_HEAD_DEK + ' ' + ENC_TYPE_STRS[KeyEncrypt] + + '-' + ENC_BLOCK_CBC + ',' + HexIv + CRLF; + + ES := TMemoryStream.Create; + Stream.Position := 0; + + try + if KeyHash = ckhMd5 then + begin + if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys)) then + Exit; + end + else if KeyHash = ckhSha256 then + begin + if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys), ckdSha256) then + Exit; + end + else + Exit; + + case KeyEncrypt of + ckeDES: + begin + Move(Keys[0], DesKey[0], SizeOf(TCnDESKey)); + Move(IvStr[1], DesIv[0], SizeOf(TCnDESIv)); + + DESEncryptStreamCBC(Stream, Stream.Size, DesKey, DesIv, ES); + Result := True; + end; + cke3DES: + begin + Move(Keys[0], Des3Key[0], SizeOf(TCn3DESKey)); + Move(IvStr[1], DesIv[0], SizeOf(TCn3DESIv)); + + TripleDESEncryptStreamCBC(Stream, Stream.Size, Des3Key, DesIv, ES); + Result := True; + end; + ckeAES128: + begin + Move(Keys[0], AESKey128[0], SizeOf(TCnAESKey128)); + Move(IvStr[1], AesIv[0], SizeOf(TCnAESBuffer)); + + EncryptAES128StreamCBC(Stream, Stream.Size, AESKey128, AesIv, ES); + Result := True; + end; + ckeAES192: + begin + Move(Keys[0], AESKey192[0], SizeOf(TCnAESKey192)); + Move(IvStr[1], AesIv[0], SizeOf(TCnAESBuffer)); + + EncryptAES192StreamCBC(Stream, Stream.Size, AESKey192, AesIv, ES); + Result := True; + end; + ckeAES256: + begin + Move(Keys[0], AESKey256[0], SizeOf(TCnAESKey256)); + Move(IvStr[1], AesIv[0], SizeOf(TCnAESBuffer)); + + EncryptAES256StreamCBC(Stream, Stream.Size, AESKey256, AesIv, ES); + Result := True; + end; + end; + finally + if ES.Size > 0 then + begin + // ES д Stream + Stream.Size := 0; + Stream.Position := 0; + ES.SaveToStream(Stream); + Stream.Position := 0; + end; + ES.Free; + end; +end; + +// ü㷨㡢ʼ⿪ Base64 Sд Stream +function DecryptPemString(const S, M1, M2, HexIv, Password: string; Stream: TMemoryStream; + KeyHash: TCnKeyHashMethod): Boolean; +var + DS: TMemoryStream; + Keys: array[0..31] of Byte; //  Key Ҳֻ 32 ֽ + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + IvStr: AnsiString; + AesIv: TCnAESBuffer; + DesKey: TCnDESKey; + Des3Key: TCn3DESKey; + DesIv: TCnDESIv; +begin + Result := False; + DS := nil; + + if (M1 = '') or (M2 = '') or (HexIv = '') or (Password = '') then + Exit; + + try + DS := TMemoryStream.Create; + if ECN_BASE64_OK <> Base64Decode(AnsiString(S), DS, False) then + Exit; + + DS.Position := 0; + SetLength(IvStr, HexToData(HexIv)); + if Length(IvStr) > 0 then + HexToData(HexIv, @IvStr[1]); + + // Salt Լ Hash 㷨ӽܵ Key + FillChar(Keys[0], SizeOf(Keys), 0); + if KeyHash = ckhMd5 then + begin + if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys)) then + Exit; + end + else if KeyHash = ckhSha256 then + begin + if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys), ckdSha256) then + Exit; + end + else + Exit; + + // DS ģҪ⵽ Stream + if (M1 = ENC_TYPE_AES256) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ AES-256-CBC ܵ + Move(Keys[0], AESKey256[0], SizeOf(TCnAESKey256)); + Move(IvStr[1], AesIv[0], Min(SizeOf(TCnAESBuffer), Length(IvStr))); + + DecryptAES256StreamCBC(DS, DS.Size, AESKey256, AesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end + else if (M1 = ENC_TYPE_AES192) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ AES-192-CBC ܵ + Move(Keys[0], AESKey192[0], SizeOf(TCnAESKey192)); + Move(IvStr[1], AesIv[0], Min(SizeOf(TCnAESBuffer), Length(IvStr))); + + DecryptAES192StreamCBC(DS, DS.Size, AESKey192, AesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end + else if (M1 = ENC_TYPE_AES128) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ AES-128-CBC ܵģ D5 òƿ Bug ³ AV + Move(Keys[0], AESKey128[0], SizeOf(TCnAESKey128)); + Move(IvStr[1], AesIv[0], Min(SizeOf(TCnAESBuffer), Length(IvStr))); + + DecryptAES128StreamCBC(DS, DS.Size, AESKey128, AesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end + else if (M1 = ENC_TYPE_DES) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ DES-CBC ܵ + Move(Keys[0], DesKey[0], SizeOf(TCnDESKey)); + Move(IvStr[1], DesIv[0], Min(SizeOf(TCnDESIv), Length(IvStr))); + + DESDecryptStreamCBC(DS, DS.Size, DesKey, DesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end + else if (M1 = ENC_TYPE_3DES) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ 3DES-CBC ܵ + Move(Keys[0], Des3Key[0], SizeOf(TCn3DESKey)); + Move(IvStr[1], DesIv[0], Min(SizeOf(TCn3DESIv), Length(IvStr))); + + TripleDESDecryptStreamCBC(DS, DS.Size, Des3Key, DesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end; + finally + DS.Free; + end; +end; + +function LoadPemStreamToMemory(Stream: TStream; const ExpectHead, ExpectTail: string; + MemoryStream: TMemoryStream; const Password: string; KeyHashMethod: TCnKeyHashMethod): Boolean; +var + I, J, HeadIndex, TailIndex: Integer; + S, L1, L2, M1, M2, M3: string; + Sl: TStringList; +begin + Result := False; + + if (Stream <> nil) and (Stream.Size > 0) and (ExpectHead <> '') and (ExpectTail <> '') then + begin + Sl := TStringList.Create; + try + Sl.LoadFromStream(Stream); + if Sl.Count > 2 then + begin + HeadIndex := -1; + for I := 0 to Sl.Count - 1 do + begin + if Trim(Sl[I]) = ExpectHead then + begin + HeadIndex := I; + Break; + end; + end; + + if HeadIndex < 0 then + Exit; + + if HeadIndex > 0 then + for I := 0 to HeadIndex - 1 do + Sl.Delete(0); + + // ҵͷˣβ + + TailIndex := -1; + for I := 0 to Sl.Count - 1 do + begin + if Trim(Sl[I]) = ExpectTail then + begin + TailIndex := I; + Break; + end; + end; + + if TailIndex > 0 then // ҵβͣɾβͺĶ + begin + if TailIndex < Sl.Count - 1 then + for I := Sl.Count - 1 downto TailIndex + 1 do + Sl.Delete(Sl.Count - 1); + end + else + Exit; + + if Sl.Count < 2 then // ûݣ˳ + Exit; + + // ͷβ֤ͨǰжǷ + L1 := Sl[1]; + if Pos(ENC_HEAD_PROCTYPE, L1) = 1 then // Ǽܵ + begin + Delete(L1, 1, Length(ENC_HEAD_PROCTYPE)); + I := Pos(',', L1); + if I <= 1 then + Exit; + + if Trim(Copy(L1, 1, I - 1)) <> ENC_HEAD_PROCTYPE_NUM then + Exit; + + if Trim(Copy(L1, I + 1, MaxInt)) <> ENC_HEAD_ENCRYPTED then + Exit; + + // ProcType: 4,ENCRYPTED жͨ + + L2 := Sl[2]; + if Pos(ENC_HEAD_DEK, L2) <> 1 then + Exit; + + Delete(L2, 1, Length(ENC_HEAD_DEK)); + I := Pos(',', L2); + if I <= 1 then + Exit; + + M1 := Trim(Copy(L2, 1, I - 1)); // õ AES256-CBC + M3 := UpperCase(Trim(Copy(L2, I + 1, MaxInt))); // õʱʹõijʼ + I := Pos('-', M1); + if I <= 1 then + Exit; + J := Pos('-', Copy(M1, I + 1, MaxInt)); + if J > 0 then + I := I + J; // AES-256-CBC + + M2 := UpperCase(Trim(Copy(M1, I + 1, MaxInt))); // õģʽ ECB CBC + M1 := UpperCase(Trim(Copy(M1, 1, I - 1))); // õ㷨 DES AES + + // ͷβȫɾ + Sl.Delete(Sl.Count - 1); + Sl.Delete(0); + Sl.Delete(0); + Sl.Delete(0); + + S := ''; + for I := 0 to Sl.Count - 1 do + S := S + Sl[I]; + + S := Trim(S); + + Result := DecryptPemString(S, M1, M2, M3, Password, MemoryStream, KeyHashMethod); + end + else // δܵģƴճ Base64 + begin + Sl.Delete(Sl.Count - 1); + Sl.Delete(0); + S := ''; + for I := 0 to Sl.Count - 1 do + S := S + Sl[I]; + + S := Trim(S); + + // To De Base64 S + MemoryStream.Clear; +{$IFDEF UNICODE} + Result := (ECN_BASE64_OK = Base64Decode(AnsiString(S), MemoryStream, False)); +{$ELSE} + Result := (ECN_BASE64_OK = Base64Decode(S, MemoryStream, False)); +{$ENDIF} + end; + end; + finally + Sl.Free; + end; + end; +end; + +function LoadPemFileToMemory(const FileName, ExpectHead, ExpectTail: string; + MemoryStream: TMemoryStream; const Password: string; KeyHashMethod: TCnKeyHashMethod): Boolean; +var + Stream: TStream; +begin + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + Result := LoadPemStreamToMemory(Stream, ExpectHead, ExpectTail, MemoryStream, Password, KeyHashMethod); + finally + Stream.Free; + end; +end; + +procedure SplitStringToList(const S: string; List: TStrings); +const + LINE_WIDTH = 64; +var + C, R: string; +begin + if List = nil then + Exit; + + List.Clear; + if S <> '' then + begin + R := S; + while R <> '' do + begin + C := Copy(R, 1, LINE_WIDTH); + Delete(R, 1, LINE_WIDTH); + List.Add(C); + end; + end; +end; + +function SaveMemoryToPemFile(const FileName, Head, Tail: string; + MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod; + KeyHashMethod: TCnKeyHashMethod; const Password: string; Append: Boolean): Boolean; +var + S, EH: string; + List, Sl: TStringList; +begin + Result := False; + if (MemoryStream <> nil) and (MemoryStream.Size <> 0) then + begin + MemoryStream.Position := 0; + + if (KeyEncryptMethod <> ckeNone) and (Password <> '') then + begin + // MemoryStream + AddPKCS7Padding(MemoryStream, ENC_TYPE_BLOCK_SIZE[KeyEncryptMethod]); + + // ټ + if not EncryptPemStream(KeyHashMethod, KeyEncryptMethod, MemoryStream, Password, EH) then + Exit; + end; + + if ECN_BASE64_OK = Base64Encode(MemoryStream, S) then + begin + List := TStringList.Create; + try + SplitStringToList(S, List); + + List.Insert(0, Head); // ͨͷ + if EH <> '' then // ͷ + List.Insert(1, EH); + List.Add(Tail); // ͨβ + + if Append and FileExists(FileName) then + begin + Sl := TStringList.Create; + try + Sl.LoadFromFile(FileName); + Sl.AddStrings(List); + Sl.SaveToFile(FileName); + finally + Sl.Free; + end; + end + else + List.SaveToFile(FileName); + + Result := True; + finally + List.Free; + end; + end; + end; +end; + +function SaveMemoryToPemStream(Stream: TStream; const Head, Tail: string; + MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod; + KeyHashMethod: TCnKeyHashMethod; const Password: string; Append: Boolean): Boolean; +var + S, EH: string; + List: TStringList; +begin + Result := False; + if (MemoryStream <> nil) and (MemoryStream.Size <> 0) then + begin + MemoryStream.Position := 0; + + if (KeyEncryptMethod <> ckeNone) and (Password <> '') then + begin + // MemoryStream + AddPKCS7Padding(MemoryStream, ENC_TYPE_BLOCK_SIZE[KeyEncryptMethod]); + + // ټ + if not EncryptPemStream(KeyHashMethod, KeyEncryptMethod, MemoryStream, Password, EH) then + Exit; + end; + + if ECN_BASE64_OK = Base64Encode(MemoryStream, S) then + begin + List := TStringList.Create; + try + SplitStringToList(S, List); + + List.Insert(0, Head); // ͨͷ + if EH <> '' then // ͷ + List.Insert(1, EH); + List.Add(Tail); // ͨβ + + if not Append then + Stream.Size := 0; + + List.SaveToStream(Stream); + + Result := True; + finally + List.Free; + end; + end; + end; +end; + +end. diff --git a/CnPack/Crypto/CnRandom.dcu b/CnPack/Crypto/CnRandom.dcu new file mode 100644 index 0000000000000000000000000000000000000000..c89e954877a4cd1e8e54c20ff7c9e1f2ca04318b GIT binary patch literal 5673 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 literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnRandom.pas b/CnPack/Crypto/CnRandom.pas new file mode 100644 index 0000000..de6a2c3 --- /dev/null +++ b/CnPack/Crypto/CnRandom.pas @@ -0,0 +1,415 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnRandom; +{* |
+================================================================================
+* ƣ
+* Ԫƣ䵥Ԫ
+* ԪߣCnPack  (master@cnpack.org)
+*     עԪװ Windows ƽ̨ MacOS/Linux ƽ̨µİȫ
+*           ṩȫ书ܡ
+* ƽ̨Win7 + Delphi 5.0
+* ݲԣWin32/Win64/MacOS/Linux + Unicode/NonUnicode
+*   õԪ豾ػ
+* ޸ļ¼2023.01.15 V1.3
+*                Windows ȫ urandom ֧ Linux
+*           2023.01.08 V1.2
+*                Win64  API 
+*           2022.08.22 V1.1
+*               ʹòϵͳṩ
+*           2020.03.27 V1.0
+*               Ԫ CnPrime ж
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils {$IFDEF MSWINDOWS}, Windows {$ENDIF}, Classes, CnNative; + +type + ECnRandomAPIError = class(Exception); + +function RandomUInt64: TUInt64; +{* UInt64 Χڵڲ֧ UInt64 ƽ̨ Int64 档 + + + ޣ + + ֵTUInt64 - UInt64 Χڵ +} + +function RandomUInt64LessThan(HighValue: TUInt64): TUInt64; +{* شڵ 0 Сָ UInt64 ֵ + + + HighValue: TUInt64 - ָ UInt64 + + ֵTUInt64 - شڵ 0 Сָ HighValue +} + +function RandomInt64: Int64; +{* شڵ 0 С Int64 ޵ + + + ޣ + + ֵInt64 - شڵ 0 С Int64 ޵ +} + +function RandomInt64LessThan(HighValue: Int64): Int64; +{* شڵ 0 Сָ Int64 ֵб֤ HighValue 0 + + + HighValue: Int64 - ָ Int64 + + ֵInt64 - شڵ 0 Сָ HighValue +} + +function RandomUInt32: Cardinal; +{* UInt32 Χڵ + + + ޣ + + ֵCardinal - UInt32 Χڵ +} + +function RandomUInt32LessThan(HighValue: Cardinal): Cardinal; +{* شڵ 0 Сָ UInt32 ֵ + + + HighValue: Cardinal - ָ UInt32 + + ֵCardinal - شڵ 0 Сָ HighValue +} + +function RandomInt32: Integer; +{* شڵ 0 С Int32 ޵ + + + ޣ + + ֵInteger - شڵ 0 С Int32 ޵ +} + +function RandomInt32LessThan(HighValue: Integer): Integer; +{* شڵ 0 Сָ Int32 б֤ HighValue 0 + + + HighValue: Integer - ָ Int32 + + ֵInteger - شڵ 0 Сָ HighValue +} + +function CnKnuthShuffle(ArrayBase: Pointer; ElementByteSize: Integer; + ElementCount: Integer): Boolean; +{* ߵϴ㷨 ArrayBase ָԪسߴΪ ElementSize ElementCount Ԫؾϴơ + + + ArrayBase: Pointer - ϴƵڴַ + ElementByteSize: Integer - ϴƵÿڴԪҲÿһƵֽڴС + ElementCount: Integer - ڴԪҲƵ + + ֵBoolean - ϴǷɹ +} + +function CnRandomFillBytes(Buf: PAnsiChar; BufByteLen: Integer): Boolean; +{* ʹ Windows API /dev/random 豸ʵ䣬ڲγʼ沢ͷš + + + Buf: PAnsiChar - ڴַ + BufByteLen: Integer - ڴֽڳ + + ֵBoolean - Ƿɹ +} + +function CnRandomFillBytes2(Buf: PAnsiChar; BufByteLen: Integer): Boolean; +{* ʹ Windows API /dev/urandom 豸ʵ䣬 + Windows ʹԤȳʼõ١ + + + Buf: PAnsiChar - ڴַ + BufByteLen: Integer - ڴֽڳ + + ֵBoolean - Ƿɹ +} + +implementation + +{$IFDEF MSWINDOWS} + +const + ADVAPI32 = 'advapi32.dll'; + + CRYPT_VERIFYCONTEXT = $F0000000; + CRYPT_NEWKEYSET = $8; + CRYPT_DELETEKEYSET = $10; + + PROV_RSA_FULL = 1; + NTE_BAD_KEYSET = $80090016; + +function CryptAcquireContext(phProv: PHandle; pszContainer: PAnsiChar; + pszProvider: PAnsiChar; dwProvType: LongWord; dwFlags: LongWord): BOOL; + stdcall; external ADVAPI32 name 'CryptAcquireContextA'; + +function CryptReleaseContext(hProv: THandle; dwFlags: LongWord): BOOL; + stdcall; external ADVAPI32 name 'CryptReleaseContext'; + +function CryptGenRandom(hProv: THandle; dwLen: LongWord; pbBuffer: PAnsiChar): BOOL; + stdcall; external ADVAPI32 name 'CryptGenRandom'; + +var + FHProv: THandle = 0; + +{$ELSE} + +const + DEV_FILE = '/dev/urandom'; + +{$ENDIF} + +function CnRandomFillBytes(Buf: PAnsiChar; BufByteLen: Integer): Boolean; +var +{$IFDEF MSWINDOWS} + HProv: THandle; + Res: DWORD; + B: Boolean; +{$ELSE} + F: TFileStream; +{$ENDIF} +begin + Result := False; +{$IFDEF MSWINDOWS} + // ʹ Windows API ʵ + HProv := 0; + B := CryptAcquireContext(@HProv, nil, nil, PROV_RSA_FULL, 0); + if not B then + B := CryptAcquireContext(@HProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + + if not B then + begin + Res := GetLastError; + if Res = NTE_BAD_KEYSET then // KeyContainer ڣ½ķʽ + begin + if not CryptAcquireContext(@HProv, nil, nil, PROV_RSA_FULL, CRYPT_NEWKEYSET) then + raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext NewKeySet $%8.8x', [GetLastError]); + end + else + raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext $%8.8x', [Res]); + end; + + if HProv <> 0 then + begin + try + Result := CryptGenRandom(HProv, BufByteLen, Buf); + if not Result then + raise ECnRandomAPIError.CreateFmt('Error CryptGenRandom $%8.8x', [GetLastError]); + finally + CryptReleaseContext(HProv, 0); + end; + end; +{$ELSE} + // MacOS/Linux µʵ֣öȡ /dev/urandom ݵķʽ + F := nil; + try + F := TFileStream.Create(DEV_FILE, fmOpenRead); + Result := F.Read(Buf^, BufByteLen) = BufByteLen; + finally + F.Free; + end; +{$ENDIF} +end; + +function CnRandomFillBytes2(Buf: PAnsiChar; BufByteLen: Integer): Boolean; +{$IFNDEF MSWINDOWS} +var + F: TFileStream; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + Result := CryptGenRandom(FHProv, BufByteLen, Buf); +{$ELSE} + // MacOS/Linux µʵ֣öȡ /dev/urandom ݵķʽ + F := nil; + try + F := TFileStream.Create(DEV_FILE, fmOpenRead); + Result := F.Read(Buf^, BufByteLen) = BufByteLen; + finally + F.Free; + end; +{$ENDIF} +end; + +function RandomUInt64: TUInt64; +var + HL: array[0..1] of Cardinal; +begin + // ϵͳ + if not CnRandomFillBytes2(@HL[0], SizeOf(TUInt64)) then + begin + // ֱ Random * High(TUInt64) ܻᾫȲ Lo ȫ FF˷ֿ + Randomize; + HL[0] := Trunc(Random * High(Cardinal) - 1) + 1; + HL[1] := Trunc(Random * High(Cardinal) - 1) + 1; + end; + + Result := (TUInt64(HL[0]) shl 32) + HL[1]; +end; + +function RandomUInt64LessThan(HighValue: TUInt64): TUInt64; +begin + Result := UInt64Mod(RandomUInt64, HighValue); +end; + +function RandomInt64LessThan(HighValue: Int64): Int64; +var + HL: array[0..1] of Cardinal; +begin + // ϵͳ + if not CnRandomFillBytes2(@HL[0], SizeOf(Int64)) then + begin + // ֱ Random * High(Int64) ܻᾫȲ Lo ȫ FF˷ֿ + Randomize; + HL[0] := Trunc(Random * High(Integer) - 1) + 1; // Int64 λ 1⸺ + HL[1] := Trunc(Random * High(Cardinal) - 1) + 1; + end + else + HL[0] := HL[0] mod (Cardinal(High(Integer)) + 1); // Int64 λ 1⸺ + + Result := (Int64(HL[0]) shl 32) + HL[1]; + Result := Result mod HighValue; // δ HighValue Сڵ 0 +end; + +function RandomInt64: Int64; +begin + Result := RandomInt64LessThan(High(Int64)); +end; + +function RandomUInt32: Cardinal; +var + D: Cardinal; +begin + // ϵͳ + if not CnRandomFillBytes2(@D, SizeOf(Cardinal)) then + begin + Randomize; + D := Trunc(Random * High(Cardinal) - 1) + 1; + end; + + Result := D; +end; + +function RandomUInt32LessThan(HighValue: Cardinal): Cardinal; +begin + Result := RandomUInt32 mod HighValue; +end; + +function RandomInt32: Integer; +begin + Result := RandomInt32LessThan(High(Integer)); +end; + +function RandomInt32LessThan(HighValue: Integer): Integer; +var + D: Cardinal; +begin + // ϵͳ + if not CnRandomFillBytes2(@D, SizeOf(Cardinal)) then + begin + Randomize; + D := Trunc(Random * High(Integer) - 1) + 1; + end + else + D := D mod (Cardinal(High(Integer)) + 1); + + Result := Integer(Int64(D) mod Int64(HighValue)); // δ HighValue Сڵ 0 +end; + +function CnKnuthShuffle(ArrayBase: Pointer; ElementByteSize: Integer; + ElementCount: Integer): Boolean; +var + I, R: Integer; + B1, B2: Pointer; +begin + Result := False; + if (ArrayBase = nil) or (ElementByteSize <= 0) or (ElementCount < 0) then // Ȳ + Exit; + + Result := True; + if ElementCount <= 1 then // ûԪػֻһԪʱϴ + Exit; + + for I := ElementCount - 1 downto 0 do + begin + R := RandomInt32LessThan(I + 1); // 0 I ڵҪ 1 + B1 := Pointer(TCnNativeUInt(ArrayBase) + TCnNativeUInt(I * ElementByteSize)); + B2 := Pointer(TCnNativeUInt(ArrayBase) + TCnNativeUInt(R * ElementByteSize)); + MemorySwap(B1, B2, ElementByteSize); + end; + Result := True; +end; + +{$IFDEF MSWINDOWS} + +procedure StartRandom; +var + Res: DWORD; + B: Boolean; +begin + FHProv := 0; + B := CryptAcquireContext(@FHProv, nil, nil, PROV_RSA_FULL, 0); + if not B then + B := CryptAcquireContext(@FHProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + + if not B then + begin + Res := GetLastError; + if Res = NTE_BAD_KEYSET then // KeyContainer ڣ½ķʽ + begin + if not CryptAcquireContext(@FHProv, nil, nil, PROV_RSA_FULL, CRYPT_NEWKEYSET) then + raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext NewKeySet $%8.8x', [GetLastError]); + end + else + raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext $%8.8x', [Res]); + end; +end; + +procedure StopRandom; +begin + if FHProv <> 0 then + begin + CryptReleaseContext(FHProv, 0); + FHProv := 0; + end; +end; + +initialization + StartRandom; + +finalization + StopRandom; + +{$ENDIF} + +end. diff --git a/CnPack/Crypto/CnSHA1.dcu b/CnPack/Crypto/CnSHA1.dcu new file mode 100644 index 0000000000000000000000000000000000000000..a3f75043eb9f12c9d50a84dbf880dc9592c6e5f6 GIT binary patch literal 10859 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 QlTU=35CcrI#ct;Ke<$eb%>V!Z literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnSHA1.pas b/CnPack/Crypto/CnSHA1.pas new file mode 100644 index 0000000..4daf51e --- /dev/null +++ b/CnPack/Crypto/CnSHA1.pas @@ -0,0 +1,737 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnSHA1; +{* |
+================================================================================
+* ƣ
+* ԪƣSHA1 Ӵ㷨ʵֵԪ
+* ԪߣCnPack  (master@cnpack.org)
+*           /ֲ䲿ֹܡ
+*     עԪʵ SHA1 Ӵ㷨Ӧ HMAC 㷨
+* ƽ̨PWin2000Pro + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2022.04.26 V1.5
+*               ޸ LongWord  Integer ַת֧ MacOS64
+*           2019.12.12 V1.4
+*               ֧ TBytes
+*           2019.04.15 V1.3
+*               ֧ Win32/Win64/MacOS32
+*           2015.08.14 V1.2
+*               л Pascal ֿ֧ƽ̨
+*           2014.10.22 V1.1
+*                HMAC 
+*           2010.07.14 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, CnNative, CnConsts; + +type + PCnSHA1Digest = ^TCnSHA1Digest; + TCnSHA1Digest = array[0..19] of Byte; + {* SHA1 Ӵս20 ֽ} + + TCnSHA1Context = record + {* SHA1 Ľṹ} + Hash: array[0..4] of Cardinal; + Hi, Lo: Cardinal; + Buffer: array[0..63] of Byte; + Index: Integer; + Ipad: array[0..63] of Byte; {!< HMAC: inner padding } + Opad: array[0..63] of Byte; {!< HMAC: outer padding } + end; + + TCnSHA1CalcProgressFunc = procedure (ATotal, AProgress: Int64; + var Cancel: Boolean) of object; + {* SHA1 ӴսȻص¼} + +function SHA1(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA1Digest; +{* ݿ SHA1 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1Buffer(const Buffer; Count: Cardinal): TCnSHA1Digest; +{* ݿ SHA1 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1Bytes(Data: TBytes): TCnSHA1Digest; +{* ֽ SHA1 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1String(const Str: string): TCnSHA1Digest; +{* String ݽ SHA1 㡣ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1StringA(const Str: AnsiString): TCnSHA1Digest; +{* AnsiString ַ SHA1 㣬ֱӼڲݣޱ봦 + + + const Str: AnsiString - ַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1StringW(const Str: WideString): TCnSHA1Digest; +{* WideString ַת SHA1 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +{$IFDEF UNICODE} + +function SHA1UnicodeString(const Str: string): TCnSHA1Digest; +{* UnicodeString ݽֱӵ SHA1 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +{$ELSE} + +function SHA1UnicodeString(const Str: WideString): TCnSHA1Digest; +{* UnicodeString ݽֱӵ SHA1 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +{$ENDIF} + +function SHA1File(const FileName: string; + CallBack: TCnSHA1CalcProgressFunc = nil): TCnSHA1Digest; +{* ָļݽ SHA1 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA1CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1Stream(Stream: TStream; + CallBack: TCnSHA1CalcProgressFunc = nil): TCnSHA1Digest; +{* ָݽ SHA1 㡣 + + + Stream: TStream - + CallBack: TCnSHA1CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +// ⲿݽɢ SHA1 㣬SHA1Update ɶα + +procedure SHA1Init(var Context: TCnSHA1Context); +{* ʼһ SHA1 ģ׼ SHA1 + + + var Context: TCnSHA1Context - ʼ SHA1 + + ֵޣ +} + +procedure SHA1Update(var Context: TCnSHA1Context; Input: PAnsiChar; ByteLength: Integer); +{* ԳʼĶһݽ SHA1 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA1Context - SHA1 + Input: PAnsiChar - ݿַ + ByteLength: Integer - ݿֽڳ + + ֵޣ +} + +procedure SHA1Final(var Context: TCnSHA1Context; var Digest: TCnSHA1Digest); +{* ּ㣬 SHA1 Digest С + + + var Context: TCnSHA1Context - SHA1 + var Digest: TCnSHA1Digest - ص SHA1 Ӵֵ + + ֵޣ +} + +function SHA1Print(const Digest: TCnSHA1Digest): string; +{* ʮƸʽ SHA1 Ӵֵ + + + const Digest: TCnSHA1Digest - ָ SHA1 Ӵֵ + + ֵstring - ʮַ +} + +function SHA1Match(const D1: TCnSHA1Digest; const D2: TCnSHA1Digest): Boolean; +{* Ƚ SHA1 ӴֵǷȡ + + + const D1: TCnSHA1Digest - Ƚϵ SHA1 Ӵֵһ + const D2: TCnSHA1Digest - Ƚϵ SHA1 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA1DigestToStr(const Digest: TCnSHA1Digest): string; +{* SHA1 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA1Digest - ת SHA1 Ӵֵ + + ֵstring - صַ +} + +procedure SHA1Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA1Digest); +{* SHA1 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA1 Կݿַ + KeyByteLength: Integer - SHA1 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA1Digest - ص SHA1 Ӵֵ + + ֵޣ +} + +implementation + +const + MAX_FILE_SIZE = 512 * 1024 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + HMAC_SHA1_BLOCK_SIZE_BYTE = 64; + HMAC_SHA1_OUTPUT_LENGTH_BYTE = 20; + +function LRot32(X: Cardinal; C: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X shl (C and 31) + X shr (32 - C and 31); +end; + +function F1(x, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := z xor (x and (y xor z)); +end; + +function F2(x, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := x xor y xor z; +end; + +function F3(x, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (x and y) or (z and (x or y)); +end; + +function RB(A: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (A shr 24) or ((A shr 8) and $FF00) or ((A shl 8) and $FF0000) or (A shl 24); +end; + +procedure SHA1Compress(var Data: TCnSHA1Context); +var + A, B, C, D, E, T: Cardinal; + W: array[0..79] of Cardinal; + I: Integer; +begin + Move(Data.Buffer, W, Sizeof(Data.Buffer)); + for I := 0 to 15 do + W[I] := RB(W[I]); + for I := 16 to 79 do + W[I] := LRot32(W[I - 3] xor W[I - 8] xor W[I - 14] xor W[I - 16], 1); + A := Data.Hash[0]; + B := Data.Hash[1]; + C := Data.Hash[2]; + D := Data.Hash[3]; + E := Data.Hash[4]; + for I := 0 to 19 do + begin + T := LRot32(A, 5) + F1(B, C, D) + E + W[I] + $5A827999; + E := D; + D := C; + C := LRot32(B, 30); + B := A; + A := T; + end; + for I := 20 to 39 do + begin + T := LRot32(A, 5) + F2(B, C, D) + E + W[I] + $6ED9EBA1; + E := D; + D := C; + C := LRot32(B, 30); + B := A; + A := T; + end; + for I := 40 to 59 do + begin + T := LRot32(A, 5) + F3(B, C, D) + E + W[I] + $8F1BBCDC; + E := D; + D := C; + C := LRot32(B, 30); + B := A; + A := T; + end; + for I := 60 to 79 do + begin + T := LRot32(A, 5) + F2(B, C, D) + E + W[I] + $CA62C1D6; + E := D; + D := C; + C := LRot32(B, 30); + B := A; + A := T; + end; + Data.Hash[0] := Data.Hash[0] + A; + Data.Hash[1] := Data.Hash[1] + B; + Data.Hash[2] := Data.Hash[2] + C; + Data.Hash[3] := Data.Hash[3] + D; + Data.Hash[4] := Data.Hash[4] + E; + FillChar(W, Sizeof(W), 0); + FillChar(Data.Buffer, Sizeof(Data.Buffer), 0); +end; + +procedure SHA1Init(var Context: TCnSHA1Context); +begin + Context.Hi := 0; + Context.Lo := 0; + Context.Index := 0; + FillChar(Context.Buffer, Sizeof(Context.Buffer), 0); + Context.Hash[0] := $67452301; + Context.Hash[1] := $EFCDAB89; + Context.Hash[2] := $98BADCFE; + Context.Hash[3] := $10325476; + Context.Hash[4] := $C3D2E1F0; +end; + +procedure SHA1UpdateLen(var Context: TCnSHA1Context; Len: Integer); +var + I: Cardinal; + K: Integer; +begin + for K := 0 to 7 do + begin + I := Context.Lo; + Inc(Context.Lo, Len); + if Context.Lo < I then + Inc(Context.Hi); + end; +end; + +procedure SHA1Update(var Context: TCnSHA1Context; Input: PAnsiChar; ByteLength: Integer); +begin + SHA1UpdateLen(Context, ByteLength); + while ByteLength > 0 do + begin + Context.Buffer[Context.Index] := PByte(Input)^; + Inc(PByte(Input)); + Inc(Context.Index); + Dec(ByteLength); + if Context.Index = 64 then + begin + Context.Index := 0; + SHA1Compress(Context); + end; + end; +end; + +procedure SHA1UpdateW(var Context: TCnSHA1Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + pContent: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(pContent, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(pContent), CharLength * SizeOf(WideChar), nil, nil); + SHA1Update(Context, pContent, iLen); + finally + FreeMem(pContent); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SHA1Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +procedure SHA1Final(var Context: TCnSHA1Context; var Digest: TCnSHA1Digest); +type + PDWord = ^Cardinal; +begin + Context.Buffer[Context.Index] := $80; + if Context.Index >= 56 then + SHA1Compress(Context); + PDWord(@Context.Buffer[56])^ := RB(Context.Hi); + PDWord(@Context.Buffer[60])^ := RB(Context.Lo); + SHA1Compress(Context); + Context.Hash[0] := RB(Context.Hash[0]); + Context.Hash[1] := RB(Context.Hash[1]); + Context.Hash[2] := RB(Context.Hash[2]); + Context.Hash[3] := RB(Context.Hash[3]); + Context.Hash[4] := RB(Context.Hash[4]); + Move(Context.Hash, Digest, Sizeof(Digest)); +end; + +// ݿ SHA1 +function SHA1(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, Input, ByteLength); + SHA1Final(Context, Result); +end; + +// ݿ SHA1 +function SHA1Buffer(const Buffer; Count: Cardinal): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, PAnsiChar(Buffer), Count); + SHA1Final(Context, Result); +end; + +function SHA1Bytes(Data: TBytes): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA1Final(Context, Result); +end; + +// String ݽ SHA1 +function SHA1String(const Str: string): TCnSHA1Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA1StringA(AStr); +end; + +// AnsiString ݽ SHA1 +function SHA1StringA(const Str: AnsiString): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, PAnsiChar(Str), Length(Str)); + SHA1Final(Context, Result); +end; + +// WideString ݽ SHA1 +function SHA1StringW(const Str: WideString): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1UpdateW(Context, PWideChar(Str), Length(Str)); + SHA1Final(Context, Result); +end; + +{$IFDEF UNICODE} +function SHA1UnicodeString(const Str: string): TCnSHA1Digest; +{$ELSE} +function SHA1UnicodeString(const Str: WideString): TCnSHA1Digest; +{$ENDIF} +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA1Final(Context, Result); +end; + +function InternalSHA1Stream(Stream: TStream; const BufSize: Cardinal; var D: + TCnSHA1Digest; CallBack: TCnSHA1CalcProgressFunc = nil): Boolean; +var + Context: TCnSHA1Context; + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then Exit; + if Size < BufSize then BufLen := Size + else BufLen := BufSize; + + CancelCalc := False; + SHA1Init(Context); + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + SHA1Update(Context, Buf, ReadBytes); + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + SHA1Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ָ SHA1 +function SHA1Stream(Stream: TStream; + CallBack: TCnSHA1CalcProgressFunc = nil): TCnSHA1Digest; +begin + InternalSHA1Stream(Stream, 4096 * 1024, Result, CallBack); +end; + +// ָļݽ SHA1 +function SHA1File(const FileName: string; + CallBack: TCnSHA1CalcProgressFunc): TCnSHA1Digest; +var +{$IFDEF MSWINDOWS} + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; + Context: TCnSHA1Context; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; + + function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} + var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec : Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then Exit; + try + if not GetFileInformationByHandle(H, Info) then Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} + end; + +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSHA1Stream(Stream, 4096 * 1024, Result, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + SHA1Init(Context); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + SHA1Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + SHA1Final(Context, Result); +{$ENDIF} + end; +end; + +// ʮƸʽ SHA1 Ӵֵ +function SHA1Print(const Digest: TCnSHA1Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA1Digest)); +end; + +// Ƚ SHA1 ӴֵǷ +function SHA1Match(const D1, D2: TCnSHA1Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 20) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// SHA1 Ӵֵת string +function SHA1DigestToStr(const Digest: TCnSHA1Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA1Digest)); +end; + +procedure SHA1HmacInit(var Ctx: TCnSHA1Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA1Digest; +begin + if KeyLength > HMAC_SHA1_BLOCK_SIZE_BYTE then + begin + Sum := SHA1Buffer(Key, KeyLength); + KeyLength := HMAC_SHA1_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Ctx.Ipad, HMAC_SHA1_BLOCK_SIZE_BYTE, $36); + FillChar(Ctx.Opad, HMAC_SHA1_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Ctx.Ipad[I] := Byte(Ctx.Ipad[I] xor Byte(Key[I])); + Ctx.Opad[I] := Byte(Ctx.Opad[I] xor Byte(Key[I])); + end; + + SHA1Init(Ctx); + SHA1Update(Ctx, @(Ctx.Ipad[0]), HMAC_SHA1_BLOCK_SIZE_BYTE); +end; + +procedure SHA1HmacUpdate(var Ctx: TCnSHA1Context; Input: PAnsiChar; Length: Cardinal); +begin + SHA1Update(Ctx, Input, Length); +end; + +procedure SHA1HmacFinal(var Ctx: TCnSHA1Context; var Output: TCnSHA1Digest); +var + Len: Integer; + TmpBuf: TCnSHA1Digest; +begin + Len := HMAC_SHA1_OUTPUT_LENGTH_BYTE; + SHA1Final(Ctx, TmpBuf); + SHA1Init(Ctx); + SHA1Update(Ctx, @(Ctx.Opad[0]), HMAC_SHA1_BLOCK_SIZE_BYTE); + SHA1Update(Ctx, @(TmpBuf[0]), Len); + SHA1Final(Ctx, Output); +end; + +procedure SHA1Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA1Digest); +var + Ctx: TCnSHA1Context; +begin + SHA1HmacInit(Ctx, Key, KeyByteLength); + SHA1HmacUpdate(Ctx, Input, ByteLength); + SHA1HmacFinal(Ctx, Output); +end; + +end. diff --git a/CnPack/Crypto/CnSHA2.dcu b/CnPack/Crypto/CnSHA2.dcu new file mode 100644 index 0000000000000000000000000000000000000000..b080c2a50656f8ebf30bc3076405071038294457 GIT binary patch literal 30907 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 +================================================================================ +* ƣ +* ԪƣSHA2 Ӵ㷨ʵֵԪ +* ԪߣCnPack (master@cnpack.org) +* / C Pascal ֲ䲿ֹܡ +* עԪʵ SHA2 ϵӴ㷨Ӧ HMAC 㷨 SHA224/256/384/512 +* עDelphi 5/6/7 Ԫз Int64 ޷ UInt64 SHA512/384 +* ԭǻڲ޷ļӼλԼƵȶͬΨһ +* ͬDZȽϣԪûƵıȽϡ +* ƽ̨PWinXP + Delphi 5.0 +* ݲԣPWinXP/7 + Delphi 5/6 +* õԪеַϱػʽ +* ޸ļ¼2022.04.26 V1.4 +* ޸ LongWord Integer ַת֧ MacOS64 +* 2019.04.15 V1.3 +* ֧ Win32/Win64/MacOS32 +* 2017.10.31 V1.2 +* SHA512/384 HMAC +* 2016.09.30 V1.1 +* ʵ SHA512/384D567з Int64 ޷ UInt64 +* 2016.09.27 V1.0 +* Ԫ +================================================================================ +|} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, CnNative, CnConsts; + +type + PCnSHAGeneralDigest = ^TCnSHAGeneralDigest; + TCnSHAGeneralDigest = array[0..63] of Byte; + + PCnSHA224Digest = ^TCnSHA224Digest; + TCnSHA224Digest = array[0..27] of Byte; + {* SHA224 Ӵս28 ֽ} + + PCnSHA256Digest = ^TCnSHA256Digest; + TCnSHA256Digest = array[0..31] of Byte; + {* SHA256 Ӵս32 ֽ} + + PCnSHA384Digest = ^TCnSHA384Digest; + TCnSHA384Digest = array[0..47] of Byte; + {* SHA384 Ӵս48 ֽ} + + PCnSHA512Digest = ^TCnSHA512Digest; + TCnSHA512Digest = array[0..63] of Byte; + {* SHA512 Ӵս64 ֽ} + + TCnSHA256Context = packed record + {* SHA256 Ľṹ} + DataLen: Cardinal; + Data: array[0..63] of Byte; + BitLen: Int64; + State: array[0..7] of Cardinal; + Ipad: array[0..63] of Byte; {!< HMAC: inner padding } + Opad: array[0..63] of Byte; {!< HMAC: outer padding } + end; + + TCnSHA224Context = TCnSHA256Context; + {* SHA224 Ľṹ} + + TCnSHA512Context = packed record + {* SHA512 Ľṹ} + DataLen: Cardinal; + Data: array[0..127] of Byte; + TotalLen: Int64; + State: array[0..7] of Int64; + Ipad: array[0..127] of Byte; {!< HMAC: inner padding } + Opad: array[0..127] of Byte; {!< HMAC: outer padding } + end; + + TCnSHA384Context = TCnSHA512Context; + {* SHA512 Ľṹ} + + TCnSHACalcProgressFunc = procedure(ATotal, AProgress: Int64; var Cancel: + Boolean) of object; + {* SHA2 ϵӴսȻص¼} + +function SHA224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA224Digest; +{* ݿ SHA224 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA256Digest; +{* ݿ SHA256 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA384Digest; +{* ݿ SHA384 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA512Digest; +{* ݿ SHA512 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA224Buffer(const Buffer; Count: Cardinal): TCnSHA224Digest; +{* ݿ SHA224 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256Buffer(const Buffer; Count: Cardinal): TCnSHA256Digest; +{* ݿ SHA256 㡣 + + + const Buffer - ݿַ + Count: Cardinal - + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384Buffer(const Buffer; Count: Cardinal): TCnSHA384Digest; +{* ݿ SHA384 㡣 + + + const Buffer - ݿַ + Count: Cardinal - + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512Buffer(const Buffer; Count: Cardinal): TCnSHA512Digest; +{* ݿ SHA512 㡣 + + + const Buffer - ݿַ + Count: Cardinal - + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA224Bytes(Data: TBytes): TCnSHA224Digest; +{* ֽ SHA224 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256Bytes(Data: TBytes): TCnSHA256Digest; +{* ֽ SHA256 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384Bytes(Data: TBytes): TCnSHA384Digest; +{* ֽ SHA384 㡣 + + Data: TBytes - ֽ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512Bytes(Data: TBytes): TCnSHA512Digest; +{* ֽ SHA512 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA224String(const Str: string): TCnSHA224Digest; +{* String ݽ SHA224 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256String(const Str: string): TCnSHA256Digest; +{* String ݽ SHA256 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384String(const Str: string): TCnSHA384Digest; +{* String ݽ SHA384 㣬ע D2009ϰ汾string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512String(const Str: string): TCnSHA512Digest; +{* String ݽ SHA512 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + + +function SHA224StringA(const Str: AnsiString): TCnSHA224Digest; +{* AnsiString ݽ SHA224 㡣 + + + const Str: AnsiString - + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA224StringW(const Str: WideString): TCnSHA224Digest; +{* WideString ݽ SHA224 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256StringA(const Str: AnsiString): TCnSHA256Digest; +{* AnsiString ݽ SHA256 㡣 + + + const Str: AnsiString - + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA256StringW(const Str: WideString): TCnSHA256Digest; +{* WideString ݽ SHA256 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384StringA(const Str: AnsiString): TCnSHA384Digest; +{* AnsiString ݽ SHA384 㡣 + + + const Str: AnsiString - + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA384StringW(const Str: WideString): TCnSHA384Digest; +{* WideString ݽ SHA384 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512StringA(const Str: AnsiString): TCnSHA512Digest; +{* AnsiString ݽ SHA512 㡣 + + + const Str: AnsiString - + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA512StringW(const Str: WideString): TCnSHA512Digest; +{* WideString ݽ SHA512 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +{$IFDEF UNICODE} + +function SHA224UnicodeString(const Str: string): TCnSHA224Digest; +{* UnicodeString ݽֱӵ SHA224 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256UnicodeString(const Str: string): TCnSHA256Digest; +{* UnicodeString ݽֱӵ SHA256 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384UnicodeString(const Str: string): TCnSHA384Digest; +{* UnicodeString ݽֱӵ SHA384 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512UnicodeString(const Str: string): TCnSHA512Digest; +{* UnicodeString ݽֱӵ SHA512 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +{$ELSE} + +function SHA224UnicodeString(const Str: WideString): TCnSHA224Digest; +{* UnicodeString ݽֱӵ SHA224 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256UnicodeString(const Str: WideString): TCnSHA256Digest; +{* UnicodeString ݽֱӵ SHA256 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384UnicodeString(const Str: WideString): TCnSHA384Digest; +{* UnicodeString ݽֱӵ SHA384 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512UnicodeString(const Str: WideString): TCnSHA512Digest; +{* UnicodeString ݽֱӵ SHA512 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +{$ENDIF} + +function SHA224File(const FileName: string; CallBack: TCnSHACalcProgressFunc = + nil): TCnSHA224Digest; +{* ָļݽ SHA256 㡣 + + + const FileName: string - ļ + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA224Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA224Digest; +{* ָݽ SHA224 㡣 + + + Stream: TStream - + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256File(const FileName: string; CallBack: TCnSHACalcProgressFunc = + nil): TCnSHA256Digest; +{* ָļݽ SHA256 㡣 + + + const FileName: string - ļ + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA256Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA256Digest; +{* ָݽ SHA256 㡣 + + + Stream: TStream - + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384File(const FileName: string; CallBack: TCnSHACalcProgressFunc = + nil): TCnSHA384Digest; +{* ָļݽ SHA384 㡣 + + + const FileName: string - ļ + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA384Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA384Digest; +{* ָݽ SHA384 㡣 + + + Stream: TStream - + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512File(const FileName: string; CallBack: TCnSHACalcProgressFunc = + nil): TCnSHA512Digest; +{* ָļݽ SHA512 㡣 + + + const FileName: string - ļ + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA512Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA512Digest; +{* ָݽ SHA512 㡣 + + + Stream: TStream - + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +// ⲿݽɢ SHA224 㣬SHA224Update ɶα + +procedure SHA224Init(var Context: TCnSHA224Context); +{* ʼһ SHA224 ģ׼ SHA224 + + + var Context: TCnSHA224Context - ʼ SHA224 + + ֵޣ +} + +procedure SHA224Update(var Context: TCnSHA224Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA224 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA224Context - SHA224 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA224Final(var Context: TCnSHA224Context; var Digest: TCnSHA224Digest); +{* ּ㣬 SHA224 Digest С + + + var Context: TCnSHA224Context - SHA224 + var Digest: TCnSHA224Digest - ص SHA224 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA256 㣬SHA256Update ɶα + +procedure SHA256Init(var Context: TCnSHA256Context); +{* ʼһ SHA256 ģ׼ SHA256 + + + var Context: TCnSHA256Context - ʼ SHA256 + + ֵޣ +} + +procedure SHA256Update(var Context: TCnSHA256Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA256 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA256Context - SHA256 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA256Final(var Context: TCnSHA256Context; var Digest: TCnSHA256Digest); +{* ּ㣬 SHA256 Digest С + + + var Context: TCnSHA256Context - SHA256 + var Digest: TCnSHA256Digest - ص SHA256 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA384 㣬SHA384Update ɶα + +procedure SHA384Init(var Context: TCnSHA384Context); +{* ʼһ SHA384 ģ׼ SHA384 + + + var Context: TCnSHA384Context - ʼ SHA384 + + ֵޣ +} + +procedure SHA384Update(var Context: TCnSHA384Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA384 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA384Context - SHA384 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA384Final(var Context: TCnSHA384Context; var Digest: TCnSHA384Digest); +{* ּ㣬 SHA384 Digest С + + + var Context: TCnSHA384Context - SHA384 + var Digest: TCnSHA384Digest - ص SHA384 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA512 㣬SHA512Update ɶα + +procedure SHA512Init(var Context: TCnSHA512Context); +{* ʼһ SHA512 ģ׼ SHA512 + + + var Context: TCnSHA512Context - ʼ SHA512 + + ֵޣ +} + +procedure SHA512Update(var Context: TCnSHA512Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA512 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA512Context - SHA512 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA512Final(var Context: TCnSHA512Context; var Digest: TCnSHA512Digest); +{* ּ㣬 SHA512 Digest + + + var Context: TCnSHA512Context - SHA512 + var Digest: TCnSHA512Digest - ص SHA512 Ӵֵ + + ֵޣ +} + +function SHA224Print(const Digest: TCnSHA224Digest): string; +{* ʮƸʽ SHA224 Ӵֵ + + + const Digest: TCnSHA224Digest - ָ SHA224 Ӵֵ + + ֵstring - ʮַ +} + +function SHA256Print(const Digest: TCnSHA256Digest): string; +{* ʮƸʽ SHA256 Ӵֵ + + + const Digest: TCnSHA256Digest - ָ SHA256 Ӵֵ + + ֵstring - ʮַ +} + +function SHA384Print(const Digest: TCnSHA384Digest): string; +{* ʮƸʽ SHA384 Ӵֵ + + + const Digest: TCnSHA384Digest - ָ SHA384 Ӵֵ + + ֵstring - ʮַ +} + +function SHA512Print(const Digest: TCnSHA512Digest): string; +{* ʮƸʽ SHA512 Ӵֵ + + + const Digest: TCnSHA512Digest - ָ SHA512 Ӵֵ + + ֵstring - ʮַ +} + +function SHA224Match(const D1: TCnSHA224Digest; const D2: TCnSHA224Digest): Boolean; +{* Ƚ SHA224 ӴֵǷȡ + + + const D1: TCnSHA224Digest - Ƚϵ SHA224 Ӵֵһ + const D2: TCnSHA224Digest - Ƚϵ SHA224 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA256Match(const D1: TCnSHA256Digest; const D2: TCnSHA256Digest): Boolean; +{* Ƚ SHA256 ӴֵǷȡ + + + const D1: TCnSHA256Digest - Ƚϵ SHA256 Ӵֵһ + const D2: TCnSHA256Digest - Ƚϵ SHA256 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA384Match(const D1: TCnSHA384Digest; const D2: TCnSHA384Digest): Boolean; +{* Ƚ SHA384 ӴֵǷȡ + + + const D1: TCnSHA384Digest - Ƚϵ SHA384 Ӵֵһ + const D2: TCnSHA384Digest - Ƚϵ SHA384 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA512Match(const D1: TCnSHA512Digest; const D2: TCnSHA512Digest): Boolean; +{* Ƚ SHA512 ӴֵǷȡ + + + const D1: TCnSHA512Digest - Ƚϵ SHA512 Ӵֵһ + const D2: TCnSHA512Digest - Ƚϵ SHA512 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA224DigestToStr(const Digest: TCnSHA224Digest): string; +{* SHA224 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA224Digest - ת SHA224 Ӵֵ + + ֵstring - صַ +} + +function SHA256DigestToStr(const Digest: TCnSHA256Digest): string; +{* SHA256 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA256Digest - ת SHA256 Ӵֵ + + ֵstring - صַ +} + +function SHA384DigestToStr(const Digest: TCnSHA384Digest): string; +{* SHA384 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA384Digest - ת SHA384 Ӵֵ + + ֵstring - صַ +} + +function SHA512DigestToStr(const Digest: TCnSHA512Digest): string; +{* SHA512 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA512Digest - ת SHA512 Ӵֵ + + ֵstring - صַ +} + +procedure SHA224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA224Digest); +{* SHA224 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA224 Կݿַ + KeyByteLength: Integer - SHA224 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA224Digest - ص SHA224 Ӵֵ + + ֵޣ +} + +procedure SHA256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA256Digest); +{* SHA256 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA256 Կݿַ + KeyByteLength: Integer - SHA256 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA256Digest - ص SHA256 Ӵֵ + + ֵޣ +} + +procedure SHA384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA384Digest); +{* SHA384 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA384 Կݿַ + KeyByteLength: Integer - SHA384 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA384Digest - ص SHA384 Ӵֵ + + ֵޣ +} + +procedure SHA512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA512Digest); +{* SHA512 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA512 Կݿַ + KeyByteLength: Integer - SHA512 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA512Digest - ص SHA512 Ӵֵ + + ֵޣ +} + +implementation + +const + HMAC_SHA2_224_256_BLOCK_SIZE_BYTE = 64; + HMAC_SHA2_384_512_BLOCK_SIZE_BYTE = 128; + + HMAC_SHA2_224_OUTPUT_LENGTH_BYTE = 28; + HMAC_SHA2_256_OUTPUT_LENGTH_BYTE = 32; + HMAC_SHA2_384_OUTPUT_LENGTH_BYTE = 48; + HMAC_SHA2_512_OUTPUT_LENGTH_BYTE = 64; + +type + TSHA2Type = (stSHA2_224, stSHA2_256, stSHA2_384, stSHA2_512); + +const + MAX_FILE_SIZE = 512 * 1024 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + KEYS256: array[0..63] of Cardinal = ($428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, + $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5, $D807AA98, $12835B01, $243185BE, + $550C7DC3, $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, $E49B69C1, $EFBE4786, + $0FC19DC6, $240CA1CC, $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA, $983E5152, + $A831C66D, $B00327C8, $BF597FC7, $C6E00BF3, $D5A79147, $06CA6351, $14292967, + $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, $650A7354, $766A0ABB, $81C2C92E, + $92722C85, $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, $D192E819, $D6990624, + $F40E3585, $106AA070, $19A4C116, $1E376C08, $2748774C, $34B0BCB5, $391C0CB3, + $4ED8AA4A, $5B9CCA4F, $682E6FF3, $748F82EE, $78A5636F, $84C87814, $8CC70208, + $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2); + + KEYS512: array[0..79] of TUInt64 = ($428A2F98D728AE22, $7137449123EF65CD, + $B5C0FBCFEC4D3B2F, $E9B5DBA58189DBBC, $3956C25BF348B538, $59F111F1B605D019, + $923F82A4AF194F9B, $AB1C5ED5DA6D8118, $D807AA98A3030242, $12835B0145706FBE, + $243185BE4EE4B28C, $550C7DC3D5FFB4E2, $72BE5D74F27B896F, $80DEB1FE3B1696B1, + $9BDC06A725C71235, $C19BF174CF692694, $E49B69C19EF14AD2, $EFBE4786384F25E3, + $0FC19DC68B8CD5B5, $240CA1CC77AC9C65, $2DE92C6F592B0275, $4A7484AA6EA6E483, + $5CB0A9DCBD41FBD4, $76F988DA831153B5, $983E5152EE66DFAB, $A831C66D2DB43210, + $B00327C898FB213F, $BF597FC7BEEF0EE4, $C6E00BF33DA88FC2, $D5A79147930AA725, + $06CA6351E003826F, $142929670A0E6E70, $27B70A8546D22FFC, $2E1B21385C26C926, + $4D2C6DFC5AC42AED, $53380D139D95B3DF, $650A73548BAF63DE, $766A0ABB3C77B2A8, + $81C2C92E47EDAEE6, $92722C851482353B, $A2BFE8A14CF10364, $A81A664BBC423001, + $C24B8B70D0F89791, $C76C51A30654BE30, $D192E819D6EF5218, $D69906245565A910, + $F40E35855771202A, $106AA07032BBD1B8, $19A4C116B8D2D0C8, $1E376C085141AB53, + $2748774CDF8EEB99, $34B0BCB5E19B48A8, $391C0CB3C5C95A63, $4ED8AA4AE3418ACB, + $5B9CCA4F7763E373, $682E6FF3D6B2B8A3, $748F82EE5DEFB2FC, $78A5636F43172F60, + $84C87814A1F0AB72, $8CC702081A6439EC, $90BEFFFA23631E28, $A4506CEBDE82BDE9, + $BEF9A3F7B2C67915, $C67178F2E372532B, $CA273ECEEA26619C, $D186B8C721C0C207, + $EADA7DD6CDE0EB1E, $F57D4F7FEE6ED178, $06F067AA72176FBA, $0A637DC5A2C898A6, + $113F9804BEF90DAE, $1B710B35131C471B, $28DB77F523047D84, $32CAAB7B40C72493, + $3C9EBE0A15C9BEBC, $431D67C49C100D4C, $4CC5D4BECB3E42B6, $597F299CFC657E2A, + $5FCB6FAB3AD6FAEC, $6C44198C4A475817); + +function ROTRight256(A, B: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (A shr B) or (A shl (32 - B)); +end; + +function ROTRight512(X: TUInt64; Y: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X shr Y) or (X shl (64 - Y)); +end; + +function SHR512(X: TUInt64; Y: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and $FFFFFFFFFFFFFFFF) shr Y; +end; + +function CH256(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and Y) xor ((not X) and Z); +end; + +function CH512(X, Y, Z: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (((Y xor Z) and X) xor Z); +end; + +function MAJ256(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and Y) xor (X and Z) xor (Y and Z); +end; + +function MAJ512(X, Y, Z: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ((X or Y) and Z) or (X and Y); +end; + +function EP0256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight256(X, 2) xor ROTRight256(X, 13) xor ROTRight256(X, 22); +end; + +function EP1256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight256(X, 6) xor ROTRight256(X, 11) xor ROTRight256(X, 25); +end; + +function SIG0256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight256(X, 7) xor ROTRight256(X, 18) xor (X shr 3); +end; + +function SIG1256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight256(X, 17) xor ROTRight256(X, 19) xor (X shr 10); +end; + +function SIG0512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight512(X, 28) xor ROTRight512(X, 34) xor ROTRight512(X, 39); +end; + +function SIG1512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight512(X, 14) xor ROTRight512(X, 18) xor ROTRight512(X, 41); +end; + +function Gamma0512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight512(X, 1) xor ROTRight512(X, 8) xor SHR512(X, 7); +end; + +function Gamma1512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight512(X, 19) xor ROTRight512(X, 61) xor SHR512(X, 6); +end; + +procedure SHA256Transform(var Context: TCnSHA256Context; Data: PAnsiChar); +var + A, B, C, D, E, F, G, H, T1, T2: Cardinal; + M: array[0..63] of Cardinal; + I, J: Integer; +begin + I := 0; + J := 0; + while I < 16 do + begin + M[I] := (Cardinal(Data[J]) shl 24) or (Cardinal(Data[J + 1]) shl 16) or (Cardinal(Data + [J + 2]) shl 8) or Cardinal(Data[J + 3]); + Inc(I); + Inc(J, 4); + end; + + while I < 64 do + begin + M[I] := SIG1256(M[I - 2]) + M[I - 7] + SIG0256(M[I - 15]) + M[I - 16]; + Inc(I); + end; + + A := Context.State[0]; + B := Context.State[1]; + C := Context.State[2]; + D := Context.State[3]; + E := Context.State[4]; + F := Context.State[5]; + G := Context.State[6]; + H := Context.State[7]; + + I := 0; + while I < 64 do + begin + T1 := H + EP1256(E) + CH256(E, F, G) + KEYS256[I] + M[I]; + T2 := EP0256(A) + MAJ256(A, B, C); + H := G; + G := F; + F := E; + E := D + T1; + D := C; + C := B; + B := A; + A := T1 + T2; + Inc(I); + end; + + Context.State[0] := Context.State[0] + A; + Context.State[1] := Context.State[1] + B; + Context.State[2] := Context.State[2] + C; + Context.State[3] := Context.State[3] + D; + Context.State[4] := Context.State[4] + E; + Context.State[5] := Context.State[5] + F; + Context.State[6] := Context.State[6] + G; + Context.State[7] := Context.State[7] + H; +end; + +{$WARNINGS OFF} + +procedure SHA512Transform(var Context: TCnSHA512Context; Data: PAnsiChar; BlockCount: Integer); +var + A, B, C, D, E, F, G, H, T1, T2: TUInt64; + M: array[0..79] of TUInt64; + I, J, K: Integer; + OrigData: PAnsiChar; +begin + OrigData := Data; + for K := 0 to BlockCount - 1 do + begin + Data := PAnsiChar(TCnNativeInt(OrigData) + (K shl 7)); + + I := 0; + J := 0; + while I < 16 do + begin + M[I] := (TUInt64(Data[J]) shl 56) or (TUInt64(Data[J + 1]) shl 48) or + (TUInt64(Data[J + 2]) shl 40) or (TUInt64(Data[J + 3]) shl 32) or + (TUInt64(Data[J + 4]) shl 24) or (TUInt64(Data[J + 5]) shl 16) or + (TUInt64(Data[J + 6]) shl 8) or TUInt64(Data[J + 7]); + Inc(I); + Inc(J, 8); + end; + + while I < 80 do + begin + M[I] := Gamma1512(M[I - 2]) + M[I - 7] + Gamma0512(M[I - 15]) + M[I - 16]; + Inc(I); + end; + + A := Context.State[0]; + B := Context.State[1]; + C := Context.State[2]; + D := Context.State[3]; + E := Context.State[4]; + F := Context.State[5]; + G := Context.State[6]; + H := Context.State[7]; + + I := 0; + while I < 80 do + begin + T1 := H + SIG1512(E) + CH512(E, F, G) + KEYS512[I] + M[I]; + T2 := SIG0512(A) + MAJ512(A, B, C); + H := G; + G := F; + F := E; + E := D + T1; + D := C; + C := B; + B := A; + A := T1 + T2; + Inc(I); + end; + + // з޷ WarningӰ + Context.State[0] := Context.State[0] + A; + Context.State[1] := Context.State[1] + B; + Context.State[2] := Context.State[2] + C; + Context.State[3] := Context.State[3] + D; + Context.State[4] := Context.State[4] + E; + Context.State[5] := Context.State[5] + F; + Context.State[6] := Context.State[6] + G; + Context.State[7] := Context.State[7] + H; + end; +end; + +{$WARNINGS ON} + +procedure SHA224Init(var Context: TCnSHA224Context); +begin + Context.DataLen := 0; + Context.BitLen := 0; + Context.State[0] := $C1059ED8; + Context.State[1] := $367CD507; + Context.State[2] := $3070DD17; + Context.State[3] := $F70E5939; + Context.State[4] := $FFC00B31; + Context.State[5] := $68581511; + Context.State[6] := $64F98FA7; + Context.State[7] := $BEFA4FA4; + FillChar(Context.Data, SizeOf(Context.Data), 0); +end; + +procedure SHA224Update(var Context: TCnSHA224Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA256Update(Context, Input, ByteLength); +end; + +procedure SHA256UpdateW(var Context: TCnSHA256Context; Input: PWideChar; CharLength: Cardinal); forward; + +procedure SHA224UpdateW(var Context: TCnSHA224Context; Input: PWideChar; CharLength: Cardinal); +begin + SHA256UpdateW(Context, Input, CharLength); +end; + +procedure SHA224Final(var Context: TCnSHA224Context; var Digest: TCnSHA224Digest); +var + Dig: TCnSHA256Digest; +begin + SHA256Final(Context, Dig); + Move(Dig[0], Digest[0], SizeOf(TCnSHA224Digest)); +end; + +procedure SHA256Init(var Context: TCnSHA256Context); +begin + Context.DataLen := 0; + Context.BitLen := 0; + Context.State[0] := $6A09E667; + Context.State[1] := $BB67AE85; + Context.State[2] := $3C6EF372; + Context.State[3] := $A54FF53A; + Context.State[4] := $510E527F; + Context.State[5] := $9B05688C; + Context.State[6] := $1F83D9AB; + Context.State[7] := $5BE0CD19; + FillChar(Context.Data, SizeOf(Context.Data), 0); +end; + +procedure SHA256Update(var Context: TCnSHA256Context; Input: PAnsiChar; ByteLength: Cardinal); +var + I: Integer; +begin + for I := 0 to ByteLength - 1 do + begin + Context.Data[Context.DataLen] := Byte(Input[I]); + Inc(Context.DataLen); + if Context.DataLen = 64 then + begin + SHA256Transform(Context, @Context.Data[0]); + Context.BitLen := Context.BitLen + 512; + Context.DataLen := 0; + end; + end; +end; + +procedure SHA256UpdateW(var Context: TCnSHA256Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + Content: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(Content, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(Content), CharLength * SizeOf(WideChar), nil, nil); + SHA256Update(Context, Content, iLen); + finally + FreeMem(Content); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SHA256Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +procedure SHA256Final(var Context: TCnSHA256Context; var Digest: TCnSHA256Digest); +var + I: Integer; +begin + I := Context.DataLen; + Context.Data[I] := $80; + Inc(I); + + if Context.Datalen < 56 then + begin + while I < 56 do + begin + Context.Data[I] := 0; + Inc(I); + end; + end + else + begin + while I < 64 do + begin + Context.Data[I] := 0; + Inc(I); + end; + + SHA256Transform(Context, @(Context.Data[0])); + FillChar(Context.Data, 56, 0); + end; + + Context.BitLen := Context.BitLen + Context.DataLen * 8; + Context.Data[63] := Context.Bitlen; + Context.Data[62] := Context.Bitlen shr 8; + Context.Data[61] := Context.Bitlen shr 16; + Context.Data[60] := Context.Bitlen shr 24; + Context.Data[59] := Context.Bitlen shr 32; + Context.Data[58] := Context.Bitlen shr 40; + Context.Data[57] := Context.Bitlen shr 48; + Context.Data[56] := Context.Bitlen shr 56; + SHA256Transform(Context, @(Context.Data[0])); + + for I := 0 to 3 do + begin + Digest[I] := (Context.State[0] shr (24 - I * 8)) and $000000FF; + Digest[I + 4] := (Context.State[1] shr (24 - I * 8)) and $000000FF; + Digest[I + 8] := (Context.State[2] shr (24 - I * 8)) and $000000FF; + Digest[I + 12] := (Context.State[3] shr (24 - I * 8)) and $000000FF; + Digest[I + 16] := (Context.State[4] shr (24 - I * 8)) and $000000FF; + Digest[I + 20] := (Context.State[5] shr (24 - I * 8)) and $000000FF; + Digest[I + 24] := (Context.State[6] shr (24 - I * 8)) and $000000FF; + Digest[I + 28] := (Context.State[7] shr (24 - I * 8)) and $000000FF; + end; +end; + +{$WARNINGS OFF} + +procedure SHA384Init(var Context: TCnSHA384Context); +begin + Context.DataLen := 0; + Context.TotalLen := 0; + Context.State[0] := $CBBB9D5DC1059ED8; + Context.State[1] := $629A292A367CD507; + Context.State[2] := $9159015A3070DD17; + Context.State[3] := $152FECD8F70E5939; + Context.State[4] := $67332667FFC00B31; + Context.State[5] := $8EB44A8768581511; + Context.State[6] := $DB0C2E0D64F98FA7; + Context.State[7] := $47B5481DBEFA4FA4; + FillChar(Context.Data, SizeOf(Context.Data), 0); +end; + +{$WARNINGS ON} + +procedure SHA384Update(var Context: TCnSHA384Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA512Update(Context, Input, ByteLength); +end; + +procedure SHA512UpdateW(var Context: TCnSHA512Context; Input: PWideChar; CharLength: Cardinal); forward; + +procedure SHA384UpdateW(var Context: TCnSHA384Context; Input: PWideChar; CharLength: Cardinal); +begin + SHA512UpdateW(Context, Input, CharLength); +end; + +procedure SHA384Final(var Context: TCnSHA384Context; var Digest: TCnSHA384Digest); +var + Dig: TCnSHA512Digest; +begin + SHA512Final(Context, Dig); + Move(Dig[0], Digest[0], SizeOf(TCnSHA384Digest)); +end; + +{$WARNINGS OFF} + +procedure SHA512Init(var Context: TCnSHA512Context); +begin + Context.DataLen := 0; + Context.TotalLen := 0; + Context.State[0] := $6A09E667F3BCC908; + Context.State[1] := $BB67AE8584CAA73B; + Context.State[2] := $3C6EF372FE94F82B; + Context.State[3] := $A54FF53A5F1D36F1; + Context.State[4] := $510E527FADE682D1; + Context.State[5] := $9B05688C2B3E6C1F; + Context.State[6] := $1F83D9ABFB41BD6B; + Context.State[7] := $5BE0CD19137E2179; + FillChar(Context.Data, SizeOf(Context.Data), 0); +end; + +{$WARNINGS ON} + +procedure SHA512Update(var Context: TCnSHA512Context; Input: PAnsiChar; ByteLength: Cardinal); +var + TempLength, RemainLength, NewLength, BlockCount: Cardinal; +begin + TempLength := 128 - Context.DataLen; + if ByteLength < TempLength then + RemainLength := ByteLength + else + RemainLength := TempLength; + + Move(Input^, Context.Data[Context.DataLen], RemainLength); + if Context.DataLen + ByteLength < 128 then + begin + Inc(Context.DataLen, ByteLength); + Exit; + end; + + NewLength := Cardinal(ByteLength) - RemainLength; + BlockCount := NewLength div 128; + Input := PAnsiChar(TCnNativeUInt(Input) + RemainLength); + + SHA512Transform(Context, @Context.Data[0], 1); + SHA512Transform(Context, Input, BlockCount); + + RemainLength := NewLength mod 128; + Input := PAnsiChar(TCnNativeUInt(Input) + (BlockCount shl 7)); + Move(Input^, Context.Data[Context.DataLen], RemainLength); + + Context.DataLen := RemainLength; + Inc(Context.TotalLen, (BlockCount + 1) shl 7); +end; + +procedure SHA512UpdateW(var Context: TCnSHA512Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + Content: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(Content, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(Content), CharLength * SizeOf(WideChar), nil, nil); + SHA512Update(Context, Content, iLen); + finally + FreeMem(Content); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SHA512Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +procedure SHA512Final(var Context: TCnSHA512Context; var Digest: TCnSHA512Digest); +var + I: Integer; + BlockCount, BitLength, PmLength: Cardinal; +begin + if (Context.DataLen mod 128) > 111 then + BlockCount := 2 + else + BlockCount := 1; + + BitLength := (Context.TotalLen + Context.DataLen) shl 3; + PmLength := BlockCount shl 7; + FillChar(Context.Data[Context.DataLen], PmLength - Context.DataLen, 0); + Context.Data[Context.DataLen] := $80; + + Context.Data[PmLength - 1] := Byte(BitLength); + Context.Data[PmLength - 2] := Byte(BitLength shr 8); + Context.Data[PmLength - 3] := Byte(BitLength shr 16); + Context.Data[PmLength - 4] := Byte(BitLength shr 24); + + SHA512Transform(Context, @(Context.Data[0]), BlockCount); + + for I := 0 to 7 do + begin + Digest[I] := (Context.State[0] shr (56 - I * 8)) and $000000FF; + Digest[I + 8] := (Context.State[1] shr (56 - I * 8)) and $000000FF; + Digest[I + 16] := (Context.State[2] shr (56 - I * 8)) and $000000FF; + Digest[I + 24] := (Context.State[3] shr (56 - I * 8)) and $000000FF; + Digest[I + 32] := (Context.State[4] shr (56 - I * 8)) and $000000FF; + Digest[I + 40] := (Context.State[5] shr (56 - I * 8)) and $000000FF; + Digest[I + 48] := (Context.State[6] shr (56 - I * 8)) and $000000FF; + Digest[I + 56] := (Context.State[7] shr (56 - I * 8)) and $000000FF; + end; +end; + +// ݿ SHA224 +function SHA224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, Input, ByteLength); + SHA224Final(Context, Result); +end; + +// ݿ SHA256 +function SHA256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, Input, ByteLength); + SHA256Final(Context, Result); +end; + +// ݿ SHA384 +function SHA384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, Input, ByteLength); + SHA384Final(Context, Result); +end; + +// ݿ SHA512 +function SHA512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, Input, ByteLength); + SHA512Final(Context, Result); +end; + +// ݿ SHA224 +function SHA224Buffer(const Buffer; Count: Cardinal): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, PAnsiChar(Buffer), Count); + SHA224Final(Context, Result); +end; + +// ݿ SHA256 +function SHA256Buffer(const Buffer; Count: Cardinal): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, PAnsiChar(Buffer), Count); + SHA256Final(Context, Result); +end; + +// ݿ SHA384 +function SHA384Buffer(const Buffer; Count: Cardinal): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, PAnsiChar(Buffer), Count); + SHA384Final(Context, Result); +end; + +// ݿ SHA512 +function SHA512Buffer(const Buffer; Count: Cardinal): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, PAnsiChar(Buffer), Count); + SHA512Final(Context, Result); +end; + +// ֽ SHA224 +function SHA224Bytes(Data: TBytes): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA224Final(Context, Result); +end; + +// ֽ SHA256 +function SHA256Bytes(Data: TBytes): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA256Final(Context, Result); +end; + +// ֽ SHA384 +function SHA384Bytes(Data: TBytes): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA384Final(Context, Result); +end; + +// ֽ SHA512 +function SHA512Bytes(Data: TBytes): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA512Final(Context, Result); +end; + +// String ݽ SHA224 +function SHA224String(const Str: string): TCnSHA224Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA224StringA(AStr); +end; + +// String ݽ SHA256 +function SHA256String(const Str: string): TCnSHA256Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA256StringA(AStr); +end; + +// String ݽ SHA384 +function SHA384String(const Str: string): TCnSHA384Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA384StringA(AStr); +end; + +// String ݽ SHA512 +function SHA512String(const Str: string): TCnSHA512Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA512StringA(AStr); +end; + +// UnicodeString ݽֱӵ SHA224 㣬ת +{$IFDEF UNICODE} +function SHA224UnicodeString(const Str: string): TCnSHA224Digest; +{$ELSE} +function SHA224UnicodeString(const Str: WideString): TCnSHA224Digest; +{$ENDIF} +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA224Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SHA256 㣬ת +{$IFDEF UNICODE} +function SHA256UnicodeString(const Str: string): TCnSHA256Digest; +{$ELSE} +function SHA256UnicodeString(const Str: WideString): TCnSHA256Digest; +{$ENDIF} +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA256Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SHA384 㣬ת +{$IFDEF UNICODE} +function SHA384UnicodeString(const Str: string): TCnSHA384Digest; +{$ELSE} +function SHA384UnicodeString(const Str: WideString): TCnSHA384Digest; +{$ENDIF} +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA384Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SHA512 㣬ת +{$IFDEF UNICODE} +function SHA512UnicodeString(const Str: string): TCnSHA512Digest; +{$ELSE} +function SHA512UnicodeString(const Str: WideString): TCnSHA512Digest; +{$ENDIF} +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA512Final(Context, Result); +end; + +// AnsiString ݽ SHA224 +function SHA224StringA(const Str: AnsiString): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, PAnsiChar(Str), Length(Str)); + SHA224Final(Context, Result); +end; + +// WideString ݽ SHA224 +function SHA224StringW(const Str: WideString): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224UpdateW(Context, PWideChar(Str), Length(Str)); + SHA224Final(Context, Result); +end; + +// AnsiString ݽ SHA256 +function SHA256StringA(const Str: AnsiString): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, PAnsiChar(Str), Length(Str)); + SHA256Final(Context, Result); +end; + +// WideString ݽ SHA256 +function SHA256StringW(const Str: WideString): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256UpdateW(Context, PWideChar(Str), Length(Str)); + SHA256Final(Context, Result); +end; + +// AnsiString ݽ SHA384 +function SHA384StringA(const Str: AnsiString): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, PAnsiChar(Str), Length(Str)); + SHA384Final(Context, Result); +end; + +// WideString ݽ SHA384 +function SHA384StringW(const Str: WideString): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384UpdateW(Context, PWideChar(Str), Length(Str)); + SHA384Final(Context, Result); +end; + +// AnsiString ݽ SHA512 +function SHA512StringA(const Str: AnsiString): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, PAnsiChar(Str), Length(Str)); + SHA512Final(Context, Result); +end; + +// WideString ݽ SHA512 +function SHA512StringW(const Str: WideString): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512UpdateW(Context, PWideChar(Str), Length(Str)); + SHA512Final(Context, Result); +end; + +function InternalSHAStream(Stream: TStream; const BufSize: Cardinal; var D: + TCnSHAGeneralDigest; SHA2Type: TSHA2Type; CallBack: TCnSHACalcProgressFunc = nil): Boolean; +var + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; + + Context224: TCnSHA224Context; + Context256: TCnSHA256Context; + Context384: TCnSHA384Context; + Context512: TCnSHA512Context; + Dig224: TCnSHA224Digest; + Dig256: TCnSHA256Digest; + Dig384: TCnSHA384Digest; + Dig512: TCnSHA512Digest; + + procedure _SHAInit; + begin + case SHA2Type of + stSHA2_224: + SHA224Init(Context224); + stSHA2_256: + SHA256Init(Context256); + stSHA2_384: + SHA384Init(Context384); + stSHA2_512: + SHA512Init(Context512); + end; + end; + + procedure _SHAUpdate; + begin + case SHA2Type of + stSHA2_224: + SHA224Update(Context224, Buf, ReadBytes); + stSHA2_256: + SHA256Update(Context256, Buf, ReadBytes); + stSHA2_384: + SHA384Update(Context384, Buf, ReadBytes); + stSHA2_512: + SHA512Update(Context512, Buf, ReadBytes); + end; + end; + + procedure _SHAFinal; + begin + case SHA2Type of + stSHA2_224: + SHA224Final(Context224, Dig224); + stSHA2_256: + SHA256Final(Context256, Dig256); + stSHA2_384: + SHA384Final(Context384, Dig384); + stSHA2_512: + SHA512Final(Context512, Dig512); + end; + end; + + procedure _CopyResult; + begin + case SHA2Type of + stSHA2_224: + Move(Dig224[0], D[0], SizeOf(TCnSHA224Digest)); + stSHA2_256: + Move(Dig256[0], D[0], SizeOf(TCnSHA256Digest)); + stSHA2_384: + Move(Dig384[0], D[0], SizeOf(TCnSHA384Digest)); + stSHA2_512: + Move(Dig512[0], D[0], SizeOf(TCnSHA512Digest)); + end; + end; + +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then + Exit; + if Size < BufSize then + BufLen := Size + else + BufLen := BufSize; + + CancelCalc := False; + _SHAInit; + + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + _SHAUpdate; + + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then + Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + _SHAFinal; + _CopyResult; + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ָ SHA224 +function SHA224Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA224Digest; +var + Dig: TCnSHAGeneralDigest; +begin + InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_224, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA224Digest)); +end; + +// ָ SHA256 +function SHA256Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA256Digest; +var + Dig: TCnSHAGeneralDigest; +begin + InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_256, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA256Digest)); +end; + +// ָ SHA384 +function SHA384Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA384Digest; +var + Dig: TCnSHAGeneralDigest; +begin + InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_384, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA384Digest)); +end; + +// ָ SHA512 +function SHA512Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA512Digest; +var + Dig: TCnSHAGeneralDigest; +begin + InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_512, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA512Digest)); +end; + +function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} +var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec: Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(AFileName), GENERIC_READ, FILE_SHARE_READ, nil, + OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then + Exit; + try + if not GetFileInformationByHandle(H, Info) then + Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} +end; + +function InternalSHAFile(const FileName: string; SHA2Type: TSHA2Type; + CallBack: TCnSHACalcProgressFunc): TCnSHAGeneralDigest; +var + Context224: TCnSHA224Context; + Context256: TCnSHA256Context; + Context384: TCnSHA384Context; + Context512: TCnSHA512Context; + Dig224: TCnSHA224Digest; + Dig256: TCnSHA256Digest; + Dig384: TCnSHA384Digest; + Dig512: TCnSHA512Digest; + +{$IFDEF MSWINDOWS} + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; + + procedure _SHAInit; + begin + case SHA2Type of + stSHA2_224: + SHA224Init(Context224); + stSHA2_256: + SHA256Init(Context256); + stSHA2_384: + SHA384Init(Context384); + stSHA2_512: + SHA512Init(Context512); + end; + end; + +{$IFDEF MSWINDOWS} + procedure _SHAUpdate; + begin + case SHA2Type of + stSHA2_224: + SHA224Update(Context224, ViewPointer, GetFileSize(FileHandle, nil)); + stSHA2_256: + SHA256Update(Context256, ViewPointer, GetFileSize(FileHandle, nil)); + stSHA2_384: + SHA384Update(Context384, ViewPointer, GetFileSize(FileHandle, nil)); + stSHA2_512: + SHA512Update(Context512, ViewPointer, GetFileSize(FileHandle, nil)); + end; + end; +{$ENDIF} + + procedure _SHAFinal; + begin + case SHA2Type of + stSHA2_224: + SHA224Final(Context224, Dig224); + stSHA2_256: + SHA256Final(Context256, Dig256); + stSHA2_384: + SHA384Final(Context384, Dig384); + stSHA2_512: + SHA512Final(Context512, Dig512); + end; + end; + + procedure _CopyResult(var D: TCnSHAGeneralDigest); + begin + case SHA2Type of + stSHA2_224: + Move(Dig224[0], D[0], SizeOf(TCnSHA224Digest)); + stSHA2_256: + Move(Dig256[0], D[0], SizeOf(TCnSHA256Digest)); + stSHA2_384: + Move(Dig384[0], D[0], SizeOf(TCnSHA384Digest)); + stSHA2_512: + Move(Dig512[0], D[0], SizeOf(TCnSHA512Digest)); + end; + end; + +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSHAStream(Stream, 4096 * 1024, Result, SHA2Type, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + _SHAInit; + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + _SHAUpdate; + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + _SHAFinal; + _CopyResult(Result); +{$ENDIF} + end; +end; + +// ָļݽ SHA224 +function SHA224File(const FileName: string; CallBack: TCnSHACalcProgressFunc): + TCnSHA224Digest; +var + Dig: TCnSHAGeneralDigest; +begin + Dig := InternalSHAFile(FileName, stSHA2_224, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA224Digest)); +end; + +// ָļݽ SHA256 +function SHA256File(const FileName: string; CallBack: TCnSHACalcProgressFunc): + TCnSHA256Digest; +var + Dig: TCnSHAGeneralDigest; +begin + Dig := InternalSHAFile(FileName, stSHA2_256, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA256Digest)); +end; + +// ָļݽ SHA384 +function SHA384File(const FileName: string; CallBack: TCnSHACalcProgressFunc): + TCnSHA384Digest; +var + Dig: TCnSHAGeneralDigest; +begin + Dig := InternalSHAFile(FileName, stSHA2_384, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA384Digest)); +end; + +// ָļݽ SHA512 +function SHA512File(const FileName: string; CallBack: TCnSHACalcProgressFunc): + TCnSHA512Digest; +var + Dig: TCnSHAGeneralDigest; +begin + Dig := InternalSHAFile(FileName, stSHA2_512, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA512Digest)); +end; + +// ʮƸʽ SHA224 Ӵֵ +function SHA224Print(const Digest: TCnSHA224Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA224Digest)); +end; + +// ʮƸʽ SHA256 Ӵֵ +function SHA256Print(const Digest: TCnSHA256Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA256Digest)); +end; + +// ʮƸʽ SHA384 Ӵֵ +function SHA384Print(const Digest: TCnSHA384Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA384Digest)); +end; + +// ʮƸʽ SHA512 Ӵֵ +function SHA512Print(const Digest: TCnSHA512Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA512Digest)); +end; + +// Ƚ SHA224 ӴֵǷ +function SHA224Match(const D1, D2: TCnSHA224Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 28) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// Ƚ SHA256 ӴֵǷ +function SHA256Match(const D1, D2: TCnSHA256Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 32) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// Ƚ SHA384 ӴֵǷ +function SHA384Match(const D1, D2: TCnSHA384Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 48) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// Ƚ SHA512 ӴֵǷ +function SHA512Match(const D1, D2: TCnSHA512Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 64) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// SHA224 Ӵֵת string +function SHA224DigestToStr(const Digest: TCnSHA224Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA224Digest)); +end; + +// SHA256 Ӵֵת string +function SHA256DigestToStr(const Digest: TCnSHA256Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA256Digest)); +end; + +// SHA384 Ӵֵת string +function SHA384DigestToStr(const Digest: TCnSHA384Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA384Digest)); +end; + +// SHA512 Ӵֵת string +function SHA512DigestToStr(const Digest: TCnSHA512Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA512Digest)); +end; + +procedure SHA224HmacInit(var Context: TCnSHA224Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA224Digest; +begin + if KeyLength > HMAC_SHA2_224_256_BLOCK_SIZE_BYTE then + begin + Sum := SHA224Buffer(Key, KeyLength); + KeyLength := HMAC_SHA2_224_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA224Init(Context); + SHA224Update(Context, @(Context.Ipad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); +end; + +procedure SHA224HmacUpdate(var Context: TCnSHA224Context; Input: PAnsiChar; Length: + Cardinal); +begin + SHA224Update(Context, Input, Length); +end; + +procedure SHA224HmacFinal(var Context: TCnSHA224Context; var Output: TCnSHA224Digest); +var + Len: Integer; + TmpBuf: TCnSHA224Digest; +begin + Len := HMAC_SHA2_224_OUTPUT_LENGTH_BYTE; + SHA224Final(Context, TmpBuf); + SHA224Init(Context); + SHA224Update(Context, @(Context.Opad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); + SHA224Update(Context, @(TmpBuf[0]), Len); + SHA224Final(Context, Output); +end; + +procedure SHA256HmacInit(var Context: TCnSHA256Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA256Digest; +begin + if KeyLength > HMAC_SHA2_224_256_BLOCK_SIZE_BYTE then + begin + Sum := SHA256Buffer(Key, KeyLength); + KeyLength := HMAC_SHA2_256_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA256Init(Context); + SHA256Update(Context, @(Context.Ipad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); +end; + +procedure SHA256HmacUpdate(var Context: TCnSHA256Context; Input: PAnsiChar; Length: + Cardinal); +begin + SHA256Update(Context, Input, Length); +end; + +procedure SHA256HmacFinal(var Context: TCnSHA256Context; var Output: TCnSHA256Digest); +var + Len: Integer; + TmpBuf: TCnSHA256Digest; +begin + Len := HMAC_SHA2_256_OUTPUT_LENGTH_BYTE; + SHA256Final(Context, TmpBuf); + SHA256Init(Context); + SHA256Update(Context, @(Context.Opad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); + SHA256Update(Context, @(TmpBuf[0]), Len); + SHA256Final(Context, Output); +end; + +procedure SHA224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA224Digest); +var + Context: TCnSHA224Context; +begin + SHA224HmacInit(Context, Key, KeyByteLength); + SHA224HmacUpdate(Context, Input, ByteLength); + SHA224HmacFinal(Context, Output); +end; + +procedure SHA256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA256Digest); +var + Context: TCnSHA256Context; +begin + SHA256HmacInit(Context, Key, KeyByteLength); + SHA256HmacUpdate(Context, Input, ByteLength); + SHA256HmacFinal(Context, Output); +end; + +procedure SHA384HmacInit(var Context: TCnSHA384Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA384Digest; +begin + if KeyLength > HMAC_SHA2_384_512_BLOCK_SIZE_BYTE then + begin + Sum := SHA384Buffer(Key, KeyLength); + KeyLength := HMAC_SHA2_384_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA384Init(Context); + SHA384Update(Context, @(Context.Ipad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); +end; + +procedure SHA384HmacUpdate(var Context: TCnSHA384Context; Input: PAnsiChar; + Length: Cardinal); +begin + SHA384Update(Context, Input, Length); +end; + +procedure SHA384HmacFinal(var Context: TCnSHA384Context; var Output: TCnSHA384Digest); +var + Len: Integer; + TmpBuf: TCnSHA384Digest; +begin + Len := HMAC_SHA2_384_OUTPUT_LENGTH_BYTE; + SHA384Final(Context, TmpBuf); + SHA384Init(Context); + SHA384Update(Context, @(Context.Opad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); + SHA384Update(Context, @(TmpBuf[0]), Len); + SHA384Final(Context, Output); +end; + +procedure SHA384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA384Digest); +var + Context: TCnSHA384Context; +begin + SHA384HmacInit(Context, Key, KeyByteLength); + SHA384HmacUpdate(Context, Input, ByteLength); + SHA384HmacFinal(Context, Output); +end; + +procedure SHA512HmacInit(var Context: TCnSHA512Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA512Digest; +begin + if KeyLength > HMAC_SHA2_384_512_BLOCK_SIZE_BYTE then + begin + Sum := SHA512Buffer(Key, KeyLength); + KeyLength := HMAC_SHA2_512_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA512Init(Context); + SHA512Update(Context, @(Context.Ipad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); +end; + +procedure SHA512HmacUpdate(var Context: TCnSHA512Context; Input: PAnsiChar; + Length: Cardinal); +begin + SHA512Update(Context, Input, Length); +end; + +procedure SHA512HmacFinal(var Context: TCnSHA512Context; var Output: TCnSHA512Digest); +var + Len: Integer; + TmpBuf: TCnSHA512Digest; +begin + Len := HMAC_SHA2_512_OUTPUT_LENGTH_BYTE; + SHA512Final(Context, TmpBuf); + SHA512Init(Context); + SHA512Update(Context, @(Context.Opad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); + SHA512Update(Context, @(TmpBuf[0]), Len); + SHA512Final(Context, Output); +end; + +procedure SHA512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA512Digest); +var + Context: TCnSHA512Context; +begin + SHA512HmacInit(Context, Key, KeyByteLength); + SHA512HmacUpdate(Context, Input, ByteLength); + SHA512HmacFinal(Context, Output); +end; + +end. diff --git a/CnPack/Crypto/CnSHA3.dcu b/CnPack/Crypto/CnSHA3.dcu new file mode 100644 index 0000000000000000000000000000000000000000..ab48000027067f61ba76ba27ee6468164f3d3a11 GIT binary patch literal 31943 zcmeHw3w%`7)$g7&=S*gXBn%iRAoxuvL5PqK2%-2uCy#+dlMs>_UWyo#$q>u~^HA|K z8X9N`V=T1N3I#9p>R0jc>kSnPUhM@60*V%_w$N$|tyHYw7i!c{k=*~<`@H6nkSO}Q zzu)~v4||=p*Iuu^*4q2LpuoyTA9#SVZu}ViBwKb(Np5EP#Vfi${xP%Nu*{iVQ&d`Z zS6XFF*=J2lZ<7c?1Zm4k>pjg&Z)4@QlI8Ucfocp6I*Wbza|3ntm9;g0`0k>z3OQ?e zL*O4{Kawkyyqbn-Q~z?$3;(FFXP4HMSJsqPecHW3s));~t*r`_)=XdV(w!BKqRg85 z%IqbjbxrqmU0GqPZ>X!R2~Kz^{D zE8-wC5De69d82+uh0V`3Skf|~BWU+5uBvLRUsCtM9n1Cy+OVwv;)O&5c z-j^6m^yHS-lvf32k~6E8ll~QUUuIoh>GC@!-<_W52|7vw4f%nZV8arw)nHG~@*3W+ z|2)B9+()-R4hD3lF}SVr)~AB9_rA&oZmvDEzP>V86Da3rvahZ&@H{30n)~XO zt4l$Jl+^#0_atD?FDz76CAYL?Hdt856wKluLS z3Wrc0d0e%|Rv2`q>F2X=fA4<;iKVZWJpaI{Um0gV*gs`&(4~{6Wg{ON0-K+{^6$`9 zxJ&4jSd#lt(3xFZy$q5O+;NK^n^#tzs5&9Ls^*!Q z+RQ^*EvrmJQ(k*7X%oCcOH*HML1R@zB~3;9!Op8I;(Q_#-z!-9bj66Q1&ebt3v=?l zi)ZHHkG#T}vx^HdeR;DB58eB20_^5)Ay6W^KvwCIPrTIeiob&903=RfV`TD z+Pdme@>JGxq2t2A*X|7t$gZlb4+z99$CgbAx=bSH73cZ9+eyF>j?MJ>iu1DkKJVf} zG9>@mHRu}7yJqHR&RSgJo#Xcw`tmaK7nfvb7XEwP`-g&q3?mClmn}o0yz{pov;-51 zGG_^!W*6o!;4%`>KesY)@9YXv_;=q~^8H`}=UtFl#I4^+nha14qB{JK2a=x)4)oVl zn+HBNWseW8M7=AmZ}8UD)z-b{{>jF&a(i}7A?&{=Kq(ccW(=(Y74hncD46eG929iq zls1(5YI6hk-SFJVxS*4#8b5D%f8@Ggyc)0^ePHVHA;Cn%Zf)Iio(eGWz^<#T!31@b zi1%fWC9dX5WY^ZzH}EJLQj%T66$~@Hva-Sx9Ikamd5^lwGStO+C1ZjL%lGaGBlKoA)C=yksDNNJO2GB%f`IO`i|t4G#58JmxZH&7YV z1WM9T&|9En9R;NX%BG_D{0o#_M`4Zy%9-l$kwD+_Wt6V-QxXa?=Zhj*lDE(cqJ@kN zM2|aVV2KaqvS4wRf97JNFAjN-GJxw`JlkKGQ-UFgr%5STa9~G?FH=ODKu<}zQZsMy zY`?F_?^7d@N2Q>duF)V4d!q5EG;lzVGp@JNp|7E8)7U7@V}+1a;n(==^vV=PnB zD4N*Gq!3{NR^lr$$~=UYBUA(*eayl;-&PANdY}ZD+1UkK_u-*t_%70>qNPn(L&VQVFMI!m_98Ozvo zSF(jDlDgbB>}Ro~!O8R!Wt$xB(pXEo#Jb0cyz$kQ*3{ERf*2&kORSuYj#JADh7@{l+S6`JF|{Y$mV9cDxh+L#D~`A=KD5(!yQQpb083U}bX(FYm_;7CMFo-` zD;sC0m{GUJtW}N{m&_@sN`T4yPm^7uDAK|!E>M8Boldc&A%|^HdE*z-d8urillc0V zm19pzhMbpTaK?4&vPSZQvm=?W|0agQD%%OSHLv_W5^=0-94|J4=R9KiuikhL15dh; zG4m9Dtl=WT8C@!82WiW%Qi$(UlEq!lUdXV9JASlHn2s@?j>Oy1;3Wr~yr^rPF|Ds!XH2_HT4zktv|d|z ze#RxV&W)ut>P8>62Ib|^8jLipH~zTd%^rmF(I^ zzFOJ(?s1iS#x$LK)4WhSanJ1&_uhRjxWnf<_g_qZE{(Y7_lbM&UKiZqb)CEWhv&

NA(3P9!?JiueiT3|zuV96ev0!$^2X$c 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 IRjl;?0`Q@bKL7v# literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnSHA3.pas b/CnPack/Crypto/CnSHA3.pas new file mode 100644 index 0000000..3e0ade0 --- /dev/null +++ b/CnPack/Crypto/CnSHA3.pas @@ -0,0 +1,2700 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnSHA3; +{* |

+================================================================================
+* ƣ
+* ԪƣSHA3 Ӵ㷨ʵֵԪ
+* ԪߣCnPack  (master@cnpack.org)
+*           / Keccak C  Pascal ֲ䲿ֹܡ
+*     עԪʵ SHA3 ϵӴ㷨Ӧ HMAC 㷨 SHA3-224/256/384/512
+*           ɱ䳤ժҪ SHAKE128/SHAKE256ȡ
+*           SHA3 淶 NIST.FIPS.202
+*           SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
+*           жⶨ Bit  Byte ת
+*           ֮ Bit ܹ 8 ʱÿ 8  Bit λþһֽڣֽڼ˳򱣳ֲ䡣
+*
+* ƽ̨PWinXP + Delphi 5.0
+* ݲԣPWinXP/7 + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2023.08.02 V1.4
+*                SHAKE128/SHAKE256 Ŀɱ䳤ժҪļ
+*           2022.04.26 V1.3
+*               ޸ LongWord  Integer ַת֧ MacOS64
+*           2019.12.12 V1.2
+*               ֧ TBytes
+*           2019.04.15 V1.1
+*               ֧ Win32/Win64/MacOS
+*           2017.11.10 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, CnNative, CnConsts; + +const + CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH = 32; + {* SHAKE128 ĬӴսֽڳ} + + CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH = 64; + {* SHAKE256 ĬӴսֽڳ} + +type + PCnSHA3GeneralDigest = ^TCnSHA3GeneralDigest; + TCnSHA3GeneralDigest = array[0..63] of Byte; + {* SHA3 ϵͨõӴս 64 ֽΪ׼} + + PCnSHA3_224Digest = ^TCnSHA3_224Digest; + TCnSHA3_224Digest = array[0..27] of Byte; + {* SHA3_224 Ӵս28 ֽ} + + PCnSHA3_256Digest = ^TCnSHA3_256Digest; + TCnSHA3_256Digest = array[0..31] of Byte; + {* SHA3_256 Ӵս32 ֽ} + + PCnSHA3_384Digest = ^TCnSHA3_384Digest; + TCnSHA3_384Digest = array[0..47] of Byte; + {* SHA3_384 Ӵս48 ֽ} + + PCnSHA3_512Digest = ^TCnSHA3_512Digest; + TCnSHA3_512Digest = array[0..63] of Byte; + {* SHA3_512 Ӵս64 ֽ} + + TCnSHA3Context = packed record + {* SHA3 ϵͨõĽṹ} + State: array[0..24] of Int64; + Index: Cardinal; + DigestLen: Cardinal; + Round: Cardinal; + BlockLen: Cardinal; + Block: array[0..255] of Byte; + Ipad: array[0..143] of Byte; {!< HMAC: inner padding } + Opad: array[0..143] of Byte; {!< HMAC: outer padding } + end; + + TCnSHA3CalcProgressFunc = procedure(ATotal, AProgress: Int64; var Cancel: + Boolean) of object; + {* SHA3 ϵͨõļȻص¼} + +function SHA3_224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_224Digest; +{* ݿ SHA3_224 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_256Digest; +{* ݿ SHA3_256 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_384Digest; +{* ݿ SHA3_384 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_512Digest; +{* ݿ SHA3_512 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHA3_224Buffer(const Buffer; Count: Cardinal): TCnSHA3_224Digest; +{* ݿ SHA3_224 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256Buffer(const Buffer; Count: Cardinal): TCnSHA3_256Digest; +{* ݿ SHA3_256 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384Buffer(const Buffer; Count: Cardinal): TCnSHA3_384Digest; +{* ݿ SHA3_384 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512Buffer(const Buffer; Count: Cardinal): TCnSHA3_512Digest; +{* ݿ SHA3_512 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128Buffer(const Buffer; Count: Cardinal; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* ݿӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256Buffer(const Buffer; Count: Cardinal; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* ݿӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHA3_224Bytes(Data: TBytes): TCnSHA3_224Digest; +{* ֽ SHA3_224 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256Bytes(Data: TBytes): TCnSHA3_256Digest; +{* ֽ SHA3_256 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384Bytes(Data: TBytes): TCnSHA3_384Digest; +{* ֽ SHA3_384 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512Bytes(Data: TBytes): TCnSHA3_512Digest; +{* ֽ SHA3_512 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128Bytes(Data: TBytes; DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* ֽӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս + + + Data: TBytes - ֽ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256Bytes(Data: TBytes; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* ֽӴճȿɱ SHAKE256 㣬سΪ DigestByteLength ֽΪӴս + + + Data: TBytes - ֽ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHA3_224String(const Str: string): TCnSHA3_224Digest; +{* String ݽ SHA3_224 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256String(const Str: string): TCnSHA3_256Digest; +{* String ݽ SHA3_256 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384String(const Str: string): TCnSHA3_384Digest; +{* String ݽ SHA3_384 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512String(const Str: string): TCnSHA3_512Digest; +{* String ݽ SHA3_512 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128String(const Str: string; DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* String ݽӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս + ע D2009 ϰ汾 string Ϊ UnicodeStringлὫǿת AnsiString м㡣 + + + const Str: string - ַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256String(const Str: string; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* String ݽӴճȿɱ SHAKE256 㣬سΪ DigestByteLength ֽΪӴս + ע D2009 ϰ汾 string Ϊ UnicodeStringлὫǿת AnsiString м㡣 + + + const Str: string - ַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHA3_224StringA(const Str: AnsiString): TCnSHA3_224Digest; +{* AnsiString ݽ SHA3_224 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_224StringW(const Str: WideString): TCnSHA3_224Digest; +{* WideString ݽ SHA3_224 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256StringA(const Str: AnsiString): TCnSHA3_256Digest; +{* AnsiString ݽ SHA3_256 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_256StringW(const Str: WideString): TCnSHA3_256Digest; +{* WideStringݽ SHA3_256 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384StringA(const Str: AnsiString): TCnSHA3_384Digest; +{* AnsiString ݽ SHA3_384 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_384StringW(const Str: WideString): TCnSHA3_384Digest; +{* WideString ݽ SHA3_384 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512StringA(const Str: AnsiString): TCnSHA3_512Digest; +{* AnsiString ݽ SHA3_512 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHA3_512StringW(const Str: WideString): TCnSHA3_512Digest; +{* WideString ݽ SHA512 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128StringA(const Str: AnsiString; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* AnsiString ݽӴճȿɱֱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + + + const Str: AnsiString - ַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE128StringW(const Str: WideString; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* WideString ݽӴճȿɱֱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256StringA(const Str: AnsiString; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* AnsiString ݽӴճȿɱֱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + + + const Str: AnsiString - ַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHAKE256StringW(const Str: WideString; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* WideString ݽӴճȿɱֱ SHAKE256 㣬 + سΪ DigestByteLength ֽΪӴս + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +{$IFDEF UNICODE} + +function SHA3_224UnicodeString(const Str: string): TCnSHA3_224Digest; +{* UnicodeString ݽֱӵ SHA3_224 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256UnicodeString(const Str: string): TCnSHA3_256Digest; +{* UnicodeString ݽֱӵ SHA3_256 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384UnicodeString(const Str: string): TCnSHA3_384Digest; +{* UnicodeString ݽֱӵ SHA3_384 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512UnicodeString(const Str: string): TCnSHA3_512Digest; +{* UnicodeString ݽֱӵ SHA3_512 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128UnicodeString(const Str: string; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* UnicodeString ݽӴճȿɱֱ SHAKE128 㣬ֱӼڲ UTF16 ݣת + سΪ DigestByteLength ֽΪӴս + + + const Str: string - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256UnicodeString(const Str: string; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* UnicodeString ݽӴճȿɱֱ SHAKE256 㣬ֱӼڲ UTF16 ݣת + سΪ DigestByteLength ֽΪӴս + + + const Str: string - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +{$ELSE} + +function SHA3_224UnicodeString(const Str: WideString): TCnSHA3_224Digest; +{* UnicodeString ݽֱӵ SHA3_224 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256UnicodeString(const Str: WideString): TCnSHA3_256Digest; +{* UnicodeString ݽֱӵ SHA3_256 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384UnicodeString(const Str: WideString): TCnSHA3_384Digest; +{* UnicodeString ݽֱӵ SHA3_384 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512UnicodeString(const Str: WideString): TCnSHA3_512Digest; +{* UnicodeString ݽֱӵ SHA3_512 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128UnicodeString(const Str: WideString; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* UnicodeString ݽӴճȿɱֱ SHAKE128 㣬ֱӼڲ UTF16 ݣת + سΪ DigestByteLength ֽΪӴս + + + const Str: WideString - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256UnicodeString(const Str: WideString; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* UnicodeString ݽӴճȿɱֱ SHAKE256 㣬ֱӼڲ UTF16 ݣת + سΪ DigestByteLength ֽΪӴս + + + const Str: WideString - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +{$ENDIF} + +function SHA3_224File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = + nil): TCnSHA3_224Digest; +{* ָļݽ SHA3_224 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_224Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): + TCnSHA3_224Digest; +{* ָݽ SHA3_224 㡣 + + + Stream: TStream - + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = + nil): TCnSHA3_256Digest; +{* ָļݽ SHA3_256 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_256Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): + TCnSHA3_256Digest; +{* ָݽ SHA3_256 㡣 + + + Stream: TStream - + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = + nil): TCnSHA3_384Digest; +{* ָļݽ SHA3_384 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_384Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): + TCnSHA3_384Digest; +{* ָݽ SHA3_384 㡣 + + + Stream: TStream - + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = + nil): TCnSHA3_512Digest; +{* ָļݽ SHA3_512 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHA3_512Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): + TCnSHA3_512Digest; +{* ָݽ SHA3_512 㡣 + + + Stream: TStream - + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128File(const FileName: string; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH; + CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; +{* ָļݽӴճȿɱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + + + const FileName: string - ļ + DigestByteLength: Cardinal - Ӵսֽڳ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTBytes - SHAKE128Ӵֵ +} + +function SHAKE128Stream(Stream: TStream; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH; + CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; +{* ָӴճȿɱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + + + Stream: TStream - + DigestByteLength: Cardinal - Ӵսֽڳ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256File(const FileName: string; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH; + CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; +{* ָļݽӴճȿɱ SHAKE256 㣬 + سΪ DigestByteLength ֽΪӴս + + + const FileName: string - ļ + DigestByteLength: Cardinal - Ӵսֽڳ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHAKE256Stream(Stream: TStream; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH; + CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; +{* ָӴճȿɱ SHAKE256 㣬 + سΪ DigestByteLength ֽΪӴս + + + Stream: TStream - + DigestByteLength: Cardinal - Ӵսֽڳ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTBytes - SHAKE256 Ӵֵ +} + +// ⲿݽɢ SHA3_224 㣬SHA3_224Update ɶα + +procedure SHA3_224Init(var Context: TCnSHA3Context); +{* ʼһ SHA3_224 ģ׼ SHA3_224 + + + var Context: TCnSHA3Context - ʼͨ SHA3 + + ֵޣ +} + +procedure SHA3_224Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA3_224 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA3_224Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_224Digest); +{* ּ㣬 SHA3_224 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + var Digest: TCnSHA3_224Digest - ص SHA3_224 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA3_256 㣬SHA3_256Update ɶα + +procedure SHA3_256Init(var Context: TCnSHA3Context); +{* ʼһ SHA3_256 ģ׼ SHA3_256 + + + var Context: TCnSHA3Context - ʼͨ SHA3 + + ֵޣ +} + +procedure SHA3_256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA3_256 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA3_256Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_256Digest); +{* ּ㣬 SHA3_256 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + var Digest: TCnSHA3_256Digest - ص SHA3_256 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA3_384 㣬SHA3_384Update ɶα + +procedure SHA3_384Init(var Context: TCnSHA3Context); +{* ʼһ SHA3_384 ģ׼ SHA3_384 + + + var Context: TCnSHA3Context - ʼͨ SHA3 + + ֵޣ +} + +procedure SHA3_384Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA3_384 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA3_384Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_384Digest); +{* ּ㣬 SHA3_384 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + var Digest: TCnSHA3_384Digest - ص SHA3_384 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA3_512 㣬SHA3_512Update ɶα + +procedure SHA3_512Init(var Context: TCnSHA3Context); +{* ʼһ SHA3_512 ģ׼ SHA3_512 + + + var Context: TCnSHA3Context - ʼͨ SHA3 + + ֵޣ +} + +procedure SHA3_512Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA3_512 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA3_512Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_512Digest); +{* ּ㣬 SHA3_512 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + var Digest: TCnSHA3_512Digest - ص SHA3_512 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHAKE128 㣬SHAKE128Update ɶα + +procedure SHAKE128Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH); +{* ʼһ SHAKE128 ģ׼ SHAKE128 + DigestByteLength ΪӴյֽڳȡ + + + var Context: TCnSHA3Context - ʼͨ SHA3 + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵޣ +} + +procedure SHAKE128Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHAKE128 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHAKE128Final(var Context: TCnSHA3Context; out Digest: TBytes); +{* ּ㣬 SHAKE128 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + out Digest: TBytes - ص SHAKE128 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHAKE128 㣬SHAKE128Update ɶα + +procedure SHAKE256Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH); +{* ʼһ SHAKE256 ģ׼ SHAKE256 + DigestByteLength ΪӴյֽڳȡ + + + var Context: TCnSHA3Context - ʼͨ SHA3 + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵޣ +} + +procedure SHAKE256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHAKE256 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHAKE256Final(var Context: TCnSHA3Context; out Digest: TBytes); +{* ּ㣬 SHAKE256 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + out Digest: TBytes - ص SHAKE256 Ӵֵ + + ֵޣ +} + +function SHA3_224Print(const Digest: TCnSHA3_224Digest): string; +{* ʮƸʽ SHA3_224 Ӵֵ + + + const Digest: TCnSHA3_224Digest - ָ SHA3_224 Ӵֵ + + ֵstring - ʮַ +} + +function SHA3_256Print(const Digest: TCnSHA3_256Digest): string; +{* ʮƸʽ SHA3_256 Ӵֵ + + + const Digest: TCnSHA3_256Digest - ָ SHA3_256 Ӵֵ + + ֵstring - ʮַ +} + +function SHA3_384Print(const Digest: TCnSHA3_384Digest): string; +{* ʮƸʽ SHA3_384 Ӵֵ + + const Digest: TCnSHA3_384Digest - ָ SHA3_384 Ӵֵ + + ֵstring - ʮַ +} + +function SHA3_512Print(const Digest: TCnSHA3_512Digest): string; +{* ʮƸʽ SHA3_512 Ӵֵ + + + const Digest: TCnSHA3_512Digest - ָ SHA3_512 Ӵֵ + + ֵstring - ʮַ +} + +function SHAKE128Print(const Digest: TBytes): string; +{* ʮƸʽ SHAKE128 Ӵֵ + + + const Digest: TBytes - ָ SHAKE128 Ӵֵ + + ֵstring - ʮַ +} + +function SHAKE256Print(const Digest: TBytes): string; +{* ʮƸʽ SHAKE256 Ӵֵ + + + const Digest: TBytes - ָ SHAKE128 Ӵֵ + + ֵstring - ʮַ +} + +function SHA3_224Match(const D1: TCnSHA3_224Digest; const D2: TCnSHA3_224Digest): Boolean; +{* Ƚ SHA3_224 ӴֵǷȡ + + + const D1: TCnSHA3_224Digest - Ƚϵ SHA3_224 Ӵֵһ + const D2: TCnSHA3_224Digest - Ƚϵ SHA3_224 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA3_256Match(const D1: TCnSHA3_256Digest; const D2: TCnSHA3_256Digest): Boolean; +{* Ƚ SHA3_256 ӴֵǷȡ + + + const D1: TCnSHA3_256Digest - Ƚϵ SHA3_256 Ӵֵһ + const D2: TCnSHA3_256Digest - Ƚϵ SHA3_256 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA3_384Match(const D1: TCnSHA3_384Digest; const D2: TCnSHA3_384Digest): Boolean; +{* Ƚ SHA3_384 ӴֵǷȡ + + + const D1: TCnSHA3_384Digest - Ƚϵ SHA3_384 Ӵֵһ + const D2: TCnSHA3_384Digest - Ƚϵ SHA3_384 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA3_512Match(const D1: TCnSHA3_512Digest; const D2: TCnSHA3_512Digest): Boolean; +{* Ƚ SHA3_512 ӴֵǷȡ + + + const D1: TCnSHA3_512Digest - Ƚϵ SHA3_512 Ӵֵһ + const D2: TCnSHA3_512Digest - Ƚϵ SHA3_512 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHAKE128Match(const D1: TBytes; const D2: TBytes): Boolean; +{* Ƚ SHAKE128 ӴֵǷȡ + + + const D1: TBytes - Ƚϵ SHAKE128 Ӵֵһ + const D2: TBytes - Ƚϵ SHAKE128 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHAKE256Match(const D1: TBytes; const D2: TBytes): Boolean; +{* Ƚ SHAKE256 ӴֵǷȡ + + + const D1: TBytes - Ƚϵ SHAKE256 Ӵֵһ + const D2: TBytes - Ƚϵ SHAKE256 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA3_224DigestToStr(const Digest: TCnSHA3_224Digest): string; +{* SHA3_224 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA3_224Digest - ת SHA3_224 Ӵֵ + + ֵstring - صַ +} + +function SHA3_256DigestToStr(const Digest: TCnSHA3_256Digest): string; +{* SHA3_256 Ӵֱֵת stringÿֽڶӦһַ + |
+   Digest: TSHA3_256Digest   - Ҫ
+ |
+ + + const Digest: TCnSHA3_256Digest - ת SHA3_256 Ӵֵ + + ֵstring - صַ +} + +function SHA3_384DigestToStr(const Digest: TCnSHA3_384Digest): string; +{* SHA3_384 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA3_384Digest - ת SHA3_384 Ӵֵ + + ֵstring - صַ +} + +function SHA3_512DigestToStr(const Digest: TCnSHA3_512Digest): string; +{* SHA3_512 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA3_512Digest - ת SHA3_512 Ӵֵ + + ֵstring - صַ +} + +function SHAKE128DigestToStr(const Digest: TBytes): string; +{* SHAKE128 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TBytes - ת SHAKE128 Ӵֵ + + ֵstring - صַ +} + +function SHAKE256DigestToStr(const Digest: TBytes): string; +{* SHAKE256 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TBytes - ת SHAKE256 Ӵֵ + + ֵstring - صַ +} + +procedure SHA3_224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_224Digest); +{* SHA3_224 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA3_224 Կݿַ + KeyByteLength: Integer - SHA3_224 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA3_224Digest - ص SHA3_224 Ӵֵ + + ֵޣ +} + +procedure SHA3_256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_256Digest); +{* SHA3_256 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA3_256 Կݿַ + KeyByteLength: Integer - SHA3_256 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA3_256Digest - ص SHA3_256 Ӵֵ + + ֵޣ +} + +procedure SHA3_384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_384Digest); +{* SHA3_384 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA3_384 Կݿַ + KeyByteLength: Integer - SHA3_384 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA3_384Digest - ص SHA3_384 Ӵֵ + + ֵޣ +} + +procedure SHA3_512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_512Digest); +{* SHA3_512 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA3_512 Կݿַ + KeyByteLength: Integer - SHA3_512 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA3_512Digest - ص SHA3_512 Ӵֵ + + ֵޣ +} + +implementation + +type + TSHA3Type = (stSHA3_224, stSHA3_256, stSHA3_384, stSHA3_512, stSHAKE128, stSHAKE256); + +const + MAX_FILE_SIZE = 512 * 1024 * 1024; + STREAM_BUF_SIZE = 4096 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + SHA3_ROUNDS = 24; + SHA3_STATE_LEN = 25; + + SHA3_224_OUTPUT_LENGTH_BYTE = 28; + SHA3_256_OUTPUT_LENGTH_BYTE = 32; + SHA3_384_OUTPUT_LENGTH_BYTE = 48; + SHA3_512_OUTPUT_LENGTH_BYTE = 64; + + SHA3_224_BLOCK_SIZE_BYTE = 144; + SHA3_256_BLOCK_SIZE_BYTE = 136; + SHA3_384_BLOCK_SIZE_BYTE = 104; + SHA3_512_BLOCK_SIZE_BYTE = 72; + + SHAKE128_BLOCK_SIZE_BYTE = 168; + SHAKE256_BLOCK_SIZE_BYTE = 136; + + HMAC_SHA3_224_BLOCK_SIZE_BYTE = SHA3_224_BLOCK_SIZE_BYTE; + HMAC_SHA3_256_BLOCK_SIZE_BYTE = SHA3_256_BLOCK_SIZE_BYTE; + HMAC_SHA3_384_BLOCK_SIZE_BYTE = SHA3_384_BLOCK_SIZE_BYTE; + HMAC_SHA3_512_BLOCK_SIZE_BYTE = SHA3_512_BLOCK_SIZE_BYTE; + + HMAC_SHA3_224_OUTPUT_LENGTH_BYTE = SHA3_224_OUTPUT_LENGTH_BYTE; + HMAC_SHA3_256_OUTPUT_LENGTH_BYTE = SHA3_256_OUTPUT_LENGTH_BYTE; + HMAC_SHA3_384_OUTPUT_LENGTH_BYTE = SHA3_384_OUTPUT_LENGTH_BYTE; + HMAC_SHA3_512_OUTPUT_LENGTH_BYTE = SHA3_512_OUTPUT_LENGTH_BYTE; + + KECCAKF_ROUND_CONSTS: array[0..23] of TUInt64 = ( + $0000000000000001, $0000000000008082, $800000000000808A, + $8000000080008000, $000000000000808B, $0000000080000001, + $8000000080008081, $8000000000008009, $000000000000008A, + $0000000000000088, $0000000080008009, $000000008000000A, + $000000008000808B, $800000000000008B, $8000000000008089, + $8000000000008003, $8000000000008002, $8000000000000080, + $000000000000800A, $800000008000000A, $8000000080008081, + $8000000000008080, $0000000080000001, $8000000080008008 + ); + + KECCAKF_ROT_CONSTS: array[0..23] of Integer = ( + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 + ); + + KECCAKF_PILN: array[0..23] of Integer = ( + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 + ); + +function ROTL64(Q: TUInt64; N: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (Q shl N) xor (Q shr (64 - N)); +end; + +// һ SHA3 㣬 Block ݣ State +procedure SHA3_Transform(var Context: TCnSHA3Context); +type + PUInt64Array = ^TUInt64Array; + TUInt64Array = array[0..4095] of TUInt64; +var + I, J, R, L: Integer; + P: PUInt64Array; + T: TUInt64; + BC: array[0..4] of TUInt64; +begin + P := PUInt64Array(@(Context.Block[0])); + I := 0; + L := Integer(Context.BlockLen div 8); + while I < L do + begin + Context.State[I] := Context.State[I] xor P^[I]; + Inc(I); + end; + + for R := 0 to Context.Round - 1 do + begin + // Theta + for I := 0 to 4 do + begin + BC[I] := Context.State[I] xor Context.State[I + 5] xor Context.State[I + 10] + xor Context.State[I + 15] xor Context.State[I + 20]; + end; + for I := 0 to 4 do + begin + T := BC[(I + 4) mod 5] xor ROTL64(BC[(I + 1) mod 5], 1); + for J := 0 to 4 do + Context.State[5 * J + I] := Context.State[5 * J + I] xor T; + end; + + // Rho Pi + T := Context.State[1]; + for I := 0 to 23 do + begin + J := KECCAKF_PILN[I]; + BC[0] := Context.State[J]; + Context.State[J] := ROTL64(T, KECCAKF_ROT_CONSTS[I]); + T := BC[0]; + end; + + // Chi + for J := 0 to 4 do + begin + for I := 0 to 4 do + BC[I] := Context.State[5 * J + I]; + + for I := 0 to 4 do + Context.State[5 * J + I] := Context.State[5 * J + I] xor + ((not BC[(I + 1) mod 5]) and BC[(I + 2) mod 5]); + end; + + // Iota + Context.State[0] := Context.State[0] xor KECCAKF_ROUND_CONSTS[R]; + end; +end; + +procedure SHA3Init(var Context: TCnSHA3Context; SHA3Type: TSHA3Type; + DigestByteLength: Cardinal = 0); +begin + FillChar(Context.State, SizeOf(Context.State), 0); + FillChar(Context.Block, SizeOf(Context.Block), 0); + Context.Index := 0; + Context.Round := SHA3_ROUNDS; + + case SHA3Type of + stSHA3_224: + begin + Context.BlockLen := SHA3_224_BLOCK_SIZE_BYTE; + Context.DigestLen := SHA3_224_OUTPUT_LENGTH_BYTE; + end; + stSHA3_256: + begin + Context.BlockLen := SHA3_256_BLOCK_SIZE_BYTE; + Context.DigestLen := SHA3_256_OUTPUT_LENGTH_BYTE; + end; + stSHA3_384: + begin + Context.BlockLen := SHA3_384_BLOCK_SIZE_BYTE; + Context.DigestLen := SHA3_384_OUTPUT_LENGTH_BYTE; + end; + stSHA3_512: + begin + Context.BlockLen := SHA3_512_BLOCK_SIZE_BYTE; + Context.DigestLen := SHA3_512_OUTPUT_LENGTH_BYTE; + end; + stSHAKE128: + begin + Context.BlockLen := SHAKE128_BLOCK_SIZE_BYTE; + Context.DigestLen := DigestByteLength; + end; + stSHAKE256: + begin + Context.BlockLen := SHAKE256_BLOCK_SIZE_BYTE; + Context.DigestLen := DigestByteLength; + end; + end; +end; + +procedure SHA3Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +var + R, Idx: Cardinal; +begin + Idx := Context.Index; // Index Block еijʼλָ + repeat + if ByteLength < Context.BlockLen - Idx then + R := ByteLength //  + else + R := Context.BlockLen - Idx; // ܻʣ + + FillChar(Context.Block[Idx], SizeOf(Context.Block) - Idx, 0); // ȷβΪ 0 + Move(Input^, Context.Block[Idx], R); // Block ǰ벿ֲ + + if (Idx + R) < Context.BlockLen then // ûֲ + begin // ֻ Index λָ + Idx := Idx + R; + Break; + end; + + SHA3_Transform(Context); + Dec(ByteLength, R); + Idx := 0; + Inc(Input, R); + until False; + Context.Index := Idx; +end; + +procedure SHA3UpdateW(var Context: TCnSHA3Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + Content: PAnsiChar; + Len: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(Content, CharLength * SizeOf(WideChar)); + try + Len := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(Content), CharLength * SizeOf(WideChar), nil, nil); + SHA3Update(Context, Content, Len); + finally + FreeMem(Content); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SHA3Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +// SHA3_224/256/384/512 ר +procedure SHA3Final(var Context: TCnSHA3Context; var Digest: TCnSHA3GeneralDigest); overload; +begin + Context.Block[Context.Index] := 6; + Context.Block[Context.BlockLen - 1] := Context.Block[Context.BlockLen - 1] or $80; + SHA3_Transform(Context); + Move(Context.State[0], Digest[0], Context.DigestLen); +end; + +// SHAKE128 SHAKE256 ר +procedure SHA3Final(var Context: TCnSHA3Context; out Digest: TBytes); overload; +var + Idx, DL: Cardinal; +begin + Context.Block[Context.Index] := $1F; + Context.Block[Context.BlockLen - 1] := Context.Block[Context.BlockLen - 1] or $80; + SHA3_Transform(Context); + + SetLength(Digest, Context.DigestLen); + if Context.DigestLen <= Context.BlockLen then + Move(Context.State[0], Digest[0], Context.DigestLen) + else + begin + DL := Context.DigestLen; + Idx := 0; + + while DL >= Context.BlockLen do + begin + Move(Context.State[0], Digest[Idx], Context.BlockLen); + Inc(Idx, Context.BlockLen); + Dec(DL, Context.BlockLen); + + if DL > 0 then + begin + FillChar(Context.Block[0], SizeOf(Context.Block), 0); + SHA3_Transform(Context); + end; + end; + + if DL > 0 then + Move(Context.State[0], Digest[Idx], DL); + end; +end; + +procedure SHA3_224Init(var Context: TCnSHA3Context); +begin + SHA3Init(Context, stSHA3_224); +end; + +procedure SHA3_224Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_224Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_224Digest); +var + Res: TCnSHA3GeneralDigest; +begin + SHA3Final(Context, Res); + Move(Res[0], Digest[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +procedure SHA3_256Init(var Context: TCnSHA3Context); +begin + SHA3Init(Context, stSHA3_256); +end; + +procedure SHA3_256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_256Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_256Digest); +var + Res: TCnSHA3GeneralDigest; +begin + SHA3Final(Context, Res); + Move(Res[0], Digest[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +procedure SHA3_384Init(var Context: TCnSHA3Context); +begin + SHA3Init(Context, stSHA3_384); +end; + +procedure SHA3_384Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_384Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_384Digest); +var + Res: TCnSHA3GeneralDigest; +begin + SHA3Final(Context, Res); + Move(Res[0], Digest[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +procedure SHA3_512Init(var Context: TCnSHA3Context); +begin + SHA3Init(Context, stSHA3_512); +end; + +procedure SHA3_512Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_512Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_512Digest); +var + Res: TCnSHA3GeneralDigest; +begin + SHA3Final(Context, Res); + Move(Res[0], Digest[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +procedure SHAKE128Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal); +begin + SHA3Init(Context, stSHAKE128, DigestByteLength); +end; + +procedure SHAKE128Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHAKE128Final(var Context: TCnSHA3Context; out Digest: TBytes); +begin + SHA3Final(Context, Digest); +end; + +procedure SHAKE256Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal); +begin + SHA3Init(Context, stSHAKE256, DigestByteLength); +end; + +procedure SHAKE256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHAKE256Final(var Context: TCnSHA3Context; out Digest: TBytes); +begin + SHA3Final(Context, Digest); +end; + +// ݿ SHA3_224λ +function SHA3_224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, Input, ByteLength); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_256λ +function SHA3_256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, Input, ByteLength); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_384λ +function SHA3_384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, Input, ByteLength); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_512λ +function SHA3_512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, Input, ByteLength); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_224 +function SHA3_224Buffer(const Buffer; Count: Cardinal): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, PAnsiChar(Buffer), Count); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_256 +function SHA3_256Buffer(const Buffer; Count: Cardinal): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, PAnsiChar(Buffer), Count); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_384 +function SHA3_384Buffer(const Buffer; Count: Cardinal): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, PAnsiChar(Buffer), Count); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_512 +function SHA3_512Buffer(const Buffer; Count: Cardinal): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, PAnsiChar(Buffer), Count); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHAKE128 +function SHAKE128Buffer(const Buffer; Count: Cardinal; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHAKE128Update(Context, PAnsiChar(Buffer), Count); + SHAKE128Final(Context, Result); +end; + +// ݿ SHAKE256 +function SHAKE256Buffer(const Buffer; Count: Cardinal; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHAKE256Update(Context, PAnsiChar(Buffer), Count); + SHAKE256Final(Context, Result); +end; + +// ֽ SHA3_224 +function SHA3_224Bytes(Data: TBytes): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// ֽ SHA3_256 +function SHA3_256Bytes(Data: TBytes): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// ֽ SHA3_384 +function SHA3_384Bytes(Data: TBytes): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// ֽ SHA3_512 +function SHA3_512Bytes(Data: TBytes): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// ֽ SHAKE128 +function SHAKE128Bytes(Data: TBytes; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHAKE128Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHAKE128Final(Context, Result); +end; + +// ֽ SHAKE256 +function SHAKE256Bytes(Data: TBytes; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHAKE256Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHAKE256Final(Context, Result); +end; + +// String ݽ SHA3_224 +function SHA3_224String(const Str: string): TCnSHA3_224Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA3_224StringA(AStr); +end; + +// String ݽ SHA3_256 +function SHA3_256String(const Str: string): TCnSHA3_256Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA3_256StringA(AStr); +end; + +// String ݽ SHA3_384 +function SHA3_384String(const Str: string): TCnSHA3_384Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA3_384StringA(AStr); +end; + +// String ݽ SHA3_512 +function SHA3_512String(const Str: string): TCnSHA3_512Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA3_512StringA(AStr); +end; + +// String ݽ SHAKE128 +function SHAKE128String(const Str: string; DigestByteLength: Cardinal): TBytes; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHAKE128StringA(AStr, DigestByteLength); +end; + +// String ݽ SHAKE256 +function SHAKE256String(const Str: string; DigestByteLength: Cardinal): TBytes; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHAKE256StringA(AStr, DigestByteLength); +end; + +// UnicodeString ݽֱӵ SHA3_224 㣬ת +{$IFDEF UNICODE} +function SHA3_224UnicodeString(const Str: string): TCnSHA3_224Digest; +{$ELSE} +function SHA3_224UnicodeString(const Str: WideString): TCnSHA3_224Digest; +{$ENDIF} +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// UnicodeString ݽֱӵ SHA3_256 㣬ת +{$IFDEF UNICODE} +function SHA3_256UnicodeString(const Str: string): TCnSHA3_256Digest; +{$ELSE} +function SHA3_256UnicodeString(const Str: WideString): TCnSHA3_256Digest; +{$ENDIF} +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// UnicodeString ݽֱӵ SHA3_384 㣬ת +{$IFDEF UNICODE} +function SHA3_384UnicodeString(const Str: string): TCnSHA3_384Digest; +{$ELSE} +function SHA3_384UnicodeString(const Str: WideString): TCnSHA3_384Digest; +{$ENDIF} +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// UnicodeString ݽֱӵ SHA3_512 㣬ת +{$IFDEF UNICODE} +function SHA3_512UnicodeString(const Str: string): TCnSHA3_512Digest; +{$ELSE} +function SHA3_512UnicodeString(const Str: WideString): TCnSHA3_512Digest; +{$ENDIF} +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// UnicodeString ݽֱӵ SHAKE128 㣬ת +{$IFDEF UNICODE} +function SHAKE128UnicodeString(const Str: string; DigestByteLength: Cardinal): TBytes; +{$ELSE} +function SHAKE128UnicodeString(const Str: WideString; DigestByteLength: Cardinal): TBytes; +{$ENDIF} +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHAKE128Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHAKE128Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SHAKE256 㣬ת +{$IFDEF UNICODE} +function SHAKE256UnicodeString(const Str: string; DigestByteLength: Cardinal): TBytes; +{$ELSE} +function SHAKE256UnicodeString(const Str: WideString; DigestByteLength: Cardinal): TBytes; +{$ENDIF} +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHAKE256Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHAKE256Final(Context, Result); +end; + +// AnsiString ݽSHA224 +function SHA3_224StringA(const Str: AnsiString): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, PAnsiChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// WideString ݽ SHA3_224 +function SHA3_224StringW(const Str: WideString): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// AnsiString ݽ SHA3_256 +function SHA3_256StringA(const Str: AnsiString): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, PAnsiChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// WideString ݽ SHA3_256 +function SHA3_256StringW(const Str: WideString): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// AnsiString ݽ SHA3_384 +function SHA3_384StringA(const Str: AnsiString): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, PAnsiChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// WideString ݽ SHA3_384 +function SHA3_384StringW(const Str: WideString): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// AnsiString ݽ SHA3_512 +function SHA3_512StringA(const Str: AnsiString): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, PAnsiChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// WideString ݽ SHA3_512 +function SHA3_512StringW(const Str: WideString): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// AnsiString ݽ SHAKE128 +function SHAKE128StringA(const Str: AnsiString; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHAKE128Update(Context, PAnsiChar(Str), Length(Str)); + SHAKE128Final(Context, Result); +end; + +// WideString ݽ SHAKE128 +function SHAKE128StringW(const Str: WideString; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); // SHAKE128UpdateW = SHA3UpdateW + SHAKE128Final(Context, Result); +end; + +// AnsiString ݽ SHAKE256 +function SHAKE256StringA(const Str: AnsiString; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHAKE256Update(Context, PAnsiChar(Str), Length(Str)); + SHAKE256Final(Context, Result); +end; + +// WideString ݽ SHAKE256 +function SHAKE256StringW(const Str: WideString; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); // SHAKE256UpdateW = SHA3UpdateW + SHAKE256Final(Context, Result); +end; + +// SHA3Type ֻ stSHA3_224, stSHA3_256, stSHA3_384, stSHA3_512 +function InternalSHA3Stream(Stream: TStream; const BufSize: Cardinal; var D: + TCnSHA3GeneralDigest; SHA3Type: TSHA3Type; CallBack: TCnSHA3CalcProgressFunc): Boolean; overload; +var + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; + Context: TCnSHA3Context; +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then + Exit; + if Size < BufSize then + BufLen := Size + else + BufLen := BufSize; + + CancelCalc := False; + SHA3Init(Context, SHA3Type); + + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + SHA3Update(Context, Buf, ReadBytes); + + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then + Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + SHA3Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// SHA3Type ֻ stSHAKE128 stSHAKE256 +function InternalSHA3Stream(Stream: TStream; const BufSize: Cardinal; + SHA3Type: TSHA3Type; DigestByteLength: Cardinal; out D: TBytes; + CallBack: TCnSHA3CalcProgressFunc): Boolean; overload; +var + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; + Context: TCnSHA3Context; +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then + Exit; + if Size < BufSize then + BufLen := Size + else + BufLen := BufSize; + + CancelCalc := False; + SHA3Init(Context, SHA3Type, DigestByteLength); + + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + SHA3Update(Context, Buf, ReadBytes); + + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then + Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + SHA3Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ָ SHA3_224 +function SHA3_224Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_224Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_224, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_224Digest)); +end; + +// ָ SHA3_256 +function SHA3_256Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_256Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_256, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_256Digest)); +end; + +// ָ SHA3_384 +function SHA3_384Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_384Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_384, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_384Digest)); +end; + +// ָ SHA3_512 +function SHA3_512Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_512Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_512, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_512Digest)); +end; + +// ָӴճȿɱ SHAKE128 +function SHAKE128Stream(Stream: TStream; DigestByteLength: Cardinal; + CallBack: TCnSHA3CalcProgressFunc): TBytes; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, stSHAKE128, DigestByteLength, Result, CallBack); +end; + +// ָӴճȿɱ SHAKE256 +function SHAKE256Stream(Stream: TStream; DigestByteLength: Cardinal; + CallBack: TCnSHA3CalcProgressFunc): TBytes; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, stSHAKE256, DigestByteLength, Result, CallBack); +end; + +function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} +var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec: Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(AFileName), GENERIC_READ, FILE_SHARE_READ, nil, + OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then + Exit; + try + if not GetFileInformationByHandle(H, Info) then + Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} +end; + +function InternalSHA3File(const FileName: string; SHA3Type: TSHA3Type; + CallBack: TCnSHA3CalcProgressFunc): TCnSHA3GeneralDigest; overload; +var +{$IFDEF MSWINDOWS} + Context: TCnSHA3Context; + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Result, SHA3Type, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + SHA3Init(Context, SHA3Type); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + SHA3Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + SHA3Final(Context, Result); +{$ENDIF} + end; +end; + +function InternalSHA3File(const FileName: string; SHA3Type: TSHA3Type; + DigestByteLength: Cardinal; CallBack: TCnSHA3CalcProgressFunc): TBytes; overload; +var +{$IFDEF MSWINDOWS} + Context: TCnSHA3Context; + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, SHA3Type, DigestByteLength, Result, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + SHA3Init(Context, SHA3Type, DigestByteLength); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + SHA3Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + SHA3Final(Context, Result); +{$ENDIF} + end; +end; + +// ָļݽ SHA3_224 +function SHA3_224File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_224Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + Dig := InternalSHA3File(FileName, stSHA3_224, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_224Digest)); +end; + +// ָļݽ SHA3_256 +function SHA3_256File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_256Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + Dig := InternalSHA3File(FileName, stSHA3_256, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_256Digest)); +end; + +// ָļݽ SHA3_384 +function SHA3_384File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_384Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + Dig := InternalSHA3File(FileName, stSHA3_384, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_384Digest)); +end; + +// ָļݽ SHA3_512 +function SHA3_512File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_512Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + Dig := InternalSHA3File(FileName, stSHA3_512, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_512Digest)); +end; + +// ָļݽӴճȿɱ SHAKE128 +function SHAKE128File(const FileName: string; DigestByteLength: Cardinal; + CallBack: TCnSHA3CalcProgressFunc): TBytes; +begin + Result := InternalSHA3File(FileName, stSHAKE128, DigestByteLength, CallBack); +end; + +// ָļݽӴճȿɱ SHAKE256 +function SHAKE256File(const FileName: string; DigestByteLength: Cardinal; + CallBack: TCnSHA3CalcProgressFunc): TBytes; +begin + Result := InternalSHA3File(FileName, stSHAKE256, DigestByteLength, CallBack); +end; + +// ʮƸʽ SHA3_224 Ӵֵ +function SHA3_224Print(const Digest: TCnSHA3_224Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_224Digest)); +end; + +// ʮƸʽ SHA3_256 Ӵֵ +function SHA3_256Print(const Digest: TCnSHA3_256Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_256Digest)); +end; + +// ʮƸʽ SHA3_384 Ӵֵ +function SHA3_384Print(const Digest: TCnSHA3_384Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_384Digest)); +end; + +// ʮƸʽ SHA3_512 Ӵֵ +function SHA3_512Print(const Digest: TCnSHA3_512Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_512Digest)); +end; + +// ʮƸʽ SHAKE128 Ӵֵ +function SHAKE128Print(const Digest: TBytes): string; +begin + Result := BytesToHex(Digest); +end; + +// ʮƸʽ SHAKE256 Ӵֵ +function SHAKE256Print(const Digest: TBytes): string; +begin + Result := BytesToHex(Digest); +end; + +// Ƚ SHA3_224 ӴֵǷ +function SHA3_224Match(const D1, D2: TCnSHA3_224Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_224Digest)); +end; + +// Ƚ SHA3_256 ӴֵǷ +function SHA3_256Match(const D1, D2: TCnSHA3_256Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_256Digest)); +end; + +// Ƚ SHA3_384 ӴֵǷ +function SHA3_384Match(const D1, D2: TCnSHA3_384Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_384Digest)); +end; + +// Ƚ SHA3_512 ӴֵǷ +function SHA3_512Match(const D1, D2: TCnSHA3_512Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_512Digest));; +end; + +// Ƚ SHAKE128 ӴֵǷ +function SHAKE128Match(const D1, D2: TBytes): Boolean; +begin + Result := CompareBytes(D1, D2); +end; + +// Ƚ SHAKE256 ӴֵǷ +function SHAKE256Match(const D1, D2: TBytes): Boolean; +begin + Result := CompareBytes(D1, D2); +end; + +// SHA3_224 Ӵֵת string +function SHA3_224DigestToStr(const Digest: TCnSHA3_224Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_224Digest)); +end; + +// SHA3_256 Ӵֵת string +function SHA3_256DigestToStr(const Digest: TCnSHA3_256Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_256Digest));; +end; + +// SHA3_384 Ӵֵת string +function SHA3_384DigestToStr(const Digest: TCnSHA3_384Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_384Digest)); +end; + +// SHA3_512 Ӵֵת string +function SHA3_512DigestToStr(const Digest: TCnSHA3_512Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_512Digest)); +end; + +// SHAKE128 Ӵֵת string +function SHAKE128DigestToStr(const Digest: TBytes): string; +begin + Result := BytesToString(Digest); +end; + +// SHAKE256 Ӵֵת string +function SHAKE256DigestToStr(const Digest: TBytes): string; +begin + Result := BytesToString(Digest); +end; + +procedure SHA3_224HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA3_224Digest; +begin + if KeyLength > HMAC_SHA3_224_BLOCK_SIZE_BYTE then + begin + Sum := SHA3_224Buffer(Key, KeyLength); + KeyLength := HMAC_SHA3_224_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA3_224_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA3_224_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_224_BLOCK_SIZE_BYTE); +end; + +procedure SHA3_256HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA3_256Digest; +begin + if KeyLength > HMAC_SHA3_256_BLOCK_SIZE_BYTE then + begin + Sum := SHA3_256Buffer(Key, KeyLength); + KeyLength := HMAC_SHA3_256_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA3_256_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA3_256_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_256_BLOCK_SIZE_BYTE); +end; + +procedure SHA3_384HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA3_384Digest; +begin + if KeyLength > HMAC_SHA3_384_BLOCK_SIZE_BYTE then + begin + Sum := SHA3_384Buffer(Key, KeyLength); + KeyLength := HMAC_SHA3_384_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA3_384_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA3_384_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_384_BLOCK_SIZE_BYTE); +end; + +procedure SHA3_512HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA3_512Digest; +begin + if KeyLength > HMAC_SHA3_512_BLOCK_SIZE_BYTE then + begin + Sum := SHA3_512Buffer(Key, KeyLength); + KeyLength := HMAC_SHA3_512_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA3_512_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA3_512_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_512_BLOCK_SIZE_BYTE); +end; + +procedure SHA3_224HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; + ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_256HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; + ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_384HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; + ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_512HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; + ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_224HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); +var + Len: Integer; + TmpBuf: TCnSHA3GeneralDigest; +begin + Len := HMAC_SHA3_224_OUTPUT_LENGTH_BYTE; + SHA3Final(Context, TmpBuf); + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_224_BLOCK_SIZE_BYTE); + SHA3Update(Context, @(TmpBuf[0]), Len); + SHA3Final(Context, Output); +end; + +procedure SHA3_256HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); +var + Len: Integer; + TmpBuf: TCnSHA3GeneralDigest; +begin + Len := HMAC_SHA3_256_OUTPUT_LENGTH_BYTE; + SHA3Final(Context, TmpBuf); + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_256_BLOCK_SIZE_BYTE); + SHA3Update(Context, @(TmpBuf[0]), Len); + SHA3Final(Context, Output); +end; + +procedure SHA3_384HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); +var + Len: Integer; + TmpBuf: TCnSHA3GeneralDigest; +begin + Len := HMAC_SHA3_384_OUTPUT_LENGTH_BYTE; + SHA3Final(Context, TmpBuf); + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_384_BLOCK_SIZE_BYTE); + SHA3Update(Context, @(TmpBuf[0]), Len); + SHA3Final(Context, Output); +end; + +procedure SHA3_512HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); +var + Len: Integer; + TmpBuf: TCnSHA3GeneralDigest; +begin + Len := HMAC_SHA3_512_OUTPUT_LENGTH_BYTE; + SHA3Final(Context, TmpBuf); + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_512_BLOCK_SIZE_BYTE); + SHA3Update(Context, @(TmpBuf[0]), Len); + SHA3Final(Context, Output); +end; + +procedure SHA3_224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_224Digest); +var + Context: TCnSHA3Context; + Dig: TCnSHA3GeneralDigest; +begin + SHA3_224HmacInit(Context, Key, KeyByteLength); + SHA3_224HmacUpdate(Context, Input, ByteLength); + SHA3_224HmacFinal(Context, Dig); + Move(Dig[0], Output[0], Context.DigestLen); +end; + +procedure SHA3_256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_256Digest); +var + Context: TCnSHA3Context; + Dig: TCnSHA3GeneralDigest; +begin + SHA3_256HmacInit(Context, Key, KeyByteLength); + SHA3_256HmacUpdate(Context, Input, ByteLength); + SHA3_256HmacFinal(Context, Dig); + Move(Dig[0], Output[0], Context.DigestLen); +end; + +procedure SHA3_384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_384Digest); +var + Context: TCnSHA3Context; + Dig: TCnSHA3GeneralDigest; +begin + SHA3_384HmacInit(Context, Key, KeyByteLength); + SHA3_384HmacUpdate(Context, Input, ByteLength); + SHA3_384HmacFinal(Context, Dig); + Move(Dig[0], Output[0], Context.DigestLen); +end; + +procedure SHA3_512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_512Digest); +var + Context: TCnSHA3Context; + Dig: TCnSHA3GeneralDigest; +begin + SHA3_512HmacInit(Context, Key, KeyByteLength); + SHA3_512HmacUpdate(Context, Input, ByteLength); + SHA3_512HmacFinal(Context, Dig); + Move(Dig[0], Output[0], Context.DigestLen); +end; + +end. diff --git a/CnPack/Crypto/CnSM3.dcu b/CnPack/Crypto/CnSM3.dcu new file mode 100644 index 0000000000000000000000000000000000000000..5702308fecc90851e7e1705244d10cf62f426a3c GIT binary patch literal 14942 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 hoP3Lj*(N*248(j>HZvNH_!X!X +================================================================================ +* ƣ +* Ԫƣ SM3 Ӵ㷨ʵֵԪ +* ԪߣCnPack 飨master@cnpack.org) +* οֲ goldboar C +* עԪʵ˹ SM3 Ӵ㷨Ӧ HMAC 㷨 +* ο㷨ĵSM3 Cryptographic Hash Algorith +* http://www.oscca.gov.cn/UpFile/20101222141857786.pdf +* +* ƽ̨Windows 7 + Delphi 5.0 +* ݲԣPWin9X/2000/XP/7 + Delphi 5/6 +* õԪеַϱػʽ +* ޸ļ¼2019.12.12 V1.2 +* ֧ TBytes +* 2019.04.15 V1.1 +* ֧ Win32/Win64/MacOS +* 2014.09.23 V1.0 +* ֲԪ +================================================================================ +|} + +interface + +{$I CnPack.inc} + +uses + Classes, SysUtils, CnNative, CnConsts {$IFDEF MSWINDOWS}, Windows {$ENDIF}; + +type + PCnSM3Digest = ^TCnSM3Digest; + TCnSM3Digest = array[0..31] of Byte; + {* SM3 Ӵս32 ֽ} + + TCnSM3Context = packed record + {* SM3 Ľṹ} + Total: array[0..1] of Cardinal; {!< number of bytes processed } + State: array[0..7] of Cardinal; {!< intermediate digest state } + Buffer: array[0..63] of Byte; {!< data block being processed } + Ipad: array[0..63] of Byte; {!< HMAC: inner padding } + Opad: array[0..63] of Byte; {!< HMAC: outer padding } + end; + PCnSM3Context = ^TCnSM3Context; + + TCnSM3CalcProgressFunc = procedure (ATotal, AProgress: Int64; + var Cancel: Boolean) of object; + {* SM3 ӴսȻص¼} + +function SM3(Input: PAnsiChar; ByteLength: Cardinal): TCnSM3Digest; +{* ݿ SM3 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSM3Digest - ص SM3 Ӵֵ + + } + +function SM3Buffer(const Buffer; Count: Cardinal): TCnSM3Digest; +{* ݿ SM3 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3Bytes(Data: TBytes): TCnSM3Digest; +{* ֽ SM3 㡣 + + + Data: TBytes - ֽ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3String(const Str: string): TCnSM3Digest; +{* String ݽ SM3 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3StringA(const Str: AnsiString): TCnSM3Digest; +{* AnsiString ݽ SM3 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3StringW(const Str: WideString): TCnSM3Digest; +{* WideString ַת SM3 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +{$IFDEF UNICODE} + +function SM3UnicodeString(const Str: string): TCnSM3Digest; +{* UnicodeString ݽֱӵ SM3 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +{$ELSE} + +function SM3UnicodeString(const Str: WideString): TCnSM3Digest; +{* UnicodeString ݽֱӵ SM3 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +{$ENDIF} + +function SM3File(const FileName: string; CallBack: TCnSM3CalcProgressFunc = nil): TCnSM3Digest; +{* ָļݽ SM3 㡣 + + + const FileName: string - ļ + CallBack: TCnSM3CalcProgressFunc - ȻصĬΪ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3Stream(Stream: TStream; CallBack: TCnSM3CalcProgressFunc = nil): TCnSM3Digest; +{* ָݽ SM3 㡣 + + + Stream: TStream - + CallBack: TCnSM3CalcProgressFunc - ȻصĬΪ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +// ⲿݽɢ SM3 㣬SM3Update ɶα + +procedure SM3Init(var Context: TCnSM3Context); +{* ʼһ SM3 ģ׼ SM3 + + + var Context: TCnSM3Context - ʼ SM3 + + ֵޣ +} + +procedure SM3Update(var Context: TCnSM3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SM3 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSM3Context - SM3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SM3Final(var Context: TCnSM3Context; var Digest: TCnSM3Digest); +{* ּ㣬 SM3 Digest + + + var Context: TCnSM3Context - SM3 + var Digest: TCnSM3Digest - ص SM3 Ӵֵ + + ֵޣ +} + +function SM3Print(const Digest: TCnSM3Digest): string; +{* ʮƸʽ SM3 Ӵֵ + + + const Digest: TCnSM3Digest - ָ SM3 Ӵֵ + + ֵstring - ʮַ +} + +function SM3Match(const D1: TCnSM3Digest; const D2: TCnSM3Digest): Boolean; +{* Ƚ SM3 ӴֵǷȡ + + + const D1: TCnSM3Digest - Ƚϵ SM3 Ӵֵһ + const D2: TCnSM3Digest - Ƚϵ SM3 Ӵֵ + + ֵBoolean - Ƿ +} + +function SM3DigestToStr(const Digest: TCnSM3Digest): string; +{* SM3 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSM3Digest - ת SM3 Ӵֵ + + ֵstring - صַ +} + +procedure SM3Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSM3Digest); +{* SM3 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SM3 Կݿַ + KeyByteLength: Integer - SM3 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSM3Digest - ص SM3 Ӵֵ + + ֵޣ +} + +implementation + +const + SM3Padding: array[0..63] of Byte = + ( + $80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ); + + SM3_T: array[0..63] of Cardinal = ( + $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, + $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A + ); + + MAX_FILE_SIZE = 512 * 1024 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + HMAC_SM3_BLOCK_SIZE_BYTE = 64; + HMAC_SM3_OUTPUT_LENGTH_BYTE = 32; + +type + TSM3ProcessData = array[0..63] of Byte; + +procedure GetULongBe(var N: Cardinal; B: PAnsiChar; I: Integer); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +var + D: Cardinal; +begin + D := (Cardinal(B[I]) shl 24) or (Cardinal(B[I + 1]) shl 16) or + (Cardinal(B[I + 2]) shl 8) or (Cardinal(B[I + 3])); + N := D; +end; + +procedure PutULongBe(N: Cardinal; B: PAnsiChar; I: Integer); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + B[I] := AnsiChar(N shr 24); + B[I + 1] := AnsiChar(N shr 16); + B[I + 2] := AnsiChar(N shr 8); + B[I + 3] := AnsiChar(N); +end; + +function FF0(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor Y xor Z; +end; + +function FF1(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and Y) or (Y and Z) or (X and Z); +end; + +function GG0(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor Y xor Z; +end; + +function GG1(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and Y) or ((not X) and Z); +end; + +function SM3Shl(X: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and $FFFFFFFF) shl N; +end; + +// ѭơע N Ϊ 0 32 ʱֵΪ XN Ϊ 33 ʱֵ N Ϊ 1 ʱķֵ +function ROTL(X: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := SM3Shl(X, N) or (X shr (32 - N)); +end; + +function P0(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor ROTL(X, 9) xor ROTL(X, 17); +end; + +function P1(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor ROTL(X, 15) xor ROTL(X, 23); +end; + +procedure SM3Init(var Context: TCnSM3Context); +begin + Context.Total[0] := 0; + Context.Total[1] := 0; + + Context.State[0] := $7380166F; + Context.State[1] := $4914B2B9; + Context.State[2] := $172442D7; + Context.State[3] := $DA8A0600; + Context.State[4] := $A96F30BC; + Context.State[5] := $163138AA; + Context.State[6] := $E38DEE4D; + Context.State[7] := $B0FB0E4E; + + FillChar(Context.Buffer, SizeOf(Context.Buffer), 0); +end; + +// һδ 64 ֽҲ 512 λݿ +procedure SM3Process(var Context: TCnSM3Context; Data: PAnsiChar); +var + SS1, SS2, TT1, TT2: Cardinal; + W: array[0..67] of Cardinal; + W1: array[0..63] of Cardinal; + A, B, C, D, E, F, G, H: Cardinal; + Temp1, Temp2: Cardinal; + J: Integer; +begin + GetULongBe(W[ 0], Data, 0); + GetULongBe(W[ 1], Data, 4); + GetULongBe(W[ 2], Data, 8); + GetULongBe(W[ 3], Data, 12); + GetULongBe(W[ 4], Data, 16); + GetULongBe(W[ 5], Data, 20); + GetULongBe(W[ 6], Data, 24); + GetULongBe(W[ 7], Data, 28); + GetULongBe(W[ 8], Data, 32); + GetULongBe(W[ 9], Data, 36); + GetULongBe(W[10], Data, 40); + GetULongBe(W[11], Data, 44); + GetULongBe(W[12], Data, 48); + GetULongBe(W[13], Data, 52); + GetULongBe(W[14], Data, 56); + GetULongBe(W[15], Data, 60); + + for J := 16 to 67 do + begin + Temp1 := W[J - 16] xor W[J - 9]; + Temp2 := ROTL(W[J - 3], 15); + W[J] := P1(Temp1 xor Temp2) xor (ROTL(W[J - 13], 7) xor W[J - 6]); + end; + + for J := 0 to 63 do + W1[J] := W[J] xor W[J + 4]; + + // ѾW/W1ֵ + + A := Context.State[0]; + B := Context.State[1]; + C := Context.State[2]; + D := Context.State[3]; + E := Context.State[4]; + F := Context.State[5]; + G := Context.State[6]; + H := Context.State[7]; + + for J := 0 to 15 do + begin + SS1 := ROTL((ROTL(A, 12) + E + ROTL(SM3_T[J], J)), 7); + SS2 := SS1 xor ROTL(A, 12); + TT1 := FF0(A, B, C) + D + SS2 + W1[J]; + TT2 := GG0(E, F, G) + H + SS1 + W[J]; + D := C; + C := ROTL(B, 9); + B := A; + A := TT1; + H := G; + G := ROTL(F, 19); + F := E; + E := P0(TT2); + end; + + for J := 16 to 63 do + begin + SS1 := ROTL((ROTL(A, 12) + E + ROTL(SM3_T[J], J)), 7); + SS2 := SS1 xor ROTL(A, 12); + TT1 := FF1(A, B, C) + D + SS2 + W1[J]; + TT2 := GG1(E, F, G) + H + SS1 + W[J]; + D := C; + C := ROTL(B,9); + B := A; + A := TT1; + H := G; + G := ROTL(F,19); + F := E; + E := P0(TT2); + end; + + Context.State[0] := Context.State[0] xor A; + Context.State[1] := Context.State[1] xor B; + Context.State[2] := Context.State[2] xor C; + Context.State[3] := Context.State[3] xor D; + Context.State[4] := Context.State[4] xor E; + Context.State[5] := Context.State[5] xor F; + Context.State[6] := Context.State[6] xor G; + Context.State[7] := Context.State[7] xor H; + + // +end; + +procedure SM3UpdateW(var Context: TCnSM3Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + pContent: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(pContent, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(pContent), CharLength * SizeOf(WideChar), nil, nil); + SM3Update(Context, pContent, iLen); + finally + FreeMem(pContent); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SM3Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +procedure SM3Update(var Context: TCnSM3Context; Input: PAnsiChar; ByteLength: Cardinal); +var + Fill, Left: Cardinal; +begin + if (Input = nil) or (ByteLength <= 0) then + Exit; + + Left := Context.Total[0] and $3F; + Fill := 64 - Left; + + Context.Total[0] := Context.Total[0] + ByteLength; + Context.Total[0] := Context.Total[0] and $FFFFFFFF; + + if Context.Total[0] < ByteLength then + Context.Total[1] := Context.Total[1] + 1; + + if (Left <> 0) and (ByteLength >= Fill) then + begin + Move(Input^, Context.Buffer[Left], Fill); + SM3Process(Context, @(Context.Buffer[0])); + Input := Input + Fill; + ByteLength := ByteLength - Fill; + Left := 0; + end; + + while ByteLength >= 64 do + begin + SM3Process(Context, Input); + Input := Input + 64; + ByteLength := ByteLength - 64; + end; + + if ByteLength > 0 then + Move(Input^, Context.Buffer[Left], ByteLength); +end; + +procedure SM3Final(var Context: TCnSM3Context; var Digest: TCnSM3Digest); +var + Last, Padn: Cardinal; + High, Low: Cardinal; + MsgLen: array[0..7] of Byte; +begin + High := (Context.Total[0] shr 29) or (Context.Total[1] shl 3); + Low := Context.Total[0] shl 3; + + PutULongBe(High, @(MsgLen[0]), 0); + PutULongBe(Low, @(MsgLen[0]), 4); + + Last := Context.Total[0] and $3F; + if Last < 56 then + Padn := 56 - Last + else + Padn := 120 - Last; + + SM3Update(Context, @(SM3Padding[0]), Padn); + SM3Update(Context, @(MsgLen[0]), 8); + + PutULongBe(Context.State[0], @Digest, 0); + PutULongBe(Context.State[1], @Digest, 4); + PutULongBe(Context.State[2], @Digest, 8); + PutULongBe(Context.State[3], @Digest, 12); + PutULongBe(Context.State[4], @Digest, 16); + PutULongBe(Context.State[5], @Digest, 20); + PutULongBe(Context.State[6], @Digest, 24); + PutULongBe(Context.State[7], @Digest, 28); +end; + +function SM3(Input: PAnsiChar; ByteLength: Cardinal): TCnSM3Digest; +var + Ctx: TCnSM3Context; +begin + SM3Init(Ctx); + SM3Update(Ctx, Input, ByteLength); + SM3Final(Ctx, Result); +end; + +procedure SM3HmacStarts(var Ctx: TCnSM3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSM3Digest; +begin + if KeyLength > HMAC_SM3_BLOCK_SIZE_BYTE then + begin + Sum := SM3(Key, KeyLength); + KeyLength := HMAC_SM3_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Ctx.Ipad, HMAC_SM3_BLOCK_SIZE_BYTE, $36); + FillChar(Ctx.Opad, HMAC_SM3_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Ctx.Ipad[I] := Byte(Ctx.Ipad[I] xor Byte(Key[I])); + Ctx.Opad[I] := Byte(Ctx.Opad[I] xor Byte(Key[I])); + end; + + SM3Init(Ctx); + SM3Update(Ctx, @(Ctx.Ipad[0]), HMAC_SM3_BLOCK_SIZE_BYTE); +end; + +procedure SM3HmacUpdate(var Ctx: TCnSM3Context; Input: PAnsiChar; Length: Cardinal); +begin + SM3Update(Ctx, Input, Length); +end; + +procedure SM3HmacFinish(var Ctx: TCnSM3Context; var Output: TCnSM3Digest); +var + Len: Integer; + TmpBuf: TCnSM3Digest; +begin + Len := HMAC_SM3_OUTPUT_LENGTH_BYTE; + SM3Final(Ctx, TmpBuf); + SM3Init(Ctx); + SM3Update(Ctx, @(Ctx.Opad[0]), HMAC_SM3_BLOCK_SIZE_BYTE); + SM3Update(Ctx, @(TmpBuf[0]), Len); + SM3Final(Ctx, Output); +end; + +procedure SM3Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSM3Digest); +var + Ctx: TCnSM3Context; +begin + SM3HmacStarts(Ctx, Key, KeyByteLength); + SM3HmacUpdate(Ctx, Input, ByteLength); + SM3HmacFinish(Ctx, Output); +end; + +function SM3Buffer(const Buffer; Count: Cardinal): TCnSM3Digest; +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3Update(Context, PAnsiChar(Buffer), Count); + SM3Final(Context, Result); +end; + +function SM3Bytes(Data: TBytes): TCnSM3Digest; +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SM3Final(Context, Result); +end; + +// String ݽ SM3 ת +function SM3String(const Str: string): TCnSM3Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SM3StringA(AStr); +end; + +// AnsiString ݽ SM3 ת +function SM3StringA(const Str: AnsiString): TCnSM3Digest; +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3Update(Context, PAnsiChar(Str), Length(Str)); + SM3Final(Context, Result); +end; + +// WideString ݽ SM3 ת +function SM3StringW(const Str: WideString): TCnSM3Digest; +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3UpdateW(Context, PWideChar(Str), Length(Str)); + SM3Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SM3 㣬ת +{$IFDEF UNICODE} +function SM3UnicodeString(const Str: string): TCnSM3Digest; +{$ELSE} +function SM3UnicodeString(const Str: WideString): TCnSM3Digest; +{$ENDIF} +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SM3Final(Context, Result); +end; + +function InternalSM3Stream(Stream: TStream; const BufSize: Cardinal; var D: + TCnSM3Digest; CallBack: TCnSM3CalcProgressFunc = nil): Boolean; +var + Context: TCnSM3Context; + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then Exit; + if Size < BufSize then BufLen := Size + else BufLen := BufSize; + + CancelCalc := False; + SM3Init(Context); + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + SM3Update(Context, Buf, ReadBytes); + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + SM3Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ָļݽSM3ת +function SM3File(const FileName: string; + CallBack: TCnSM3CalcProgressFunc): TCnSM3Digest; +var +{$IFDEF MSWINDOWS} + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; + Context: TCnSM3Context; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; + + function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} + var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec : Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then Exit; + try + if not GetFileInformationByHandle(H, Info) then Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} + end; + +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSM3Stream(Stream, 4096 * 1024, Result, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + SM3Init(Context); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + SM3Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + SM3Final(Context, Result); +{$ENDIF} + end; +end; + +// ָ SM3 +function SM3Stream(Stream: TStream; + CallBack: TCnSM3CalcProgressFunc = nil): TCnSM3Digest; +begin + InternalSM3Stream(Stream, 4096 * 1024, Result, CallBack); +end; + +function SM3Print(const Digest: TCnSM3Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSM3Digest)); +end; + +function SM3Match(const D1, D2: TCnSM3Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSM3Digest)); +end; + +function SM3DigestToStr(const Digest: TCnSM3Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSM3Digest)); +end; + +end. From 8266f5e634591f8246dc91119b73e3d2a6f092f3 Mon Sep 17 00:00:00 2001 From: freitasjca Date: Sat, 14 Mar 2026 11:06:01 +0000 Subject: [PATCH 05/10] Remove tracked .dcu files and add to .gitignore --- .gitignore | 63 +++++++++++++++++++++++++++++++++++ CnPack/Crypto/CnAES.dcu | Bin 122925 -> 0 bytes CnPack/Crypto/CnBase64.dcu | Bin 7426 -> 0 bytes CnPack/Crypto/CnConsts.dcu | Bin 14305 -> 0 bytes CnPack/Crypto/CnDES.dcu | Bin 30941 -> 0 bytes CnPack/Crypto/CnFloat.dcu | Bin 15913 -> 0 bytes CnPack/Crypto/CnKDF.dcu | Bin 13854 -> 0 bytes CnPack/Crypto/CnMD5.dcu | Bin 15598 -> 0 bytes CnPack/Crypto/CnNative.dcu | Bin 48972 -> 0 bytes CnPack/Crypto/CnPemUtils.dcu | Bin 16968 -> 0 bytes CnPack/Crypto/CnRandom.dcu | Bin 5673 -> 0 bytes CnPack/Crypto/CnSHA1.dcu | Bin 10859 -> 0 bytes CnPack/Crypto/CnSHA2.dcu | Bin 30907 -> 0 bytes CnPack/Crypto/CnSHA3.dcu | Bin 31943 -> 0 bytes CnPack/Crypto/CnSM3.dcu | Bin 14942 -> 0 bytes 15 files changed, 63 insertions(+) create mode 100644 .gitignore delete mode 100644 CnPack/Crypto/CnAES.dcu delete mode 100644 CnPack/Crypto/CnBase64.dcu delete mode 100644 CnPack/Crypto/CnConsts.dcu delete mode 100644 CnPack/Crypto/CnDES.dcu delete mode 100644 CnPack/Crypto/CnFloat.dcu delete mode 100644 CnPack/Crypto/CnKDF.dcu delete mode 100644 CnPack/Crypto/CnMD5.dcu delete mode 100644 CnPack/Crypto/CnNative.dcu delete mode 100644 CnPack/Crypto/CnPemUtils.dcu delete mode 100644 CnPack/Crypto/CnRandom.dcu delete mode 100644 CnPack/Crypto/CnSHA1.dcu delete mode 100644 CnPack/Crypto/CnSHA2.dcu delete mode 100644 CnPack/Crypto/CnSHA3.dcu delete mode 100644 CnPack/Crypto/CnSM3.dcu diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8454266 --- /dev/null +++ b/.gitignore @@ -0,0 +1,63 @@ +modules/ +dist/ +static/ +**/Win32/ +**/Win64/ +**/Linux64/ +**/__history/ +**/__recovery/ +src/*.~* +__history/ +__recovery/ +packages/Win32/ +packages/Win64/ +packages/Linux64/ +packages/dcu/ +packages/dcp/ +packages/bpl/ +*.res +*.exe +*.dll +*.bpl +*.bpi +*.dcp +*.bpl +*.so +*.apk +*.drc +*.map +*.dres +*.rsm +*.tds +*.dcu +*.lib +*.a +*.o +*.ocx +*.local +*.identcache +*.projdata +*.tvsconfig +*.dsk +*.dcu +*.exe +*.ico +*.so +*.~* +*.a +*.stat +*.skincfg + +# Mac +*.DS_Store + +#FPC/Laz +lib/ +backup/ +*.lps + +# Code coverage reports +**/console/ +**/vcl/ +dunitx-results.xml +*.bak diff --git a/CnPack/Crypto/CnAES.dcu b/CnPack/Crypto/CnAES.dcu deleted file mode 100644 index ebc666a410074a233b156bd06d693c171451fb02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122925 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 U5XKli4!pF diff --git a/CnPack/Crypto/CnConsts.dcu b/CnPack/Crypto/CnConsts.dcu deleted file mode 100644 index c867ed279f4c00fe26ff633e118584d938e5bedb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14305 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 e3USNw2)Y>N%(KXha^|S(k2<+r=u|5s diff --git a/CnPack/Crypto/CnDES.dcu b/CnPack/Crypto/CnDES.dcu deleted file mode 100644 index 86e855f0e249b9d709daafffd26601b8f2c8b4ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30941 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

NA(3P9!?JiueiT3|zuV96ev0!$^2X$c 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 IRjl;?0`Q@bKL7v# diff --git a/CnPack/Crypto/CnSM3.dcu b/CnPack/Crypto/CnSM3.dcu deleted file mode 100644 index 5702308fecc90851e7e1705244d10cf62f426a3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14942 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 hoP3Lj*(N*248(j>HZvNH_!X!X Date: Mon, 6 Apr 2026 12:45:18 +0100 Subject: [PATCH 06/10] After reviewing --- .gitignore | 18 +++++ Net/Net.CrossSslSocket.OpenSSL.pas | 109 +++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/.gitignore b/.gitignore index 8454266..344952c 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,21 @@ backup/ **/vcl/ dunitx-results.xml *.bak + +# Claude Code +.claude/settings.local.json +.claude.json +CLAUDE.md + +# Delphi build output +__history/ +__recovery/ +*.dcu +*.exe +*.dll +*.bpl +*.dcp +*.local +*.identcache +*.tvsconfig +*.dsk diff --git a/Net/Net.CrossSslSocket.OpenSSL.pas b/Net/Net.CrossSslSocket.OpenSSL.pas index 01b8723..76af7b8 100644 --- a/Net/Net.CrossSslSocket.OpenSSL.pas +++ b/Net/Net.CrossSslSocket.OpenSSL.pas @@ -19,6 +19,23 @@ 传输层安全协议: https://zh.wikipedia.org/wiki/%E5%82%B3%E8%BC%B8%E5%B1%A4%E5%AE%89%E5%85%A8%E5%8D%94%E8%AD%B0 + + ── mTLS patch ──────────────────────────────────────────────────────────────── + [MTLS-1] SetCACertificate(Pointer, Integer) override added. + Loads a CA certificate from a memory buffer and registers it with + the SSL context for client-certificate verification (mTLS server + mode). Uses BIO_new_mem_buf + PEM_read_bio_X509 to parse the PEM + data, then calls SSL_CTX_add_client_CA (populates the list sent to + clients in the CertificateRequest handshake message) and + X509_STORE_add_cert (adds the cert to the trust store used to + verify the presented certificate chain). + + [MTLS-2] SetVerifyPeer(Boolean) override added. + When AVerify=True, sets SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT + so the server demands a valid client certificate. + When AVerify=False, reverts to SSL_VERIFY_NONE (default). + Must be called AFTER SetCACertificate — the trust store must be + populated before verify mode is enabled. } interface @@ -118,6 +135,18 @@ TCrossOpenSslSocket = class(TCrossSslSocketBase) procedure SetCertificate(const ACertBuf: Pointer; const ACertBufSize: Integer); overload; override; procedure SetPrivateKey(const APKeyBuf: Pointer; const APKeyBufSize: Integer); overload; override; + + // [MTLS-1] Load a CA certificate (PEM, in memory) into the SSL context. + // Registers it with SSL_CTX_add_client_CA (sent to clients in + // CertificateRequest) and X509_STORE_add_cert (trust store for + // chain verification). Call before SetVerifyPeer. + procedure SetCACertificate(const ACACertBuf: Pointer; const ACACertBufSize: Integer); overload; override; + + // [MTLS-2] Enable or disable client-certificate verification. + // AVerify=True → SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT + // AVerify=False → SSL_VERIFY_NONE + // Call AFTER SetCACertificate so the trust store is populated first. + procedure SetVerifyPeer(const AVerify: Boolean); override; end; implementation @@ -623,6 +652,86 @@ procedure TCrossOpenSslSocket.SetPrivateKey(const APKeyBuf: Pointer; TSSLTools.SetPrivateKey(FSslCtx, APKeyBuf, APKeyBufSize); end; +// [MTLS-1] Load a CA certificate (PEM buffer) into the SSL context. +// +// Registers the certificate via two OpenSSL calls: +// SSL_CTX_add_client_CA — adds the CA's distinguished name to the list +// that the server sends to clients in the TLS CertificateRequest message, +// guiding the client to select the right certificate. +// X509_STORE_add_cert — adds the CA cert to the trust store used by +// OpenSSL when verifying the client's certificate chain during handshake. +// +// Both calls are required for correct mTLS server behaviour. Without +// SSL_CTX_add_client_CA the client may not send a certificate at all. +// Without X509_STORE_add_cert the chain verification will always fail. +// +// The X509 object is reference-counted by OpenSSL: both callers (add_client_CA +// and add_cert) increment the ref-count internally, so X509_free here is +// correct — it decrements our local reference without affecting the copies +// held by the context and the store. +procedure TCrossOpenSslSocket.SetCACertificate(const ACACertBuf: Pointer; + const ACACertBufSize: Integer); +var + LBio: PBIO; + LCACert: PX509; + LStore: PX509_STORE; +begin + if not Ssl or (FSslCtx = nil) then Exit; + + // Wrap the caller's buffer in a read-only memory BIO — no copy is made. + LBio := BIO_new_mem_buf(ACACertBuf, ACACertBufSize); + if LBio = nil then + raise ESsl.Create('SetCACertificate: BIO_new_mem_buf failed'); + try + // Parse the PEM-encoded X.509 certificate. + LCACert := PEM_read_bio_X509(LBio, nil, nil, nil); + if LCACert = nil then + raise ESsl.Create( + 'SetCACertificate: PEM_read_bio_X509 failed — ' + + 'ensure the buffer contains a valid PEM certificate'); + try + // Register the CA name in the CertificateRequest list. + SSL_CTX_add_client_CA(FSslCtx, LCACert); + + // Add the cert to the trust store for chain verification. + LStore := SSL_CTX_get_cert_store(FSslCtx); + if Assigned(LStore) then + X509_STORE_add_cert(LStore, LCACert); + // X509_STORE_add_cert returns 0 if the cert is already in the store + // (duplicate) — this is benign, so we do not raise on <= 0 here. + finally + // Decrement our local ref-count. The context and store hold their own. + X509_free(LCACert); + end; + finally + BIO_free(LBio); + end; +end; + +// [MTLS-2] Enable or disable mandatory client-certificate verification. +// +// AVerify = True: +// SSL_VERIFY_PEER — request a client certificate during handshake. +// SSL_VERIFY_FAIL_IF_NO_PEER_CERT — abort the handshake if the client does +// not present one (or if it is invalid). +// +// AVerify = False: +// SSL_VERIFY_NONE — client certificate is never requested (default). +// +// IMPORTANT: call SetCACertificate before SetVerifyPeer(True). Without a +// CA certificate in the trust store, every client certificate will be +// rejected, making the server unreachable. +procedure TCrossOpenSslSocket.SetVerifyPeer(const AVerify: Boolean); +begin + if not Ssl or (FSslCtx = nil) then Exit; + + if AVerify then + SSL_CTX_set_verify(FSslCtx, + SSL_VERIFY_PEER or SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nil) + else + SSL_CTX_set_verify(FSslCtx, SSL_VERIFY_NONE, nil); +end; + procedure TCrossOpenSslSocket.TriggerConnected(const AConnection: ICrossConnection); var LConnection: TCrossOpenSslConnection; From 5f448b8b94bba85a3da00cd363f17f0a45692a4d Mon Sep 17 00:00:00 2001 From: freitasjca Date: Thu, 9 Apr 2026 16:40:21 +0100 Subject: [PATCH 07/10] Source with running tests --- Net/Demos/Delphi/HttpClient/HttpClient.dproj | 36 +- Net/Demos/Delphi/HttpClient/HttpClient.dsv | 11 + Net/Demos/Delphi/HttpServer/HttpServer.dpr | 54 +- Net/Demos/Delphi/HttpServer/HttpServer.dproj | 959 +++++++++- Net/Demos/Delphi/HttpServer/HttpServer.dsv | 110 ++ Net/Demos/Delphi/HttpServer/HttpServer.res | Bin 109940 -> 152412 bytes Net/Net.CrossSocket.Iocp.pas | 1691 +++++++++--------- 7 files changed, 1953 insertions(+), 908 deletions(-) create mode 100644 Net/Demos/Delphi/HttpClient/HttpClient.dsv create mode 100644 Net/Demos/Delphi/HttpServer/HttpServer.dsv diff --git a/Net/Demos/Delphi/HttpClient/HttpClient.dproj b/Net/Demos/Delphi/HttpClient/HttpClient.dproj index e13e632..3278f4d 100644 --- a/Net/Demos/Delphi/HttpClient/HttpClient.dproj +++ b/Net/Demos/Delphi/HttpClient/HttpClient.dproj @@ -4,11 +4,12 @@ HttpClient.dpr True Release - 693379 + 168067 Console None 20.3 - Linux64 + Win64 + HttpClient true @@ -23,11 +24,6 @@ Base true - - true - Base - true - true Base @@ -49,8 +45,8 @@ true true - - true + + true Cfg_1 true true @@ -90,12 +86,6 @@ true true - - true - Cfg_2 - true - true - true Cfg_2 @@ -134,7 +124,7 @@ $(BDS)\bin\delphi_PROJECTICON.ico $(BDS)\bin\delphi_PROJECTICNS.icns bin\$(Platform)\ - ..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC;$(DCC_UnitSearchPath) + ..\..\..\..\;..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC;..\..\..\..\CnPack\Crypto;..\..\..\..\CnPack\Common;$(DCC_UnitSearchPath) .\$(Platform)\$(Config) @@ -171,9 +161,6 @@ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - - $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) Debug @@ -195,8 +182,10 @@ Debug - - Debug + + /usr/bin/gnome-terminal -- "%debuggee%" + (None) + none Debug @@ -226,9 +215,6 @@ Debug - - Debug - Debug @@ -286,8 +272,6 @@ False True - True - True True True True diff --git a/Net/Demos/Delphi/HttpClient/HttpClient.dsv b/Net/Demos/Delphi/HttpClient/HttpClient.dsv new file mode 100644 index 0000000..cf3b866 --- /dev/null +++ b/Net/Demos/Delphi/HttpClient/HttpClient.dsv @@ -0,0 +1,11 @@ +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwQ2xp +ZW50XEh0dHBDbGllbnQuZHBy] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpClient\HttpClient.dpr +CursorX=1 +CursorY=1 +TopLine=109 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpClient\HttpClient.dpr + diff --git a/Net/Demos/Delphi/HttpServer/HttpServer.dpr b/Net/Demos/Delphi/HttpServer/HttpServer.dpr index 6382b01..7ef2a9d 100644 --- a/Net/Demos/Delphi/HttpServer/HttpServer.dpr +++ b/Net/Demos/Delphi/HttpServer/HttpServer.dpr @@ -5,15 +5,35 @@ program HttpServer; {$I zLib.inc} uses - SysUtils - ,Classes - ,Net.CrossSocket.Base - ,Net.CrossHttpServer - ,Net.CrossHttpParams - ,Net.OpenSSL - ,Utils.Utils - ,Utils.Hash - ; + SysUtils, + Classes, + Net.CrossSocket.Base in '..\..\..\Net.CrossSocket.Base.pas', + Net.CrossHttpServer in '..\..\..\Net.CrossHttpServer.pas', + Net.CrossHttpParams in '..\..\..\Net.CrossHttpParams.pas', + Net.OpenSSL in '..\..\..\Net.OpenSSL.pas', + Utils.Utils in '..\..\..\..\Utils\Utils.Utils.pas', + Utils.Hash in '..\..\..\..\Utils\Utils.Hash.pas', + DTF.Hash in '..\..\..\..\DelphiToFPC\DTF.Hash.pas', + CnAES in '..\..\..\..\CnPack\Crypto\CnAES.pas', + CnBase64 in '..\..\..\..\CnPack\Crypto\CnBase64.pas', + CnConsts in '..\..\..\..\CnPack\Crypto\CnConsts.pas', + CnDES in '..\..\..\..\CnPack\Crypto\CnDES.pas', + CnFloat in '..\..\..\..\CnPack\Crypto\CnFloat.pas', + CnKDF in '..\..\..\..\CnPack\Crypto\CnKDF.pas', + CnMD5 in '..\..\..\..\CnPack\Crypto\CnMD5.pas', + CnNative in '..\..\..\..\CnPack\Crypto\CnNative.pas', + CnPemUtils in '..\..\..\..\CnPack\Crypto\CnPemUtils.pas', + CnRandom in '..\..\..\..\CnPack\Crypto\CnRandom.pas', + CnSHA1 in '..\..\..\..\CnPack\Crypto\CnSHA1.pas', + CnSHA2 in '..\..\..\..\CnPack\Crypto\CnSHA2.pas', + CnSHA3 in '..\..\..\..\CnPack\Crypto\CnSHA3.pas', + CnSM3 in '..\..\..\..\CnPack\Crypto\CnSM3.pas', + Net.CrossHttpParser in '..\..\..\Net.CrossHttpParser.pas', + Net.CrossHttpRouter in '..\..\..\Net.CrossHttpRouter.pas', + Net.CrossHttpRouterDirUtils in '..\..\..\Net.CrossHttpRouterDirUtils.pas', + Utils.AnonymousThread in '..\..\..\..\Utils\Utils.AnonymousThread.pas', + Utils.ArrayUtils in '..\..\..\..\Utils\Utils.ArrayUtils.pas', + Utils.DateTime in '..\..\..\..\Utils\Utils.DateTime.pas'; var __HttpServer: ICrossHttpServer; @@ -24,14 +44,15 @@ var begin LResponseStr := TOSVersion.ToString + '
Hello World!'; - __HttpServer := TCrossHttpServer.Create(0, True); + //__HttpServer := TCrossHttpServer.Create(0, True); + __HttpServer := TCrossHttpServer.Create(0, False); if __HttpServer.Ssl then begin __HttpServer.SetCertificateFile('server.crt'); __HttpServer.SetPrivateKeyFile('server.key'); end; - __HttpServer.Port := 8080; + __HttpServer.Port := 9010; __HttpServer.Start( procedure(const AListen: ICrossListen; const ASuccess: Boolean) begin @@ -51,6 +72,13 @@ begin AHandled := True; end); + __HttpServer.Get('/ping', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) + begin + AResponse.Send('pong'); + AHandled := True; + end); + __HttpServer.Post('/upload', procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) var @@ -68,8 +96,8 @@ begin LHashStr := LHashStr + sLineBreak; LHashStr := LHashStr + 'FileName: ' + LFormField.FileName + sLineBreak; - LHashStr := LHashStr + 'MD5: ' + THashMD5.GetHashString(LFormField.Value) + sLineBreak; - LHashStr := LHashStr + 'SHA1: ' + THashSHA1.GetHashString(LFormField.Value) + sLineBreak; + LHashStr := LHashStr + 'MD5: ' + THashMD5.GetHashStringFromStream(LFormField.Value) + sLineBreak; + LHashStr := LHashStr + 'SHA1: ' + THashSHA1.GetHashStringFromStream(LFormField.Value) + sLineBreak; end; end; end; diff --git a/Net/Demos/Delphi/HttpServer/HttpServer.dproj b/Net/Demos/Delphi/HttpServer/HttpServer.dproj index 1bdc2de..b4d5d26 100644 --- a/Net/Demos/Delphi/HttpServer/HttpServer.dproj +++ b/Net/Demos/Delphi/HttpServer/HttpServer.dproj @@ -3,12 +3,13 @@ {901CE442-716D-460E-8B45-0B7F08772F0D} HttpServer.dpr True - Release - 693379 + Debug + 168067 Console None - 19.5 + 20.2 Win64 + HttpServer
true @@ -23,11 +24,6 @@ Base true - - true - Base - true - true Base @@ -43,6 +39,24 @@ Base true + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + true Cfg_1 @@ -60,12 +74,6 @@ true true - - true - Cfg_2 - true - true - true Cfg_2 @@ -98,7 +106,7 @@ $(BDS)\bin\delphi_PROJECTICON.ico $(BDS)\bin\delphi_PROJECTICNS.icns bin\$(Platform)\ - ..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC;$(DCC_UnitSearchPath) + ..\..\..\..\;..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC;..\..\..\..\CnPack\Crypto;..\..\..\..\CnPack\Common;$(DCC_UnitSearchPath) package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= @@ -134,9 +142,6 @@ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - - $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) Debug @@ -155,6 +160,15 @@ false 0 + + Debug + + + Debug + + + Debug + 1033 CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= @@ -171,9 +185,6 @@ Debug - - Debug - Debug @@ -190,6 +201,33 @@ MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + Base @@ -211,30 +249,889 @@ HttpServer.dpr - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\CEF4Delphi_FMX.bpl not found - File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\AutoUpgraderProXE10.bpl not found - File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\KastriFMX280.bpl not found - File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\CEF4Delphi.bpl not found + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components False True - True - True True True True True True + + + + true + + + + + true + + + + + true + + + + + HttpServer.exe + true + + + + + 1 + + + 0 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + + + + + + + + + + + 12 + diff --git a/Net/Demos/Delphi/HttpServer/HttpServer.dsv b/Net/Demos/Delphi/HttpServer/HttpServer.dsv new file mode 100644 index 0000000..4f36088 --- /dev/null +++ b/Net/Demos/Delphi/HttpServer/HttpServer.dsv @@ -0,0 +1,110 @@ +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcVXRpbHNcVXRpbHMuSGFzaC5wYXM=] +Module=C:\lang\Repo\Delphi-Cross-Socket\Utils\Utils.Hash.pas +CursorX=31 +CursorY=159 +TopLine=143 +LeftCol=1 +Elisions={{63,4},{88,15},{'核心hash方法'}} +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Utils\Utils.Hash.pas +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwU2Vy +dmVyXEh0dHBTZXJ2ZXIuZHBy] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +CursorX=85 +CursorY=71 +TopLine=54 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwU2Vy +dmVyXEh0dHBTZXJ2ZXIuZHBy] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +CursorX=65 +CursorY=75 +TopLine=27 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwU2Vy +dmVyXEh0dHBTZXJ2ZXIuZHBy] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +CursorX=63 +CursorY=29 +TopLine=10 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwU2Vy +dmVyXEh0dHBTZXJ2ZXIuZHBy] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +CursorX=1 +CursorY=69 +TopLine=51 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc0h0dHBTZXJ2ZXIu +cGFz] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas +CursorX=1 +CursorY=3617 +TopLine=3597 +LeftCol=1 +Elisions={{1635,4},{1649,15},{'HttpParser事件'}}{{1823,4},{1826,15},{'内部: 基础发送方法'}}{{1830,4},{1839,15},{'压缩发送'}}{{1841,4},{1850,15},{'不压缩发送'}}{{1852,4},{1871,15},{'常规方法'}}{{2296,2},{2317,13},{'创建Body'}}{{3312,4},{3323,15},{'Session'}}{{3328,4},{3341,15},{'中间件'}}{{3359,4},{3368,15},{'响应请求事件'}} +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc0h0dHBQYXJzZXIu +cGFz] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpParser.pas +CursorX=43 +CursorY=62 +TopLine=42 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpParser.pas +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc0h0dHBTZXJ2ZXIu +cGFz] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas +CursorX=1 +CursorY=3620 +TopLine=3600 +LeftCol=1 +Elisions={{1635,4},{1649,15},{'HttpParser事件'}}{{1823,4},{1826,15},{'内部: 基础发送方法'}}{{1830,4},{1839,15},{'压缩发送'}}{{1841,4},{1850,15},{'不压缩发送'}}{{1852,4},{1871,15},{'常规方法'}}{{2296,2},{2317,13},{'创建Body'}}{{3312,4},{3323,15},{'Session'}}{{3328,4},{3341,15},{'中间件'}}{{3359,4},{3368,15},{'响应请求事件'}} +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas +[ClosedView_QzpcbGFuZ1xSZXBvXGhvcnNlLXByb3ZpZGVyLWNyb3Nzc29ja2V0XHNyY1xIb3JzZS5Qcm92aWRl +ci5Dcm9zc1NvY2tldC5SZXNwb25zZS5wYXM=] +Module=C:\lang\Repo\horse-provider-crosssocket\src\Horse.Provider.CrossSocket.Response.pas +CursorX=1 +CursorY=256 +TopLine=236 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\horse-provider-crosssocket\src\Horse.Provider.CrossSocket.Response.pas +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc0h0dHBTZXJ2ZXIu +cGFz] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas +CursorX=1 +CursorY=4600 +TopLine=4580 +LeftCol=1 +Elisions={{1635,4},{1649,15},{'HttpParser事件'}}{{1823,4},{1826,15},{'内部: 基础发送方法'}}{{1830,4},{1839,15},{'压缩发送'}}{{1841,4},{1850,15},{'不压缩发送'}}{{1852,4},{1871,15},{'常规方法'}}{{2296,2},{2317,13},{'创建Body'}}{{3359,4},{3368,15},{'响应请求事件'}} +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc1NvY2tldC5CYXNl +LnBhcw==] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossSocket.Base.pas +CursorX=1 +CursorY=1682 +TopLine=1664 +LeftCol=1 +Elisions={{816,4},{826,15},{'物理事件'}}{{828,4},{838,15},{'逻辑事件'}}{{1533,2},{1539,13},{'本地地址信息'}}{{1911,2},{1916,13},{'远端地址信息'}} +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossSocket.Base.pas + diff --git a/Net/Demos/Delphi/HttpServer/HttpServer.res b/Net/Demos/Delphi/HttpServer/HttpServer.res index f319bd8c09e7c0f4d14bbc6df8daf7655db98f89..ed2255311f5e3782fa37fc37d297a9dc22333f36 100644 GIT binary patch literal 152412 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 literal 109940 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
8{ANffi>JY8gRp~PmZm^D|e2D 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 diff --git a/Net/Net.CrossSocket.Iocp.pas b/Net/Net.CrossSocket.Iocp.pas index 1711fdc..07bdb32 100644 --- a/Net/Net.CrossSocket.Iocp.pas +++ b/Net/Net.CrossSocket.Iocp.pas @@ -1,838 +1,853 @@ -{******************************************************************************} -{ } -{ Delphi cross platform socket library } -{ } -{ Copyright (c) 2017 WiNDDRiVER(soulawing@gmail.com) } -{ } -{ Homepage: https://github.com/winddriver/Delphi-Cross-Socket } -{ } -{******************************************************************************} -unit Net.CrossSocket.Iocp; - -{$I zLib.inc} - -interface - -uses - SysUtils, - Classes, - Windows, - - Net.Winsock2, - Net.Wship6, - Net.SocketAPI, - Net.CrossSocket.Base; - -type - TIocpListen = class(TCrossListenBase) - end; - - TIocpConnection = class(TCrossConnectionBase) - end; - - TIocpCrossSocket = class(TCrossSocketBase) - private const - SHUTDOWN_FLAG = ULONG_PTR(-1); - SO_UPDATE_CONNECT_CONTEXT = $7010; - IPV6_V6ONLY = 27; - ERROR_ABANDONED_WAIT_0 = $02DF; - private type - TAddrUnion = record - case Integer of - 0: (IPv4: TSockAddrIn); - 1: (IPv6: TSockAddrIn6); - end; - - TAddrBuffer = record - Addr: TAddrUnion; - Extra: array [0..15] of Byte; - end; - - TAcceptExBuffer = array[0..SizeOf(TAddrBuffer) * 2 - 1] of Byte; - - TPerIoBufUnion = record - case Integer of - 0: (DataBuf: WSABUF); - // 这个Buffer只用于AcceptEx保存终端地址数据,大小为2倍地址结构 - 1: (AcceptExBuffer: TAcceptExBuffer); - end; - - TIocpAction = (ioAccept, ioConnect, ioRead, ioWrite); - - PPerIoData = ^TPerIoData; - TPerIoData = record - Overlapped: TWSAOverlapped; - Buffer: TPerIoBufUnion; - Action: TIocpAction; - Socket: TSocket; - CrossData: ICrossData; - Callback: TCrossConnectionCallback; - end; - private - FIocpHandle: THandle; - FIoThreads: TArray; - FPerIoDataCount: NativeInt; - - function _NewIoData: PPerIoData; inline; - procedure _FreeIoData(const P: PPerIoData); inline; - - procedure _NewAccept(const AListen: ICrossListen); - function _NewReadZero(const AConnection: ICrossConnection): Boolean; - - procedure _HandleAccept(const APerIoData: PPerIoData); - procedure _HandleConnect(const APerIoData: PPerIoData); - procedure _HandleRead(const APerIoData: PPerIoData); - procedure _HandleWrite(const APerIoData: PPerIoData); - protected - function CreateListen(const AOwner: TCrossSocketBase; const AListenSocket: TSocket; - const AFamily, ASockType, AProtocol: Integer): ICrossListen; override; - function CreateConnection(const AOwner: TCrossSocketBase; const AClientSocket: TSocket; - const AConnectType: TConnectType; const AHost: string; - const AConnectCb: TCrossConnectionCallback): ICrossConnection; override; - - procedure StartLoop; override; - procedure StopLoop; override; - - procedure Listen(const AHost: string; const APort: Word; - const ACallback: TCrossListenCallback = nil); override; - - procedure Connect(const AHost: string; const APort, ALocalPort: Word; - const ACallback: TCrossConnectionCallback = nil); override; - - procedure Send(const AConnection: ICrossConnection; const ABuf: Pointer; - const ALen: Integer; const ACallback: TCrossConnectionCallback = nil); override; - - function ProcessIoEvent: Boolean; override; - end; - -implementation - -{ TIocpCrossSocket } - -function TIocpCrossSocket._NewIoData: PPerIoData; -begin - GetMem(Result, SizeOf(TPerIoData)); - FillChar(Result^, SizeOf(TPerIoData), 0); - - AtomicIncrement(FPerIoDataCount); -end; - -procedure TIocpCrossSocket._FreeIoData(const P: PPerIoData); -begin - if (P = nil) then Exit; - - P.CrossData := nil; - P.Callback := nil; - FreeMem(P, SizeOf(TPerIoData)); - - AtomicDecrement(FPerIoDataCount); -end; - -procedure TIocpCrossSocket._NewAccept(const AListen: ICrossListen); -var - LClientSocket: TSocket; - LPerIoData: PPerIoData; - LBytes: Cardinal; -begin - LClientSocket := WSASocket(AListen.Family, AListen.SockType, AListen.Protocol, - nil, 0, WSA_FLAG_OVERLAPPED); - if (LClientSocket = INVALID_SOCKET) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket._NewAccept.WSASocket, %s', [AListen.DebugInfo]); - {$ENDIF} - Exit; - end; - - TSocketAPI.SetNonBlock(LClientSocket, True); - SetKeepAlive(LClientSocket); - - LPerIoData := _NewIoData; - LPerIoData.Action := ioAccept; - LPerIoData.Socket := LClientSocket; - LPerIoData.CrossData := AListen; - - if (not AcceptEx(AListen.Socket, LClientSocket, @LPerIoData.Buffer.AcceptExBuffer, 0, - SizeOf(TAddrBuffer), SizeOf(TAddrBuffer), LBytes, POverlapped(LPerIoData))) - and (WSAGetLastError <> WSA_IO_PENDING) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket._NewAccept.AcceptEx, %s', [AListen.DebugInfo]); - {$ENDIF} - TSocketAPI.CloseSocket(LClientSocket); - _FreeIoData(LPerIoData); - end; -end; - -function TIocpCrossSocket._NewReadZero(const AConnection: ICrossConnection): Boolean; -var - LPerIoData: PPerIoData; - LBytes, LFlags: Cardinal; -begin - LPerIoData := _NewIoData; - LPerIoData.Buffer.DataBuf.buf := nil; - LPerIoData.Buffer.DataBuf.len := 0; - LPerIoData.Action := ioRead; - LPerIoData.Socket := AConnection.Socket; - LPerIoData.CrossData := AConnection; - - LFlags := 0; - LBytes := 0; - if (WSARecv(AConnection.Socket, @LPerIoData.Buffer.DataBuf, 1, LBytes, LFlags, PWSAOverlapped(LPerIoData), nil) < 0) - and (WSAGetLastError <> WSA_IO_PENDING) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket._NewReadZero.WSARecv, %s', [AConnection.DebugInfo]); - {$ENDIF} - _FreeIoData(LPerIoData); - Exit(False); - end; - - Result := True; -end; - -procedure TIocpCrossSocket._HandleAccept(const APerIoData: PPerIoData); -var - LListen: ICrossListen; - LConnection: ICrossConnection; - LClientSocket, LListenSocket: TSocket; -begin - if (APerIoData.CrossData = nil) then Exit; - - LListen := APerIoData.CrossData as ICrossListen; - - _NewAccept(LListen); - - LClientSocket := APerIoData.Socket; - LListenSocket := LListen.Socket; - - // 不设置该参数, 会导致 getpeername 调用失败 - if (TSocketAPI.SetSockOpt(LClientSocket, SOL_SOCKET, - SO_UPDATE_ACCEPT_CONTEXT, LListenSocket) < 0) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket._HandleAccept.SetSockOpt'); - {$ENDIF} - TSocketAPI.CloseSocket(LClientSocket); - Exit; - end; - - if (CreateIoCompletionPort(LClientSocket, FIocpHandle, ULONG_PTR(LClientSocket), 0) = 0) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket._HandleAccept.CreateIoCompletionPort'); - {$ENDIF} - TSocketAPI.CloseSocket(LClientSocket); - Exit; - end; - - LConnection := CreateConnection(Self, LClientSocket, ctAccept, ''); - TriggerConnecting(LConnection); - TriggerConnected(LConnection); - - if not _NewReadZero(LConnection) then - LConnection.Close; -end; - -procedure TIocpCrossSocket._HandleConnect(const APerIoData: PPerIoData); -var - LClientSocket: TSocket; - LConnection: ICrossConnection; - - procedure _Failed1; - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket._HandleConnect'); - {$ENDIF} - - if Assigned(APerIoData.Callback) then - APerIoData.Callback(nil, False); - - TSocketAPI.CloseSocket(LClientSocket); - end; -begin - LClientSocket := APerIoData.Socket; - - if (TSocketAPI.GetError(LClientSocket) <> 0) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket._HandleConnect.GetError'); - {$ENDIF} - _Failed1; - Exit; - end; - - // 不设置该参数, 会导致 getpeername 调用失败 - if (TSocketAPI.SetSockOpt(LClientSocket, SOL_SOCKET, - SO_UPDATE_CONNECT_CONTEXT, 1) < 0) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket._HandleConnect.SetSockOpt'); - {$ENDIF} - _Failed1; - Exit; - end; - -// LConnection := CreateConnection(Self, LClientSocket, ctConnect, APerIoData.Callback); -// TriggerConnecting(LConnection); -// TriggerConnected(LConnection); - - LConnection := APerIoData.CrossData as ICrossConnection; - TriggerConnected(LConnection); - - if not _NewReadZero(LConnection) then - LConnection.Close; -end; - -procedure TIocpCrossSocket._HandleRead(const APerIoData: PPerIoData); -var - LConnection: ICrossConnection; - LRcvd, LError: Integer; -begin - if (APerIoData.CrossData = nil) then - begin - if Assigned(APerIoData.Callback) then - APerIoData.Callback(nil, False); - Exit; - end; - - LConnection := APerIoData.CrossData as ICrossConnection; - - while True do - begin - LRcvd := TSocketAPI.Recv(LConnection.Socket, FRecvBuf[0], RCV_BUF_SIZE); - - // 对方主动断开连接 - if (LRcvd = 0) then - begin - _Log('Recv=0(Close), %s', [LConnection.DebugInfo]); - LConnection.Close; - Exit; - end; - - if (LRcvd < 0) then - begin - LError := GetLastError; - - // 被系统信号中断, 可以重新recv - if (LError = WSAEINTR) then - Continue - // 接收缓冲区中数据已经被取完了 - else if (LError = WSAEWOULDBLOCK) or (LError = WSAEINPROGRESS) then - Break - // 接收出错 - else - begin - _LogLastOsError('Recv<0, %s', [LConnection.DebugInfo]); - LConnection.Close; - Exit; - end; - end; - - TriggerReceived(LConnection, @FRecvBuf[0], LRcvd); - - // 回调中可能关闭了连接, 需要检查状态 - if LConnection.IsClosed then Exit; - - if (LRcvd < RCV_BUF_SIZE) then Break; - end; - - if not _NewReadZero(LConnection) then - LConnection.Close; -end; - -procedure TIocpCrossSocket._HandleWrite(const APerIoData: PPerIoData); -begin - if Assigned(APerIoData.Callback) then - APerIoData.Callback(APerIoData.CrossData as ICrossConnection, True); -end; - -procedure TIocpCrossSocket.StartLoop; -var - I: Integer; -begin - if (FIoThreads <> nil) then Exit; - - FIocpHandle := CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0); - SetLength(FIoThreads, GetIoThreads); - for I := 0 to Length(FIoThreads) - 1 do - FIoThreads[I] := TIoEventThread.Create(Self); -end; - -procedure TIocpCrossSocket.StopLoop; - - // IO 线程在收到 SHUTDOWN_FLAG 标记之后就会退出 - // 而这时候有可能还有部分操作未完成, 其对应的 PerIoData 结构就无法释放 - // 只需要在这里再次接收完成端口的消息, 就能等到这部分未完成的操作超时或失败 - // 从而释放其对应的 PerIoData 结构 - procedure _FreeMissingPerIoDatas; - var - LBytes: Cardinal; - LSocket: TSocket; - LPerIoData: PPerIoData; - LConnection: ICrossConnection; - begin - while (AtomicCmpExchange(FPerIoDataCount, 0, 0) > 0) do - begin - GetQueuedCompletionStatus(FIocpHandle, LBytes, ULONG_PTR(LSocket), POverlapped(LPerIoData), 10); - - if (LPerIoData = nil) then Continue; - - try - if Assigned(LPerIoData.Callback) then - begin - if (LPerIoData.CrossData <> nil) - and (LPerIoData.CrossData is TIocpConnection) then - LConnection := LPerIoData.CrossData as ICrossConnection - else - LConnection := nil; - - LPerIoData.Callback(LConnection, False); - end; - - if (LPerIoData.CrossData <> nil) then - LPerIoData.CrossData.Close - else - TSocketAPI.CloseSocket(LPerIoData.Socket); - finally - _FreeIoData(LPerIoData); - end; - end; - end; - -var - I: Integer; - LCurrentThreadID: TThreadID; -begin - if (FIoThreads = nil) then Exit; - - CloseAll; - - while (ListensCount > 0) or (ConnectionsCount > 0) do Sleep(1); - - for I := 0 to Length(FIoThreads) - 1 do - PostQueuedCompletionStatus(FIocpHandle, 0, 0, POverlapped(SHUTDOWN_FLAG)); - - LCurrentThreadID := GetCurrentThreadId; - for I := 0 to Length(FIoThreads) - 1 do - begin - if (FIoThreads[I].ThreadID = LCurrentThreadID) then - raise ECrossSocket.Create('不能在IO线程中执行StopLoop!'); - - FIoThreads[I].WaitFor; - FreeAndNil(FIoThreads[I]); - end; - FIoThreads := nil; - - _FreeMissingPerIoDatas; - CloseHandle(FIocpHandle); -end; - -procedure TIocpCrossSocket.Connect(const AHost: string; - const APort, ALocalPort: Word; const ACallback: TCrossConnectionCallback); -var - LHints: TRawAddrInfo; - P, LAddrInfo: PRawAddrInfo; - LSocket: TSocket; - - procedure _Failed1; - begin - if Assigned(ACallback) then - ACallback(nil, False); - end; - - function _Connect(ASocket: TSocket; AAddr: PRawAddrInfo): Boolean; - procedure _Failed2; - begin - if Assigned(ACallback) then - ACallback(nil, False); - TSocketAPI.CloseSocket(ASocket); - end; - var - LSockAddr: TRawSockAddrIn; - LPerIoData: PPerIoData; - LBytes: Cardinal; - LConnection: ICrossConnection; - begin - FillChar(LSockAddr, SizeOf(TRawSockAddrIn), 0); - LSockAddr.AddrLen := AAddr.ai_addrlen; - if (AAddr.ai_family = AF_INET6) then - begin - LSockAddr.Addr6.sin6_family := AAddr.ai_family; - LSockAddr.Addr6.sin6_port := htons(ALocalPort); - end else - begin - LSockAddr.Addr.sin_family := AAddr.ai_family; - LSockAddr.Addr.sin_port := htons(ALocalPort); - end; - if (TSocketAPI.Bind(ASocket, @LSockAddr.Addr, LSockAddr.AddrLen) < 0) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket._Connect.Bind'); - {$ENDIF} - _Failed2; - Exit(False); - end; - - if (CreateIoCompletionPort(ASocket, FIocpHandle, ULONG_PTR(ASocket), 0) = 0) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket._Connect.CreateIoCompletionPort'); - {$ENDIF} - _Failed2; - Exit(False); - end; - - LConnection := CreateConnection(Self, ASocket, ctConnect, AHost, ACallback); - TriggerConnecting(LConnection); - - LPerIoData := _NewIoData; - LPerIoData.Action := ioConnect; - LPerIoData.CrossData := LConnection; - LPerIoData.Socket := ASocket; - LPerIoData.Callback := nil; - if not ConnectEx(ASocket, AAddr.ai_addr, AAddr.ai_addrlen, nil, 0, LBytes, PWSAOverlapped(LPerIoData)) and - (WSAGetLastError <> WSA_IO_PENDING) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket._Connect.ConnectEx'); - {$ENDIF} - _FreeIoData(LPerIoData); - LConnection.Close; - _Failed2; - Exit(False); - end; - - Result := True; - end; - -begin - FillChar(LHints, SizeOf(TRawAddrInfo), 0); - LHints.ai_family := AF_UNSPEC; - LHints.ai_socktype := SOCK_STREAM; - LHints.ai_protocol := IPPROTO_TCP; - LAddrInfo := TSocketAPI.GetAddrInfo(AHost, APort, LHints); - if (LAddrInfo = nil) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket.Connect.GetAddrInfo'); - {$ENDIF} - _Failed1; - Exit; - end; - - P := LAddrInfo; - try - while (LAddrInfo <> nil) do - begin - LSocket := WSASocket(LAddrInfo.ai_family, LAddrInfo.ai_socktype, - LAddrInfo.ai_protocol, nil, 0, WSA_FLAG_OVERLAPPED); - if (LSocket = INVALID_SOCKET) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket.Connect.WSASocket'); - {$ENDIF} - _Failed1; - Exit; - end; - - TSocketAPI.SetNonBlock(LSocket, True); - SetKeepAlive(LSocket); - - {$IFDEF DEBUG} - _Log('TIocpCrossSocket.Connect.WSASocket=%d', [LSocket]); - {$ENDIF} - - if _Connect(LSocket, LAddrInfo) then Exit; - - LAddrInfo := PRawAddrInfo(LAddrInfo.ai_next); - end; - finally - TSocketAPI.FreeAddrInfo(P); - end; - - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket.Connect.Unknown'); - {$ENDIF} - _Failed1; -end; - -function TIocpCrossSocket.CreateConnection(const AOwner: TCrossSocketBase; - const AClientSocket: TSocket; const AConnectType: TConnectType; - const AHost: string; const AConnectCb: TCrossConnectionCallback): ICrossConnection; -begin - Result := TIocpConnection.Create(AOwner, AClientSocket, AConnectType, AHost, AConnectCb); -end; - -function TIocpCrossSocket.CreateListen(const AOwner: TCrossSocketBase; - const AListenSocket: TSocket; const AFamily, ASockType, AProtocol: Integer): ICrossListen; -begin - Result := TIocpListen.Create(AOwner, AListenSocket, AFamily, ASockType, AProtocol); -end; - -procedure TIocpCrossSocket.Listen(const AHost: string; const APort: Word; - const ACallback: TCrossListenCallback); -var - LHints: TRawAddrInfo; - P, LAddrInfo: PRawAddrInfo; - LListenSocket: TSocket; - LListen: ICrossListen; - I: Integer; - LListenSuccess: Boolean; - - procedure _Failed; - begin - if not LListenSuccess and Assigned(ACallback) then - ACallback(LListen, False); - - if (LListen <> nil) then - LListen.Close - else if (LListenSocket <> INVALID_SOCKET) then - TSocketAPI.CloseSocket(LListenSocket); - end; - - procedure _Success; - begin - TriggerListened(LListen); - - if Assigned(ACallback) then - ACallback(LListen, True); - end; -begin - LListenSuccess := False; - FillChar(LHints, SizeOf(TRawAddrInfo), 0); - - LHints.ai_flags := AI_PASSIVE; - LHints.ai_family := AF_UNSPEC; - LHints.ai_socktype := SOCK_STREAM; - LHints.ai_protocol := IPPROTO_TCP; - LAddrInfo := TSocketAPI.GetAddrInfo(AHost, APort, LHints); - if (LAddrInfo = nil) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket.Listen.GetAddrInfo'); - {$ENDIF} - _Failed; - Exit; - end; - - P := LAddrInfo; - try - while (LAddrInfo <> nil) do - begin - LListen := nil; - LListenSocket := WSASocket(LAddrInfo.ai_family, LAddrInfo.ai_socktype, - LAddrInfo.ai_protocol, nil, 0, WSA_FLAG_OVERLAPPED); - if (LListenSocket = INVALID_SOCKET) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket.Listen.WSASocket'); - {$ENDIF} - _Failed; - Exit; - end; - - TSocketAPI.SetNonBlock(LListenSocket, True); - TSocketAPI.SetReUseAddr(LListenSocket, True); - - if (LAddrInfo.ai_family = AF_INET6) then - TSocketAPI.SetSockOpt(LListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, 1); - - if (TSocketAPI.Bind(LListenSocket, LAddrInfo.ai_addr, LAddrInfo.ai_addrlen) < 0) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket.Listen.Bind'); - {$ENDIF} - _Failed; - Exit; - end; - - if (TSocketAPI.Listen(LListenSocket) < 0) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket.Listen.Listen'); - {$ENDIF} - _Failed; - Exit; - end; - - LListen := CreateListen(Self, LListenSocket, LAddrInfo.ai_family, - LAddrInfo.ai_socktype, LAddrInfo.ai_protocol); - - if (CreateIoCompletionPort(LListenSocket, FIocpHandle, ULONG_PTR(LListenSocket), 0) = 0) then - begin - {$IFDEF DEBUG} - _LogLastOsError('TIocpCrossSocket.Listen.CreateIoCompletionPort'); - {$ENDIF} - _Failed; - Exit; - end; - - // 给每个IO线程投递一个AcceptEx - for I := 1 to GetIoThreads do - _NewAccept(LListen); - - LListenSuccess := True; - _Success; - - // 如果端口传入0,让所有地址统一用首个分配到的端口 - if (APort = 0) and (LAddrInfo.ai_next <> nil) then - LAddrInfo.ai_next.ai_addr.sin_port := LListen.LocalPort; - - LAddrInfo := PRawAddrInfo(LAddrInfo.ai_next); - end; - finally - TSocketAPI.FreeAddrInfo(P); - end; -end; - -procedure TIocpCrossSocket.Send(const AConnection: ICrossConnection; - const ABuf: Pointer; const ALen: Integer; const ACallback: TCrossConnectionCallback); -var - LPerIoData: PPerIoData; - LBytes, LFlags: Cardinal; -begin - LPerIoData := _NewIoData; - LPerIoData.Buffer.DataBuf.buf := ABuf; - LPerIoData.Buffer.DataBuf.len := ALen; - LPerIoData.Action := ioWrite; - LPerIoData.Socket := AConnection.Socket; - LPerIoData.CrossData := AConnection; - LPerIoData.Callback := ACallback; - - LFlags := 0; - LBytes := 0; - // WSASend 不会出现部分发送的情况, 要么全部失败, 要么全部成功 - // 所以不需要像 kqueue 或 epoll 中调用 send 那样调用完之后还得检查实际发送了多少 - // 唯一需要注意的是: WSASend 会将待发送的数据锁定到非页面内存, 非页面内存资源 - // 是非常紧张的, 所以不要无节制的调用 WSASend, 最好通过回调发送完一批数据再继 - // 续发送下一批 - if (WSASend(AConnection.Socket, @LPerIoData.Buffer.DataBuf, 1, LBytes, LFlags, PWSAOverlapped(LPerIoData), nil) < 0) - and (WSAGetLastError <> WSA_IO_PENDING) then - begin - {$IFDEF DEBUG} - _LogLastOsError('WSASend, %s', [AConnection.DebugInfo]); - {$ENDIF} - - // 出错多半是 WSAENOBUFS, 也就是投递的 WSASend 过多, 来不及发送 - // 导致非页面内存资源全部被锁定, 要避免这种情况必须上层发送逻辑 - // 保证不能无节制的调用Send发送大量数据, 最好发送完一个再继续下 - // 一个, 本函数提供了发送结果的回调函数, 在回调函数报告发送成功 - // 之后就可以继续下一块数据发送了 - _FreeIoData(LPerIoData); - - if Assigned(ACallback) then - ACallback(AConnection, False); - - AConnection.Close; - end; -end; - -function TIocpCrossSocket.ProcessIoEvent: Boolean; -var - LBytes: Cardinal; - LSocket: TSocket; - LPerIoData: PPerIoData; - LConnection: ICrossConnection; - {$IFDEF DEBUG} - LErrNo: Cardinal; - {$ENDIF} -begin - if not GetQueuedCompletionStatus(FIocpHandle, LBytes, ULONG_PTR(LSocket), POverlapped(LPerIoData), INFINITE) then - begin - {$IFDEF DEBUG} - LErrNo := GetLastError; - // 完成端口被关闭时可能会触发 ERROR_INVALID_HANDLE 和 ERROR_ABANDONED_WAIT_0 - if (LErrNo <> ERROR_INVALID_HANDLE) - and (LErrNo <> ERROR_ABANDONED_WAIT_0) - then - _LogLastOsError('TIocpCrossSocket.ProcessIoEvent.GetQueuedCompletionStatus'); - {$ENDIF} - - // 出错了, 并且完成数据也都是空的, - // 这种情况即便重试, 应该也会继续出错, 最好立即终止IO线程 - if (LPerIoData = nil) then Exit(False); - - try - // WSA_OPERATION_ABORTED, 995, 由于线程退出或应用程序请求,已中止 I/O 操作。 - // WSAENOTSOCK, 10038, 在一个非套接字上尝试了一个操作。 - // WSAESHUTDOWN, 10058, 套接字已关闭 - // ERROR_NETNAME_DELETED, 64, 指定的网络名不再可用 - // ERROR_CONNECTION_REFUSED, 1225, 远程计算机拒绝网络连接。 - if (LPerIoData.CrossData <> nil) then - begin - // AcceptEx虽然成功, 但是Socket句柄耗尽了, 再次投递AcceptEx - if (LPerIoData.Action = ioAccept) then - begin - // 照理说能执行到这里, 说明Socket分配失败了 - // 但是为了以防万一, 这里还是判断一下并释放掉无效的Socket句柄 - if (LPerIoData.Socket <> 0) then - TSocketAPI.CloseSocket(LPerIoData.Socket); - - // 关闭监听后会触发该错误, 这种情况不应该继续投递 - if (GetLastError <> WSA_OPERATION_ABORTED) then - _NewAccept(LPerIoData.CrossData as ICrossListen); - end else - begin - {$IFDEF DEBUG} - _LogLastOsError( - Format('TIocpCrossSocket.ProcessIoEvent.GetQueuedCompletionStatus.CrossDataNotNil(socket=%d, action=%d)', - [LPerIoData.Socket, Ord(LPerIoData.Action)]) - ); - {$ENDIF} - if Assigned(LPerIoData.Callback) then - begin - if (LPerIoData.CrossData is TIocpConnection) then - LConnection := LPerIoData.CrossData as ICrossConnection - else - LConnection := nil; - - LPerIoData.Callback(LConnection, False); - end; - - LPerIoData.CrossData.Close; - end; - end else - begin - {$IFDEF DEBUG} - _LogLastOsError( - Format('TIocpCrossSocket.ProcessIoEvent.GetQueuedCompletionStatus.CrossDataIsNil(socket=%d, action=%d)', - [LPerIoData.Socket, Ord(LPerIoData.Action)]) - ); - {$ENDIF} - if Assigned(LPerIoData.Callback) then - LPerIoData.Callback(nil, False); - - if (LPerIoData.Socket <> 0) then - TSocketAPI.CloseSocket(LPerIoData.Socket); - end; - finally - _FreeIoData(LPerIoData); - end; - - // 出错了, 但是完成数据不是空的, 需要重试 - Exit(True); - end; - - // 主动调用了 StopLoop - if (LBytes = 0) and (ULONG_PTR(LPerIoData) = SHUTDOWN_FLAG) then Exit(False); - - // 由于未知原因未获取到完成数据, 但是返回的错误代码又是正常 - // 这种情况需要进行重试(返回True之后IO线程会再次调用ProcessIoEvent) - if (LPerIoData = nil) then Exit(True); - - try - case LPerIoData.Action of - ioAccept : _HandleAccept(LPerIoData); - ioConnect : _HandleConnect(LPerIoData); - ioRead : _HandleRead(LPerIoData); - ioWrite : _HandleWrite(LPerIoData); - end; - finally - _FreeIoData(LPerIoData); - end; - - Result := True; -end; - -end. +{******************************************************************************} +{ } +{ Delphi cross platform socket library } +{ } +{ Copyright (c) 2017 WiNDDRiVER(soulawing@gmail.com) } +{ } +{ Homepage: https://github.com/winddriver/Delphi-Cross-Socket } +{ } +{******************************************************************************} + +{ PATCH-IOCP-1: fix DEBUG-build shutdown cascade (995 → _NewAccept → 10038 → 995). + Root cause: LErrNo was declared only in {$IFDEF DEBUG *, so the WSA_OPERATION_ABORTED + guard at the _NewAccept call site called GetLastError() a second time — after + _LogLastOsError() had already made Win32 calls that reset the thread's last-error + value. The guard then evaluated to True on a listener that was already closed, + called _NewAccept which failed with 10038 (not a socket), which fed back into + ProcessIoEvent as another 995, producing the cascade visible in the log. + Fix: always declare LErrNo; save GetLastError() immediately after GQCS fails, + before any other call; use LErrNo (not GetLastError()) at the _NewAccept guard. } + +unit Net.CrossSocket.Iocp; + +{$I zLib.inc} + +interface + +uses + SysUtils, + Classes, + Windows, + + Net.Winsock2, + Net.Wship6, + Net.SocketAPI, + Net.CrossSocket.Base; + +type + TIocpListen = class(TCrossListenBase) + end; + + TIocpConnection = class(TCrossConnectionBase) + end; + + TIocpCrossSocket = class(TCrossSocketBase) + private const + SHUTDOWN_FLAG = ULONG_PTR(-1); + SO_UPDATE_CONNECT_CONTEXT = $7010; + IPV6_V6ONLY = 27; + ERROR_ABANDONED_WAIT_0 = $02DF; + private type + TAddrUnion = record + case Integer of + 0: (IPv4: TSockAddrIn); + 1: (IPv6: TSockAddrIn6); + end; + + TAddrBuffer = record + Addr: TAddrUnion; + Extra: array [0..15] of Byte; + end; + + TAcceptExBuffer = array[0..SizeOf(TAddrBuffer) * 2 - 1] of Byte; + + TPerIoBufUnion = record + case Integer of + 0: (DataBuf: WSABUF); + // 这个Buffer只用于AcceptEx保存终端地址数据,大小为2倍地址结构 + 1: (AcceptExBuffer: TAcceptExBuffer); + end; + + TIocpAction = (ioAccept, ioConnect, ioRead, ioWrite); + + PPerIoData = ^TPerIoData; + TPerIoData = record + Overlapped: TWSAOverlapped; + Buffer: TPerIoBufUnion; + Action: TIocpAction; + Socket: TSocket; + CrossData: ICrossData; + Callback: TCrossConnectionCallback; + end; + private + FIocpHandle: THandle; + FIoThreads: TArray; + FPerIoDataCount: NativeInt; + + function _NewIoData: PPerIoData; inline; + procedure _FreeIoData(const P: PPerIoData); inline; + + procedure _NewAccept(const AListen: ICrossListen); + function _NewReadZero(const AConnection: ICrossConnection): Boolean; + + procedure _HandleAccept(const APerIoData: PPerIoData); + procedure _HandleConnect(const APerIoData: PPerIoData); + procedure _HandleRead(const APerIoData: PPerIoData); + procedure _HandleWrite(const APerIoData: PPerIoData); + protected + function CreateListen(const AOwner: TCrossSocketBase; const AListenSocket: TSocket; + const AFamily, ASockType, AProtocol: Integer): ICrossListen; override; + function CreateConnection(const AOwner: TCrossSocketBase; const AClientSocket: TSocket; + const AConnectType: TConnectType; const AHost: string; + const AConnectCb: TCrossConnectionCallback): ICrossConnection; override; + + procedure StartLoop; override; + procedure StopLoop; override; + + procedure Listen(const AHost: string; const APort: Word; + const ACallback: TCrossListenCallback = nil); override; + + procedure Connect(const AHost: string; const APort, ALocalPort: Word; + const ACallback: TCrossConnectionCallback = nil); override; + + procedure Send(const AConnection: ICrossConnection; const ABuf: Pointer; + const ALen: Integer; const ACallback: TCrossConnectionCallback = nil); override; + + function ProcessIoEvent: Boolean; override; + end; + +implementation + +{ TIocpCrossSocket } + +function TIocpCrossSocket._NewIoData: PPerIoData; +begin + GetMem(Result, SizeOf(TPerIoData)); + FillChar(Result^, SizeOf(TPerIoData), 0); + + AtomicIncrement(FPerIoDataCount); +end; + +procedure TIocpCrossSocket._FreeIoData(const P: PPerIoData); +begin + if (P = nil) then Exit; + + P.CrossData := nil; + P.Callback := nil; + FreeMem(P, SizeOf(TPerIoData)); + + AtomicDecrement(FPerIoDataCount); +end; + +procedure TIocpCrossSocket._NewAccept(const AListen: ICrossListen); +var + LClientSocket: TSocket; + LPerIoData: PPerIoData; + LBytes: Cardinal; +begin + LClientSocket := WSASocket(AListen.Family, AListen.SockType, AListen.Protocol, + nil, 0, WSA_FLAG_OVERLAPPED); + if (LClientSocket = INVALID_SOCKET) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket._NewAccept.WSASocket, %s', [AListen.DebugInfo]); + {$ENDIF} + Exit; + end; + + TSocketAPI.SetNonBlock(LClientSocket, True); + SetKeepAlive(LClientSocket); + + LPerIoData := _NewIoData; + LPerIoData.Action := ioAccept; + LPerIoData.Socket := LClientSocket; + LPerIoData.CrossData := AListen; + + if (not AcceptEx(AListen.Socket, LClientSocket, @LPerIoData.Buffer.AcceptExBuffer, 0, + SizeOf(TAddrBuffer), SizeOf(TAddrBuffer), LBytes, POverlapped(LPerIoData))) + and (WSAGetLastError <> WSA_IO_PENDING) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket._NewAccept.AcceptEx, %s', [AListen.DebugInfo]); + {$ENDIF} + TSocketAPI.CloseSocket(LClientSocket); + _FreeIoData(LPerIoData); + end; +end; + +function TIocpCrossSocket._NewReadZero(const AConnection: ICrossConnection): Boolean; +var + LPerIoData: PPerIoData; + LBytes, LFlags: Cardinal; +begin + LPerIoData := _NewIoData; + LPerIoData.Buffer.DataBuf.buf := nil; + LPerIoData.Buffer.DataBuf.len := 0; + LPerIoData.Action := ioRead; + LPerIoData.Socket := AConnection.Socket; + LPerIoData.CrossData := AConnection; + + LFlags := 0; + LBytes := 0; + if (WSARecv(AConnection.Socket, @LPerIoData.Buffer.DataBuf, 1, LBytes, LFlags, PWSAOverlapped(LPerIoData), nil) < 0) + and (WSAGetLastError <> WSA_IO_PENDING) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket._NewReadZero.WSARecv, %s', [AConnection.DebugInfo]); + {$ENDIF} + _FreeIoData(LPerIoData); + Exit(False); + end; + + Result := True; +end; + +procedure TIocpCrossSocket._HandleAccept(const APerIoData: PPerIoData); +var + LListen: ICrossListen; + LConnection: ICrossConnection; + LClientSocket, LListenSocket: TSocket; +begin + if (APerIoData.CrossData = nil) then Exit; + + LListen := APerIoData.CrossData as ICrossListen; + + _NewAccept(LListen); + + LClientSocket := APerIoData.Socket; + LListenSocket := LListen.Socket; + + // 不设置该参数, 会导致 getpeername 调用失败 + if (TSocketAPI.SetSockOpt(LClientSocket, SOL_SOCKET, + SO_UPDATE_ACCEPT_CONTEXT, LListenSocket) < 0) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket._HandleAccept.SetSockOpt'); + {$ENDIF} + TSocketAPI.CloseSocket(LClientSocket); + Exit; + end; + + if (CreateIoCompletionPort(LClientSocket, FIocpHandle, ULONG_PTR(LClientSocket), 0) = 0) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket._HandleAccept.CreateIoCompletionPort'); + {$ENDIF} + TSocketAPI.CloseSocket(LClientSocket); + Exit; + end; + + LConnection := CreateConnection(Self, LClientSocket, ctAccept, ''); + TriggerConnecting(LConnection); + TriggerConnected(LConnection); + + if not _NewReadZero(LConnection) then + LConnection.Close; +end; + +procedure TIocpCrossSocket._HandleConnect(const APerIoData: PPerIoData); +var + LClientSocket: TSocket; + LConnection: ICrossConnection; + + procedure _Failed1; + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket._HandleConnect'); + {$ENDIF} + + if Assigned(APerIoData.Callback) then + APerIoData.Callback(nil, False); + + TSocketAPI.CloseSocket(LClientSocket); + end; +begin + LClientSocket := APerIoData.Socket; + + if (TSocketAPI.GetError(LClientSocket) <> 0) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket._HandleConnect.GetError'); + {$ENDIF} + _Failed1; + Exit; + end; + + // 不设置该参数, 会导致 getpeername 调用失败 + if (TSocketAPI.SetSockOpt(LClientSocket, SOL_SOCKET, + SO_UPDATE_CONNECT_CONTEXT, 1) < 0) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket._HandleConnect.SetSockOpt'); + {$ENDIF} + _Failed1; + Exit; + end; + +// LConnection := CreateConnection(Self, LClientSocket, ctConnect, APerIoData.Callback); +// TriggerConnecting(LConnection); +// TriggerConnected(LConnection); + + LConnection := APerIoData.CrossData as ICrossConnection; + TriggerConnected(LConnection); + + if not _NewReadZero(LConnection) then + LConnection.Close; +end; + +procedure TIocpCrossSocket._HandleRead(const APerIoData: PPerIoData); +var + LConnection: ICrossConnection; + LRcvd, LError: Integer; +begin + if (APerIoData.CrossData = nil) then + begin + if Assigned(APerIoData.Callback) then + APerIoData.Callback(nil, False); + Exit; + end; + + LConnection := APerIoData.CrossData as ICrossConnection; + + while True do + begin + LRcvd := TSocketAPI.Recv(LConnection.Socket, FRecvBuf[0], RCV_BUF_SIZE); + + // 对方主动断开连接 + if (LRcvd = 0) then + begin + _Log('Recv=0(Close), %s', [LConnection.DebugInfo]); + LConnection.Close; + Exit; + end; + + if (LRcvd < 0) then + begin + LError := GetLastError; + + // 被系统信号中断, 可以重新recv + if (LError = WSAEINTR) then + Continue + // 接收缓冲区中数据已经被取完了 + else if (LError = WSAEWOULDBLOCK) or (LError = WSAEINPROGRESS) then + Break + // 接收出错 + else + begin + _LogLastOsError('Recv<0, %s', [LConnection.DebugInfo]); + LConnection.Close; + Exit; + end; + end; + + TriggerReceived(LConnection, @FRecvBuf[0], LRcvd); + + // 回调中可能关闭了连接, 需要检查状态 + if LConnection.IsClosed then Exit; + + if (LRcvd < RCV_BUF_SIZE) then Break; + end; + + if not _NewReadZero(LConnection) then + LConnection.Close; +end; + +procedure TIocpCrossSocket._HandleWrite(const APerIoData: PPerIoData); +begin + if Assigned(APerIoData.Callback) then + APerIoData.Callback(APerIoData.CrossData as ICrossConnection, True); +end; + +procedure TIocpCrossSocket.StartLoop; +var + I: Integer; +begin + if (FIoThreads <> nil) then Exit; + + FIocpHandle := CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0); + SetLength(FIoThreads, GetIoThreads); + for I := 0 to Length(FIoThreads) - 1 do + FIoThreads[I] := TIoEventThread.Create(Self); +end; + +procedure TIocpCrossSocket.StopLoop; + + // IO 线程在收到 SHUTDOWN_FLAG 标记之后就会退出 + // 而这时候有可能还有部分操作未完成, 其对应的 PerIoData 结构就无法释放 + // 只需要在这里再次接收完成端口的消息, 就能等到这部分未完成的操作超时或失败 + // 从而释放其对应的 PerIoData 结构 + procedure _FreeMissingPerIoDatas; + var + LBytes: Cardinal; + LSocket: TSocket; + LPerIoData: PPerIoData; + LConnection: ICrossConnection; + begin + while (AtomicCmpExchange(FPerIoDataCount, 0, 0) > 0) do + begin + GetQueuedCompletionStatus(FIocpHandle, LBytes, ULONG_PTR(LSocket), POverlapped(LPerIoData), 10); + + if (LPerIoData = nil) then Continue; + + try + if Assigned(LPerIoData.Callback) then + begin + if (LPerIoData.CrossData <> nil) + and (LPerIoData.CrossData is TIocpConnection) then + LConnection := LPerIoData.CrossData as ICrossConnection + else + LConnection := nil; + + LPerIoData.Callback(LConnection, False); + end; + + if (LPerIoData.CrossData <> nil) then + LPerIoData.CrossData.Close + else + TSocketAPI.CloseSocket(LPerIoData.Socket); + finally + _FreeIoData(LPerIoData); + end; + end; + end; + +var + I: Integer; + LCurrentThreadID: TThreadID; +begin + if (FIoThreads = nil) then Exit; + + CloseAll; + + while (ListensCount > 0) or (ConnectionsCount > 0) do Sleep(1); + + for I := 0 to Length(FIoThreads) - 1 do + PostQueuedCompletionStatus(FIocpHandle, 0, 0, POverlapped(SHUTDOWN_FLAG)); + + LCurrentThreadID := GetCurrentThreadId; + for I := 0 to Length(FIoThreads) - 1 do + begin + if (FIoThreads[I].ThreadID = LCurrentThreadID) then + raise ECrossSocket.Create('不能在IO线程中执行StopLoop!'); + + FIoThreads[I].WaitFor; + FreeAndNil(FIoThreads[I]); + end; + FIoThreads := nil; + + _FreeMissingPerIoDatas; + CloseHandle(FIocpHandle); +end; + +procedure TIocpCrossSocket.Connect(const AHost: string; + const APort, ALocalPort: Word; const ACallback: TCrossConnectionCallback); +var + LHints: TRawAddrInfo; + P, LAddrInfo: PRawAddrInfo; + LSocket: TSocket; + + procedure _Failed1; + begin + if Assigned(ACallback) then + ACallback(nil, False); + end; + + function _Connect(ASocket: TSocket; AAddr: PRawAddrInfo): Boolean; + procedure _Failed2; + begin + if Assigned(ACallback) then + ACallback(nil, False); + TSocketAPI.CloseSocket(ASocket); + end; + var + LSockAddr: TRawSockAddrIn; + LPerIoData: PPerIoData; + LBytes: Cardinal; + LConnection: ICrossConnection; + begin + FillChar(LSockAddr, SizeOf(TRawSockAddrIn), 0); + LSockAddr.AddrLen := AAddr.ai_addrlen; + if (AAddr.ai_family = AF_INET6) then + begin + LSockAddr.Addr6.sin6_family := AAddr.ai_family; + LSockAddr.Addr6.sin6_port := htons(ALocalPort); + end else + begin + LSockAddr.Addr.sin_family := AAddr.ai_family; + LSockAddr.Addr.sin_port := htons(ALocalPort); + end; + if (TSocketAPI.Bind(ASocket, @LSockAddr.Addr, LSockAddr.AddrLen) < 0) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket._Connect.Bind'); + {$ENDIF} + _Failed2; + Exit(False); + end; + + if (CreateIoCompletionPort(ASocket, FIocpHandle, ULONG_PTR(ASocket), 0) = 0) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket._Connect.CreateIoCompletionPort'); + {$ENDIF} + _Failed2; + Exit(False); + end; + + LConnection := CreateConnection(Self, ASocket, ctConnect, AHost, ACallback); + TriggerConnecting(LConnection); + + LPerIoData := _NewIoData; + LPerIoData.Action := ioConnect; + LPerIoData.CrossData := LConnection; + LPerIoData.Socket := ASocket; + LPerIoData.Callback := nil; + if not ConnectEx(ASocket, AAddr.ai_addr, AAddr.ai_addrlen, nil, 0, LBytes, PWSAOverlapped(LPerIoData)) and + (WSAGetLastError <> WSA_IO_PENDING) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket._Connect.ConnectEx'); + {$ENDIF} + _FreeIoData(LPerIoData); + LConnection.Close; + _Failed2; + Exit(False); + end; + + Result := True; + end; + +begin + FillChar(LHints, SizeOf(TRawAddrInfo), 0); + LHints.ai_family := AF_UNSPEC; + LHints.ai_socktype := SOCK_STREAM; + LHints.ai_protocol := IPPROTO_TCP; + LAddrInfo := TSocketAPI.GetAddrInfo(AHost, APort, LHints); + if (LAddrInfo = nil) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket.Connect.GetAddrInfo'); + {$ENDIF} + _Failed1; + Exit; + end; + + P := LAddrInfo; + try + while (LAddrInfo <> nil) do + begin + LSocket := WSASocket(LAddrInfo.ai_family, LAddrInfo.ai_socktype, + LAddrInfo.ai_protocol, nil, 0, WSA_FLAG_OVERLAPPED); + if (LSocket = INVALID_SOCKET) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket.Connect.WSASocket'); + {$ENDIF} + _Failed1; + Exit; + end; + + TSocketAPI.SetNonBlock(LSocket, True); + SetKeepAlive(LSocket); + + {$IFDEF DEBUG} + _Log('TIocpCrossSocket.Connect.WSASocket=%d', [LSocket]); + {$ENDIF} + + if _Connect(LSocket, LAddrInfo) then Exit; + + LAddrInfo := PRawAddrInfo(LAddrInfo.ai_next); + end; + finally + TSocketAPI.FreeAddrInfo(P); + end; + + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket.Connect.Unknown'); + {$ENDIF} + _Failed1; +end; + +function TIocpCrossSocket.CreateConnection(const AOwner: TCrossSocketBase; + const AClientSocket: TSocket; const AConnectType: TConnectType; + const AHost: string; const AConnectCb: TCrossConnectionCallback): ICrossConnection; +begin + Result := TIocpConnection.Create(AOwner, AClientSocket, AConnectType, AHost, AConnectCb); +end; + +function TIocpCrossSocket.CreateListen(const AOwner: TCrossSocketBase; + const AListenSocket: TSocket; const AFamily, ASockType, AProtocol: Integer): ICrossListen; +begin + Result := TIocpListen.Create(AOwner, AListenSocket, AFamily, ASockType, AProtocol); +end; + +procedure TIocpCrossSocket.Listen(const AHost: string; const APort: Word; + const ACallback: TCrossListenCallback); +var + LHints: TRawAddrInfo; + P, LAddrInfo: PRawAddrInfo; + LListenSocket: TSocket; + LListen: ICrossListen; + I: Integer; + LListenSuccess: Boolean; + + procedure _Failed; + begin + if not LListenSuccess and Assigned(ACallback) then + ACallback(LListen, False); + + if (LListen <> nil) then + LListen.Close + else if (LListenSocket <> INVALID_SOCKET) then + TSocketAPI.CloseSocket(LListenSocket); + end; + + procedure _Success; + begin + TriggerListened(LListen); + + if Assigned(ACallback) then + ACallback(LListen, True); + end; +begin + LListenSuccess := False; + FillChar(LHints, SizeOf(TRawAddrInfo), 0); + + LHints.ai_flags := AI_PASSIVE; + LHints.ai_family := AF_UNSPEC; + LHints.ai_socktype := SOCK_STREAM; + LHints.ai_protocol := IPPROTO_TCP; + LAddrInfo := TSocketAPI.GetAddrInfo(AHost, APort, LHints); + if (LAddrInfo = nil) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket.Listen.GetAddrInfo'); + {$ENDIF} + _Failed; + Exit; + end; + + P := LAddrInfo; + try + while (LAddrInfo <> nil) do + begin + LListen := nil; + LListenSocket := WSASocket(LAddrInfo.ai_family, LAddrInfo.ai_socktype, + LAddrInfo.ai_protocol, nil, 0, WSA_FLAG_OVERLAPPED); + if (LListenSocket = INVALID_SOCKET) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket.Listen.WSASocket'); + {$ENDIF} + _Failed; + Exit; + end; + + TSocketAPI.SetNonBlock(LListenSocket, True); + TSocketAPI.SetReUseAddr(LListenSocket, True); + + if (LAddrInfo.ai_family = AF_INET6) then + TSocketAPI.SetSockOpt(LListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, 1); + + if (TSocketAPI.Bind(LListenSocket, LAddrInfo.ai_addr, LAddrInfo.ai_addrlen) < 0) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket.Listen.Bind'); + {$ENDIF} + _Failed; + Exit; + end; + + if (TSocketAPI.Listen(LListenSocket) < 0) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket.Listen.Listen'); + {$ENDIF} + _Failed; + Exit; + end; + + LListen := CreateListen(Self, LListenSocket, LAddrInfo.ai_family, + LAddrInfo.ai_socktype, LAddrInfo.ai_protocol); + + if (CreateIoCompletionPort(LListenSocket, FIocpHandle, ULONG_PTR(LListenSocket), 0) = 0) then + begin + {$IFDEF DEBUG} + _LogLastOsError('TIocpCrossSocket.Listen.CreateIoCompletionPort'); + {$ENDIF} + _Failed; + Exit; + end; + + // 给每个IO线程投递一个AcceptEx + for I := 1 to GetIoThreads do + _NewAccept(LListen); + + LListenSuccess := True; + _Success; + + // 如果端口传入0,让所有地址统一用首个分配到的端口 + if (APort = 0) and (LAddrInfo.ai_next <> nil) then + LAddrInfo.ai_next.ai_addr.sin_port := LListen.LocalPort; + + LAddrInfo := PRawAddrInfo(LAddrInfo.ai_next); + end; + finally + TSocketAPI.FreeAddrInfo(P); + end; +end; + +procedure TIocpCrossSocket.Send(const AConnection: ICrossConnection; + const ABuf: Pointer; const ALen: Integer; const ACallback: TCrossConnectionCallback); +var + LPerIoData: PPerIoData; + LBytes, LFlags: Cardinal; +begin + LPerIoData := _NewIoData; + LPerIoData.Buffer.DataBuf.buf := ABuf; + LPerIoData.Buffer.DataBuf.len := ALen; + LPerIoData.Action := ioWrite; + LPerIoData.Socket := AConnection.Socket; + LPerIoData.CrossData := AConnection; + LPerIoData.Callback := ACallback; + + LFlags := 0; + LBytes := 0; + // WSASend 不会出现部分发送的情况, 要么全部失败, 要么全部成功 + // 所以不需要像 kqueue 或 epoll 中调用 send 那样调用完之后还得检查实际发送了多少 + // 唯一需要注意的是: WSASend 会将待发送的数据锁定到非页面内存, 非页面内存资源 + // 是非常紧张的, 所以不要无节制的调用 WSASend, 最好通过回调发送完一批数据再继 + // 续发送下一批 + if (WSASend(AConnection.Socket, @LPerIoData.Buffer.DataBuf, 1, LBytes, LFlags, PWSAOverlapped(LPerIoData), nil) < 0) + and (WSAGetLastError <> WSA_IO_PENDING) then + begin + {$IFDEF DEBUG} + _LogLastOsError('WSASend, %s', [AConnection.DebugInfo]); + {$ENDIF} + + // 出错多半是 WSAENOBUFS, 也就是投递的 WSASend 过多, 来不及发送 + // 导致非页面内存资源全部被锁定, 要避免这种情况必须上层发送逻辑 + // 保证不能无节制的调用Send发送大量数据, 最好发送完一个再继续下 + // 一个, 本函数提供了发送结果的回调函数, 在回调函数报告发送成功 + // 之后就可以继续下一块数据发送了 + _FreeIoData(LPerIoData); + + if Assigned(ACallback) then + ACallback(AConnection, False); + + AConnection.Close; + end; +end; + +function TIocpCrossSocket.ProcessIoEvent: Boolean; +var + LBytes: Cardinal; + LSocket: TSocket; + LPerIoData: PPerIoData; + LConnection: ICrossConnection; + // PATCH-IOCP-1: always declare LErrNo so the WSA_OPERATION_ABORTED guard + // below uses the value captured immediately after GetQueuedCompletionStatus, + // before _LogLastOsError (or any other Win32 call) resets the thread's + // last-error value. + LErrNo: Cardinal; +begin + if not GetQueuedCompletionStatus(FIocpHandle, LBytes, ULONG_PTR(LSocket), POverlapped(LPerIoData), INFINITE) then + begin + // PATCH-IOCP-1: capture before any other call that could reset last-error. + LErrNo := GetLastError; + {$IFDEF DEBUG} + // 完成端口被关闭时可能会触发 ERROR_INVALID_HANDLE 和 ERROR_ABANDONED_WAIT_0 + if (LErrNo <> ERROR_INVALID_HANDLE) + and (LErrNo <> ERROR_ABANDONED_WAIT_0) + then + _LogLastOsError('TIocpCrossSocket.ProcessIoEvent.GetQueuedCompletionStatus'); + {$ENDIF} + + // 出错了, 并且完成数据也都是空的, + // 这种情况即便重试, 应该也会继续出错, 最好立即终止IO线程 + if (LPerIoData = nil) then Exit(False); + + try + // WSA_OPERATION_ABORTED, 995, 由于线程退出或应用程序请求,已中止 I/O 操作。 + // WSAENOTSOCK, 10038, 在一个非套接字上尝试了一个操作。 + // WSAESHUTDOWN, 10058, 套接字已关闭 + // ERROR_NETNAME_DELETED, 64, 指定的网络名不再可用 + // ERROR_CONNECTION_REFUSED, 1225, 远程计算机拒绝网络连接。 + if (LPerIoData.CrossData <> nil) then + begin + // AcceptEx虽然成功, 但是Socket句柄耗尽了, 再次投递AcceptEx + if (LPerIoData.Action = ioAccept) then + begin + // 照理说能执行到这里, 说明Socket分配失败了 + // 但是为了以防万一, 这里还是判断一下并释放掉无效的Socket句柄 + if (LPerIoData.Socket <> 0) then + TSocketAPI.CloseSocket(LPerIoData.Socket); + + // 关闭监听后会触发该错误, 这种情况不应该继续投递 + // PATCH-IOCP-1: use LErrNo (captured before _LogLastOsError) + if (LErrNo <> WSA_OPERATION_ABORTED) then + _NewAccept(LPerIoData.CrossData as ICrossListen); + end else + begin + {$IFDEF DEBUG} + _LogLastOsError( + Format('TIocpCrossSocket.ProcessIoEvent.GetQueuedCompletionStatus.CrossDataNotNil(socket=%d, action=%d)', + [LPerIoData.Socket, Ord(LPerIoData.Action)]) + ); + {$ENDIF} + if Assigned(LPerIoData.Callback) then + begin + if (LPerIoData.CrossData is TIocpConnection) then + LConnection := LPerIoData.CrossData as ICrossConnection + else + LConnection := nil; + + LPerIoData.Callback(LConnection, False); + end; + + LPerIoData.CrossData.Close; + end; + end else + begin + {$IFDEF DEBUG} + _LogLastOsError( + Format('TIocpCrossSocket.ProcessIoEvent.GetQueuedCompletionStatus.CrossDataIsNil(socket=%d, action=%d)', + [LPerIoData.Socket, Ord(LPerIoData.Action)]) + ); + {$ENDIF} + if Assigned(LPerIoData.Callback) then + LPerIoData.Callback(nil, False); + + if (LPerIoData.Socket <> 0) then + TSocketAPI.CloseSocket(LPerIoData.Socket); + end; + finally + _FreeIoData(LPerIoData); + end; + + // 出错了, 但是完成数据不是空的, 需要重试 + Exit(True); + end; + + // 主动调用了 StopLoop + if (LBytes = 0) and (ULONG_PTR(LPerIoData) = SHUTDOWN_FLAG) then Exit(False); + + // 由于未知原因未获取到完成数据, 但是返回的错误代码又是正常 + // 这种情况需要进行重试(返回True之后IO线程会再次调用ProcessIoEvent) + if (LPerIoData = nil) then Exit(True); + + try + case LPerIoData.Action of + ioAccept : _HandleAccept(LPerIoData); + ioConnect : _HandleConnect(LPerIoData); + ioRead : _HandleRead(LPerIoData); + ioWrite : _HandleWrite(LPerIoData); + end; + finally + _FreeIoData(LPerIoData); + end; + + Result := True; +end; + +end. From 967fa54c46040457811af0a2c9d08d447479a0b6 Mon Sep 17 00:00:00 2001 From: freitasjca Date: Thu, 23 Apr 2026 02:59:55 +0100 Subject: [PATCH 08/10] chore(release): bump version to 1.0.1 --- boss.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boss.json b/boss.json index 52ec717..2ba2a20 100644 --- a/boss.json +++ b/boss.json @@ -1,7 +1,7 @@ { "name": "delphi-cross-socket", "description": "Delphi cross-platform async socket library (IOCP/epoll/kqueue) with HTTP server and OpenSSL 3.x support. Fork of winddriver/Delphi-Cross-Socket — adds Boss package manifest only. Zero source changes.", - "version": "1.0.0", + "version": "1.0.1", "homepage": "https://github.com/freitasjca/Delphi-Cross-Socket", "license": "MIT", "mainsrc": "Net/", From 5843113ec81b50b18382836c33e4fc813af65d8d Mon Sep 17 00:00:00 2001 From: freitasjca Date: Thu, 23 Apr 2026 15:04:31 +0100 Subject: [PATCH 09/10] chore: prepare release v1.0.1 --- .gitignore | 162 +- CnPack/Common/CnPack.inc | 7246 ++++---- CnPack/Crypto/CnAES.pas | 15138 ++++++++-------- CnPack/Crypto/CnBase64.pas | 1094 +- CnPack/Crypto/CnConsts.pas | 500 +- CnPack/Crypto/CnDES.pas | 3946 ++-- CnPack/Crypto/CnFloat.pas | 2708 +-- CnPack/Crypto/CnKDF.pas | 1614 +- CnPack/Crypto/CnMD5.pas | 1768 +- CnPack/Crypto/CnNative.pas | 9808 +++++----- CnPack/Crypto/CnPemUtils.pas | 2438 +-- CnPack/Crypto/CnRandom.pas | 830 +- CnPack/Crypto/CnSHA1.pas | 1474 +- CnPack/Crypto/CnSHA2.pas | 4674 ++--- CnPack/Crypto/CnSHA3.pas | 5400 +++--- CnPack/Crypto/CnSM3.pas | 1658 +- DelphiToFPC/DTF.Character.pas | 890 +- DelphiToFPC/DTF.Consts.pas | 74 +- DelphiToFPC/DTF.Diagnostics.pas | 296 +- DelphiToFPC/DTF.Generics.pas | 84 +- DelphiToFPC/DTF.Hash.pas | 1040 +- DelphiToFPC/DTF.RTL.pas | 142 +- DelphiToFPC/DTF.Rtti.pas | 344 +- DelphiToFPC/DTF.StreamEx.pas | 3670 ++-- DelphiToFPC/DTF.Types.pas | 54 +- LICENSE | 330 +- Net/BSD.kqueue.pas | 250 +- Net/Demos/Delphi/HttpClient/HttpClient.dpr | 592 +- Net/Demos/Delphi/HttpClient/HttpClient.dproj | 2322 +-- Net/Demos/Delphi/HttpClient/HttpClient.dsv | 22 +- Net/Demos/Delphi/HttpServer/HttpServer.dpr | 236 +- Net/Demos/Delphi/HttpServer/HttpServer.dproj | 2274 +-- .../Delphi/HttpServer/HttpServer.dproj.local | 4 +- Net/Demos/Delphi/HttpServer/HttpServer.dsv | 220 +- .../WebSocketClient/WebSocketClient.dpr | 196 +- .../WebSocketClient/WebSocketClient.dproj | 614 +- .../WebSocketClient.dproj.local | 4 +- .../WebSocketServer/WebSocketServer.dpr | 212 +- .../WebSocketServer/WebSocketServer.dproj | 542 +- .../WebSocketServer.dproj.local | 4 +- Net/Demos/FPC/HttpClient/HttpClient.lpi | 458 +- Net/Demos/FPC/HttpClient/HttpClient.lpr | 594 +- Net/Demos/FPC/HttpClient/HttpClient.lps | 518 +- Net/Demos/FPC/HttpServer/HttpServer.lpi | 460 +- Net/Demos/FPC/HttpServer/HttpServer.lpr | 190 +- Net/Demos/FPC/HttpServer/HttpServer.lps | 410 +- .../FPC/WebSocketClient/WebSocketClient.lpi | 378 +- .../FPC/WebSocketClient/WebSocketClient.lpr | 200 +- .../FPC/WebSocketClient/WebSocketClient.lps | 520 +- .../FPC/WebSocketServer/WebSocketServer.lpi | 378 +- .../FPC/WebSocketServer/WebSocketServer.lpr | 222 +- .../FPC/WebSocketServer/WebSocketServer.lps | 482 +- .../Old/CrossHttpConsole/CrossHttpConsole.dpr | 78 +- .../CrossHttpConsole/CrossHttpConsole.dproj | 1618 +- Net/Demos/Old/CrossHttpConsole/uAppCfg.pas | 170 +- Net/Demos/Old/CrossHttpConsole/uDM.dfm | 14 +- Net/Demos/Old/CrossHttpConsole/uDM.pas | 924 +- .../CrossWebSocket/CrossWebSocketServer.dpr | 28 +- .../CrossWebSocket/CrossWebSocketServer.dproj | 1622 +- .../uCrossWebSocketServerDemo.fmx | 98 +- .../uCrossWebSocketServerDemo.pas | 394 +- Net/Demos/Old/CrossWebSocket/web/index.html | 216 +- .../CrossWebSocket/web/jquery-2.2.3.min.js | 8 +- Net/Demos/Old/CrossWebSocket/web/style.css | 192 +- .../AndroidManifest.template.xml | 78 +- .../Entitlement.TemplateOSX32.xml | 14 +- .../Entitlement.TemplateiOS.xml | 20 +- .../TestCrossSocket.deployproj | 748 +- .../Old/TestCrossSocket/TestCrossSocket.dpr | 60 +- .../Old/TestCrossSocket/TestCrossSocket.dproj | 3326 ++-- .../info.plist.TemplateOSX.xml | 16 +- Net/Demos/Old/TestCrossSocket/uMain.fmx | 630 +- Net/Demos/Old/TestCrossSocket/uMain.pas | 824 +- Net/Demos/Old/server.crt | 206 +- Net/Demos/Old/server.key | 52 +- Net/Demos/server.crt | 46 +- Net/Demos/server.key | 56 +- Net/Net.CrossHttpClient.pas | 6500 +++---- Net/Net.CrossHttpMiddleware.pas | 494 +- Net/Net.CrossHttpParser.pas | 1146 +- Net/Net.CrossHttpRouter.pas | 348 +- Net/Net.CrossHttpRouterDirUtils.pas | 578 +- Net/Net.CrossServer.pas | 342 +- Net/Net.CrossSocket.Base.pas | 3890 ++-- Net/Net.CrossSocket.pas | 114 +- Net/Net.CrossSslDemoCert.pas | 144 +- Net/Net.CrossSslSocket.Base.pas | 560 +- Net/Net.CrossSslSocket.MbedTls.pas | 1094 +- Net/Net.CrossSslSocket.Types.pas | 622 +- Net/Net.CrossSslSocket.pas | 66 +- Net/Net.CrossWebSocketClient.pas | 2792 +-- Net/Net.CrossWebSocketParser.pas | 908 +- Net/Net.CrossWebSocketServer.pas | 2046 +-- Net/Net.MbedBIO.pas | 780 +- Net/Net.MbedTls.pas | 3282 ++-- Net/Net.OpenSSL.pas | 6938 +++---- Net/Net.RawSocket.pas | 346 +- Net/Net.SocketAPI.pas | 2240 +-- Net/Net.Winsock.inc | 2104 +-- Net/Net.Winsock2.pas | 13510 +++++++------- Net/Net.Wship6.pas | 1180 +- Net/Tools/OpenSSL/CA.pl | 474 +- Net/Tools/OpenSSL/PEM/ca-cert.srl | 2 +- Net/Tools/OpenSSL/PEM/ca-key.pem | 32 +- Net/Tools/OpenSSL/PEM/ca-req.pem | 22 +- Net/Tools/OpenSSL/PEM/cert.pem | 22 +- Net/Tools/OpenSSL/PEM/client.pem | 104 +- .../OpenSSL/PEM/demoSRP/srp_verifier.txt | 12 +- .../OpenSSL/PEM/demoSRP/srp_verifier.txt.attr | 2 +- Net/Tools/OpenSSL/PEM/dsa-ca.pem | 94 +- Net/Tools/OpenSSL/PEM/dsa-pca.pem | 94 +- Net/Tools/OpenSSL/PEM/dsa1024.pem | 18 +- Net/Tools/OpenSSL/PEM/dsa512.pem | 12 +- Net/Tools/OpenSSL/PEM/dsap.pem | 12 +- Net/Tools/OpenSSL/PEM/pca-cert.srl | 2 +- Net/Tools/OpenSSL/PEM/pca-key.pem | 32 +- Net/Tools/OpenSSL/PEM/pca-req.pem | 22 +- Net/Tools/OpenSSL/PEM/privkey.pem | 32 +- Net/Tools/OpenSSL/PEM/req.pem | 22 +- Net/Tools/OpenSSL/PEM/rsa8192.pem | 198 +- Net/Tools/OpenSSL/PEM/s1024key.pem | 30 +- Net/Tools/OpenSSL/PEM/s1024req.pem | 22 +- Net/Tools/OpenSSL/PEM/s512-key.pem | 18 +- Net/Tools/OpenSSL/PEM/s512-req.pem | 16 +- Net/Tools/OpenSSL/PEM/server.pem | 94 +- Net/Tools/OpenSSL/PEM/server.srl | 2 +- Net/Tools/OpenSSL/PEM/server2.pem | 104 +- Net/Tools/OpenSSL/PEM/testCA.pem | 16 +- Net/Tools/OpenSSL/keys/ca.crt | 50 +- Net/Tools/OpenSSL/keys/ca.csr | 34 +- Net/Tools/OpenSSL/keys/ca.key | 56 +- Net/Tools/OpenSSL/keys/ca.srl | 2 +- Net/Tools/OpenSSL/keys/client.crt | 46 +- Net/Tools/OpenSSL/keys/client.csr | 34 +- Net/Tools/OpenSSL/keys/client.key | 56 +- Net/Tools/OpenSSL/keys/client.pem | 18 +- Net/Tools/OpenSSL/keys/server.crt | 46 +- Net/Tools/OpenSSL/keys/server.csr | 34 +- Net/Tools/OpenSSL/keys/server.key | 56 +- Net/Tools/OpenSSL/keys/server.pem | 18 +- Net/Tools/OpenSSL/progs.pl | 440 +- Net/Tools/OpenSSL/step1.bat | 40 +- Net/Tools/OpenSSL/step2.bat | 32 +- Net/Tools/OpenSSL/step3.bat | 38 +- Net/Tools/OpenSSL/v3.ext | 6 +- README.en.md | 238 +- README.md | 242 +- Utils/Utils.AnonymousThread.pas | 82 +- Utils/Utils.ArrayUtils.pas | 1128 +- Utils/Utils.Base64.pas | 562 +- Utils/Utils.DateTime.pas | 1824 +- Utils/Utils.EasyThread.pas | 236 +- Utils/Utils.EasyTimer.pas | 454 +- Utils/Utils.Hash.pas | 2156 +-- Utils/Utils.IOUtils.pas | 3010 +-- Utils/Utils.Logger.pas | 868 +- Utils/Utils.Punycode.pas | 620 +- Utils/Utils.RegEx.pas | 2012 +- Utils/Utils.Rtti.pas | 1658 +- Utils/Utils.SimpleWatch.pas | 134 +- Utils/Utils.StrUtils.pas | 350 +- Utils/Utils.SyncObjs.pas | 2036 +-- Utils/Utils.Utils.pas | 2220 +-- boss.json | 20 +- clear.bat | 6 +- zLib.inc | 102 +- 166 files changed, 82810 insertions(+), 82810 deletions(-) diff --git a/.gitignore b/.gitignore index 344952c..a5b28f3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,81 +1,81 @@ -modules/ -dist/ -static/ -**/Win32/ -**/Win64/ -**/Linux64/ -**/__history/ -**/__recovery/ -src/*.~* -__history/ -__recovery/ -packages/Win32/ -packages/Win64/ -packages/Linux64/ -packages/dcu/ -packages/dcp/ -packages/bpl/ -*.res -*.exe -*.dll -*.bpl -*.bpi -*.dcp -*.bpl -*.so -*.apk -*.drc -*.map -*.dres -*.rsm -*.tds -*.dcu -*.lib -*.a -*.o -*.ocx -*.local -*.identcache -*.projdata -*.tvsconfig -*.dsk -*.dcu -*.exe -*.ico -*.so -*.~* -*.a -*.stat -*.skincfg - -# Mac -*.DS_Store - -#FPC/Laz -lib/ -backup/ -*.lps - -# Code coverage reports -**/console/ -**/vcl/ -dunitx-results.xml -*.bak - -# Claude Code -.claude/settings.local.json -.claude.json -CLAUDE.md - -# Delphi build output -__history/ -__recovery/ -*.dcu -*.exe -*.dll -*.bpl -*.dcp -*.local -*.identcache -*.tvsconfig -*.dsk +modules/ +dist/ +static/ +**/Win32/ +**/Win64/ +**/Linux64/ +**/__history/ +**/__recovery/ +src/*.~* +__history/ +__recovery/ +packages/Win32/ +packages/Win64/ +packages/Linux64/ +packages/dcu/ +packages/dcp/ +packages/bpl/ +*.res +*.exe +*.dll +*.bpl +*.bpi +*.dcp +*.bpl +*.so +*.apk +*.drc +*.map +*.dres +*.rsm +*.tds +*.dcu +*.lib +*.a +*.o +*.ocx +*.local +*.identcache +*.projdata +*.tvsconfig +*.dsk +*.dcu +*.exe +*.ico +*.so +*.~* +*.a +*.stat +*.skincfg + +# Mac +*.DS_Store + +#FPC/Laz +lib/ +backup/ +*.lps + +# Code coverage reports +**/console/ +**/vcl/ +dunitx-results.xml +*.bak + +# Claude Code +.claude/settings.local.json +.claude.json +CLAUDE.md + +# Delphi build output +__history/ +__recovery/ +*.dcu +*.exe +*.dll +*.bpl +*.dcp +*.local +*.identcache +*.tvsconfig +*.dsk diff --git a/CnPack/Common/CnPack.inc b/CnPack/Common/CnPack.inc index cad0164..3ffcc8d 100644 --- a/CnPack/Common/CnPack.inc +++ b/CnPack/Common/CnPack.inc @@ -1,3623 +1,3623 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -{******************************************************************************} -{ } -{ עõԪΪָͱ汾Ϣļ } -{ õԪݲֲο JCL GExperts } -{ } -{******************************************************************************} - -//============================================================================== -// ѡ -//============================================================================== - -{$IFDEF FPC} - // Free Pascal Compiler 3.x Up Definitions - {$DEFINE SUPPORT_PASCAL} // Pascal - {$DEFINE SUPPORT_UINT64} // UInt64 - {$DEFINE SUPPORT_32_AND_64} // ֧ 32 64 λ NativeInt - {$DEFINE SUPPORT_ENCODING} // Unicode ַ֧ Encoding ת - {$DEFINE SUPPORT_INLINE} // ֧ inline - - {$DEFINE OBJECT_HAS_TOSTRING} // TObject.ToString - {$DEFINE TBYTES_DEFINED} - - // CPU FPC ӳ䵽 Delphi - {$IFDEF CPU386} // Intel 32 CPU - {$DEFINE CPU32BITS} - {$DEFINE CPUX86} - {$asmMode intel} - {$ENDIF} - {$IFDEF CPUi386} - {$DEFINE CPU32BITS} - {$DEFINE CPUX86} - {$asmMode intel} - {$ENDIF} - - {$IFDEF CPUAMD64} // Intel 64 CPU - {$DEFINE CPU64BITS} - {$DEFINE CPUX64} - {$asmMode intel} - {$ENDIF} - {$IFDEF CPUX86_64} - {$DEFINE CPU64BITS} - {$DEFINE CPUX64} - {$asmMode intel} - {$ENDIF} - {$IFDEF CPUIA64} - {$DEFINE CPU64BITS} - {$DEFINE CPUX64} - {$asmMode intel} - {$ENDIF} - - {$IFDEF CPUARM} // ARM 32 bit processor - {$DEFINE CPU32BITS} - {$DEFINE CPUARM} - {$DEFINE CPUARM32} - {$ENDIF} - - {$IFDEF CPUAARCH64} // ARM 64 bit processor - {$DEFINE CPU64BITS} - {$DEFINE CPUARM} - {$DEFINE CPUARM64} - {$ENDIF} - - {$mode Delphi} // Delphi Compatibility, not DelphiUnicodeעԴظ - - // ر Range Check Overflow Check - {$R- No Range checking} - {$OVERFLOWCHECKS OFF} - -{$ELSE FPC} // Below is for Delphi Compiler - -//{$DEFINE PERSONAL_EDITION} -{$DEFINE ENTERPRISE_EDITION} - -{$IFNDEF PERSONAL_EDITION} - {$DEFINE SUPPORT_DB} - {$DEFINE SUPPORT_ADO} -{$ENDIF} - -//============================================================================== -// 汾Ϣ -//============================================================================== - -{$IFDEF VER360} - {$DEFINE COMPILER29} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI29} - {$DEFINE DELPHI120_ATHENS} - {$DEFINE BCB28} - {$DEFINE BCB120_ATHENS} - {$DEFINE BDS23} -{$ENDIF} - -{$IFDEF VER350} - {$DEFINE COMPILER28} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI28} - {$DEFINE DELPHI110_ALEXANDRIA} - {$DEFINE BCB28} - {$DEFINE BCB110_ALEXANDRIA} - {$DEFINE BDS22} -{$ENDIF} - -{$IFDEF VER340} - {$DEFINE COMPILER27} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI27} - {$DEFINE DELPHI104_SYDNEY} - {$DEFINE BCB27} - {$DEFINE BCB104_SYDNEY} - {$DEFINE BDS21} -{$ENDIF} - -{$IFDEF VER330} - {$DEFINE COMPILER26} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI26} - {$DEFINE DELPHI103_RIO} - {$DEFINE BCB26} - {$DEFINE BCB103_RIO} - {$DEFINE BDS20} -{$ENDIF} - -{$IFDEF VER320} - {$DEFINE COMPILER25} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI25} - {$DEFINE DELPHI102_TOKYO} - {$DEFINE BCB25} - {$DEFINE BCB102_TOKYO} - {$DEFINE BDS19} -{$ENDIF} - -{$IFDEF VER310} - {$DEFINE COMPILER24} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI24} - {$DEFINE DELPHI101_BERLIN} - {$DEFINE BCB24} - {$DEFINE BCB101_BERLIN} - {$DEFINE BDS18} -{$ENDIF} - -{$IFDEF VER300} - {$DEFINE COMPILER23} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI23} - {$DEFINE DELPHI10_SEATTLE} - {$DEFINE BCB23} - {$DEFINE BCB10_SEATTLE} - {$DEFINE BDS17} -{$ENDIF} - -{$IFDEF VER290} - {$DEFINE COMPILER22} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI22} - {$DEFINE DELPHIXE8} - {$DEFINE BCB22} - {$DEFINE BCBXE8} - {$DEFINE BDS16} -{$ENDIF} - -{$IFDEF VER280} - {$DEFINE COMPILER21} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI21} - {$DEFINE DELPHIXE7} - {$DEFINE BCB21} - {$DEFINE BCBXE7} - {$DEFINE BDS15} -{$ENDIF} - -{$IFDEF VER270} - {$DEFINE COMPILER20} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI20} - {$DEFINE DELPHIXE6} - {$DEFINE BCB20} - {$DEFINE BCBXE6} - {$DEFINE BDS14} -{$ENDIF} - -{$IFDEF VER260} - {$DEFINE COMPILER19} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI19} - {$DEFINE DELPHIXE5} - {$DEFINE BCB19} - {$DEFINE BCBXE5} - {$DEFINE BDS12} -{$ENDIF} - -{$IFDEF VER250} - {$DEFINE COMPILER18} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI18} - {$DEFINE DELPHIXE4} - {$DEFINE BCB18} - {$DEFINE BCBXE4} - {$DEFINE BDS11} -{$ENDIF} - -{$IFDEF VER240} - {$DEFINE COMPILER17} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI17} - {$DEFINE DELPHIXE3} - {$DEFINE DELPHI2013} - {$DEFINE BCB17} - {$DEFINE BCBXE3} - {$DEFINE BCB2013} - {$DEFINE BDS10} - {$DEFINE BDS2013} -{$ENDIF} - -{$IFDEF VER230} - {$DEFINE COMPILER16} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI16} - {$DEFINE DELPHIXE2} - {$DEFINE DELPHI2012} - {$DEFINE BCB16} - {$DEFINE BCBXE2} - {$DEFINE BCB2012} - {$DEFINE BDS9} - {$DEFINE BDS2012} -{$ENDIF} - -{$IFDEF VER220} - {$DEFINE COMPILER15} - {$IFDEF LINUX} - {$DEFINE UCL10} - {$ELSE} - {$DEFINE VCL71} - {$ENDIF} - {$DEFINE DELPHI15} - {$DEFINE DELPHIXE} - {$DEFINE DELPHI2011} - {$DEFINE BCB15} - {$DEFINE BCBXE} - {$DEFINE BCB2011} - {$DEFINE BDS8} - {$DEFINE BDS2011} -{$ENDIF} - -{$IFDEF VER210} - {$DEFINE COMPILER14} - {$DEFINE VCL71} - {$DEFINE DELPHI14} - {$DEFINE DELPHI2010} - {$DEFINE BCB14} - {$DEFINE BCB2010} - {$DEFINE BDS7} - {$DEFINE BDS2010} -{$ENDIF} - -{$IFDEF VER200} - {$DEFINE COMPILER12} - {$DEFINE VCL71} - {$DEFINE DELPHI12} - {$DEFINE DELPHI2009} - {$DEFINE BCB12} - {$DEFINE BCB2009} - {$DEFINE BDS6} - {$DEFINE BDS2009} -{$ENDIF} - -{$IFDEF VER185} - {$DEFINE COMPILER11} - {$DEFINE VCL71} - {$DEFINE DELPHI11} - {$DEFINE DELPHI2007} - {$DEFINE BCB11} - {$DEFINE BCB2007} - {$DEFINE BDS5} - {$DEFINE BDS2007} - {$UNDEF VER180} -{$ENDIF} - -{$IFDEF VER180} - {$DEFINE COMPILER10} - {$DEFINE VCL71} - {$DEFINE DELPHI10} - {$DEFINE DELPHI2006} - {$DEFINE BCB10} - {$DEFINE BCB2006} - {$DEFINE BDS4} - {$DEFINE BDS2006} -{$ENDIF} - -{$IFDEF VER170} - {$DEFINE COMPILER9} - {$DEFINE VCL71} - {$DEFINE DELPHI9} - {$DEFINE DELPHI2005} - {$DEFINE BDS3} - {$DEFINE BDS2005} -{$ENDIF} - -{$IFDEF VER160} - {$DEFINE COMPILER8} - {$DEFINE VCL71} - {$DEFINE DELPHI8} - {$DEFINE BDS2} -{$ENDIF} - -{$IFDEF VER150} - {$DEFINE COMPILER7} - {$IFDEF LINUX} - {$DEFINE CLX10} - {$ELSE} - {$DEFINE VCL70} - {$DEFINE CLX10} - {$IFDEF BCB} - {$DEFINE BCB7} - {$ELSE} - {$DEFINE DELPHI7} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$IFDEF VER140} - {$DEFINE COMPILER6} - {$IFDEF LINUX} - {$DEFINE CLX10} - {$IFDEF CONDITIONALEXPRESSIONS} - {$IFDEF CompilerVersion} - {$IF System.RTLVersion = 14.1} - {$DEFINE KYLIX2} - {$IFEND} - {$IF System.RTLVersion = 14.5} - {$DEFINE KYLIX3} - {$IFEND} - {$ELSE} - {$DEFINE KYLIX1} - {$ENDIF} - {$ENDIF} - {$ELSE} - {$DEFINE VCL60} - {$DEFINE CLX10} - {$IFDEF BCB} - {$DEFINE BCB6} - {$ELSE} - {$DEFINE DELPHI6} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$IFDEF VER130} - {$DEFINE COMPILER5} - {$DEFINE VCL50} - {$IFDEF BCB} - {$DEFINE BCB5} - {$ELSE} - {$DEFINE DELPHI5} - {$ENDIF} -{$ENDIF} - -{$IFDEF VER125} - {$DEFINE COMPILER4} - {$DEFINE VCL40} - {$DEFINE BCB4} -{$ENDIF} - -{$IFDEF VER120} - {$DEFINE COMPILER4} - {$DEFINE VCL40} - {$DEFINE DELPHI4} -{$ENDIF} - -{$IFDEF VER110} - {$DEFINE COMPILER35} - {$DEFINE VCL30} - {$DEFINE BCB3} -{$ENDIF} - -{$IFDEF VER100} - {$DEFINE COMPILER3} - {$DEFINE VCL30} - {$DEFINE DELPHI3} -{$ENDIF} - -{$IFDEF VER93} - {$DEFINE COMPILER2} - {$DEFINE VCL20} - {$DEFINE BCB1} -{$ENDIF} - -{$IFDEF VER90} - {$DEFINE COMPILER2} - {$DEFINE VCL20} - {$DEFINE DELPHI2} -{$ENDIF} - -{$IFDEF VER80} - {$DEFINE COMPILER1} - {$DEFINE VCL10} - {$DEFINE DELPHI1} -{$ENDIF} - -// DELPHIX_UP from DELPHIX mappings - -{$IFDEF DELPHI29} - {$DEFINE DELPHI} - {$DEFINE DELPHI29_UP} - {$DEFINE DELPHI28_UP} - {$DEFINE DELPHI27_UP} - {$DEFINE DELPHI26_UP} - {$DEFINE DELPHI25_UP} - {$DEFINE DELPHI24_UP} - {$DEFINE DELPHI23_UP} - {$DEFINE DELPHI22_UP} - {$DEFINE DELPHI21_UP} - {$DEFINE DELPHI20_UP} - {$DEFINE DELPHI19_UP} - {$DEFINE DELPHI18_UP} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI120_ATHENS} - {$DEFINE DELPHI120_ATHENS_UP} - {$DEFINE DELPHI110_ALEXANDRIA_UP} - {$DEFINE DELPHI104_SYDNEY_UP} - {$DEFINE DELPHI103_RIO_UP} - {$DEFINE DELPHI102_TOKYO_UP} - {$DEFINE DELPHI101_BERLIN_UP} - {$DEFINE DELPHI10_SEATTLE_UP} - {$DEFINE DELPHIXE8_UP} - {$DEFINE DELPHIXE7_UP} - {$DEFINE DELPHIXE6_UP} - {$DEFINE DELPHIXE5_UP} - {$DEFINE DELPHIXE4_UP} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} - - // NO DELPHI2014 defined, so need define below here. - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI28} - {$DEFINE DELPHI} - {$DEFINE DELPHI28_UP} - {$DEFINE DELPHI27_UP} - {$DEFINE DELPHI26_UP} - {$DEFINE DELPHI25_UP} - {$DEFINE DELPHI24_UP} - {$DEFINE DELPHI23_UP} - {$DEFINE DELPHI22_UP} - {$DEFINE DELPHI21_UP} - {$DEFINE DELPHI20_UP} - {$DEFINE DELPHI19_UP} - {$DEFINE DELPHI18_UP} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI110_ALEXANDRIA} - {$DEFINE DELPHI110_ALEXANDRIA_UP} - {$DEFINE DELPHI104_SYDNEY_UP} - {$DEFINE DELPHI103_RIO_UP} - {$DEFINE DELPHI102_TOKYO_UP} - {$DEFINE DELPHI101_BERLIN_UP} - {$DEFINE DELPHI10_SEATTLE_UP} - {$DEFINE DELPHIXE8_UP} - {$DEFINE DELPHIXE7_UP} - {$DEFINE DELPHIXE6_UP} - {$DEFINE DELPHIXE5_UP} - {$DEFINE DELPHIXE4_UP} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} - - // NO DELPHI2014 defined, so need define below here. - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI27} - {$DEFINE DELPHI} - {$DEFINE DELPHI27_UP} - {$DEFINE DELPHI26_UP} - {$DEFINE DELPHI25_UP} - {$DEFINE DELPHI24_UP} - {$DEFINE DELPHI23_UP} - {$DEFINE DELPHI22_UP} - {$DEFINE DELPHI21_UP} - {$DEFINE DELPHI20_UP} - {$DEFINE DELPHI19_UP} - {$DEFINE DELPHI18_UP} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI104_SYDNEY} - {$DEFINE DELPHI104_SYDNEY_UP} - {$DEFINE DELPHI103_RIO_UP} - {$DEFINE DELPHI102_TOKYO_UP} - {$DEFINE DELPHI101_BERLIN_UP} - {$DEFINE DELPHI10_SEATTLE_UP} - {$DEFINE DELPHIXE8_UP} - {$DEFINE DELPHIXE7_UP} - {$DEFINE DELPHIXE6_UP} - {$DEFINE DELPHIXE5_UP} - {$DEFINE DELPHIXE4_UP} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} - - // NO DELPHI2014 defined, so need define below here. - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI26} - {$DEFINE DELPHI} - {$DEFINE DELPHI26_UP} - {$DEFINE DELPHI25_UP} - {$DEFINE DELPHI24_UP} - {$DEFINE DELPHI23_UP} - {$DEFINE DELPHI22_UP} - {$DEFINE DELPHI21_UP} - {$DEFINE DELPHI20_UP} - {$DEFINE DELPHI19_UP} - {$DEFINE DELPHI18_UP} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI103_RIO} - {$DEFINE DELPHI103_RIO_UP} - {$DEFINE DELPHI102_TOKYO_UP} - {$DEFINE DELPHI101_BERLIN_UP} - {$DEFINE DELPHI10_SEATTLE_UP} - {$DEFINE DELPHIXE8_UP} - {$DEFINE DELPHIXE7_UP} - {$DEFINE DELPHIXE6_UP} - {$DEFINE DELPHIXE5_UP} - {$DEFINE DELPHIXE4_UP} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} - - // NO DELPHI2014 defined, so need define below here. - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI25} - {$DEFINE DELPHI} - {$DEFINE DELPHI25_UP} - {$DEFINE DELPHI24_UP} - {$DEFINE DELPHI23_UP} - {$DEFINE DELPHI22_UP} - {$DEFINE DELPHI21_UP} - {$DEFINE DELPHI20_UP} - {$DEFINE DELPHI19_UP} - {$DEFINE DELPHI18_UP} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI102_TOKYO} - {$DEFINE DELPHI102_TOKYO_UP} - {$DEFINE DELPHI101_BERLIN_UP} - {$DEFINE DELPHI10_SEATTLE_UP} - {$DEFINE DELPHIXE8_UP} - {$DEFINE DELPHIXE7_UP} - {$DEFINE DELPHIXE6_UP} - {$DEFINE DELPHIXE5_UP} - {$DEFINE DELPHIXE4_UP} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} - - // NO DELPHI2014 defined, so need define below here. - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI24} - {$DEFINE DELPHI} - {$DEFINE DELPHI24_UP} - {$DEFINE DELPHI23_UP} - {$DEFINE DELPHI22_UP} - {$DEFINE DELPHI21_UP} - {$DEFINE DELPHI20_UP} - {$DEFINE DELPHI19_UP} - {$DEFINE DELPHI18_UP} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI101_BERLIN} - {$DEFINE DELPHI101_BERLIN_UP} - {$DEFINE DELPHI10_SEATTLE_UP} - {$DEFINE DELPHIXE8_UP} - {$DEFINE DELPHIXE7_UP} - {$DEFINE DELPHIXE6_UP} - {$DEFINE DELPHIXE5_UP} - {$DEFINE DELPHIXE4_UP} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} - - // NO DELPHI2014 defined, so need define below here. - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI23} - {$DEFINE DELPHI} - {$DEFINE DELPHI23_UP} - {$DEFINE DELPHI22_UP} - {$DEFINE DELPHI21_UP} - {$DEFINE DELPHI20_UP} - {$DEFINE DELPHI19_UP} - {$DEFINE DELPHI18_UP} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI10_SEATTLE} - {$DEFINE DELPHI10_SEATTLE_UP} - {$DEFINE DELPHIXE8_UP} - {$DEFINE DELPHIXE7_UP} - {$DEFINE DELPHIXE6_UP} - {$DEFINE DELPHIXE5_UP} - {$DEFINE DELPHIXE4_UP} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} - - // NO DELPHI2014 defined, so need define below here. - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI22} - {$DEFINE DELPHI} - {$DEFINE DELPHI22_UP} - {$DEFINE DELPHI21_UP} - {$DEFINE DELPHI20_UP} - {$DEFINE DELPHI19_UP} - {$DEFINE DELPHI18_UP} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHIXE8} - {$DEFINE DELPHIXE8_UP} - {$DEFINE DELPHIXE7_UP} - {$DEFINE DELPHIXE6_UP} - {$DEFINE DELPHIXE5_UP} - {$DEFINE DELPHIXE4_UP} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} - - // NO DELPHI2014 defined, so need define below here. - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI21} - {$DEFINE DELPHI} - {$DEFINE DELPHI21_UP} - {$DEFINE DELPHI20_UP} - {$DEFINE DELPHI19_UP} - {$DEFINE DELPHI18_UP} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHIXE7} - {$DEFINE DELPHIXE7_UP} - {$DEFINE DELPHIXE6_UP} - {$DEFINE DELPHIXE5_UP} - {$DEFINE DELPHIXE4_UP} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} - - // NO DELPHI2014 defined, so need define below here. - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI20} - {$DEFINE DELPHI} - {$DEFINE DELPHI20_UP} - {$DEFINE DELPHI19_UP} - {$DEFINE DELPHI18_UP} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHIXE6} - {$DEFINE DELPHIXE6_UP} - {$DEFINE DELPHIXE5_UP} - {$DEFINE DELPHIXE4_UP} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} - - // NO DELPHI2014 defined, so need define below here. - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI19} - {$DEFINE DELPHI} - {$DEFINE DELPHI19_UP} - {$DEFINE DELPHI18_UP} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHIXE5} - {$DEFINE DELPHIXE5_UP} - {$DEFINE DELPHIXE4_UP} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} - - // NO DELPHI2014 defined, so need define below here. - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI18} - {$DEFINE DELPHI} - {$DEFINE DELPHI18_UP} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHIXE4} - {$DEFINE DELPHIXE4_UP} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} - - // NO DELPHI2014 defined, so need define below here. - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI17} - {$DEFINE DELPHI} - {$DEFINE DELPHI17_UP} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHIXE3} - {$DEFINE DELPHIXE3_UP} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} -{$ENDIF} - -{$IFDEF DELPHI2013} - {$DEFINE DELPHI2013_UP} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI16} - {$DEFINE DELPHI} - {$DEFINE DELPHI16_UP} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHIXE2} - {$DEFINE DELPHIXE2_UP} - {$DEFINE DELPHIXE_UP} -{$ENDIF} - -{$IFDEF DELPHI2012} - {$DEFINE DELPHI2012_UP} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI15} - {$DEFINE DELPHI} - {$DEFINE DELPHI15_UP} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHIXE} - {$DEFINE DELPHIXE_UP} -{$ENDIF} - -{$IFDEF DELPHI2011} - {$DEFINE DELPHI2011_UP} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI14} - {$DEFINE DELPHI} - {$DEFINE DELPHI14_UP} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI2010} - {$DEFINE DELPHI2010_UP} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI12} - {$DEFINE DELPHI} - {$DEFINE DELPHI12_UP} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI2009} - {$DEFINE DELPHI2009_UP} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI11} - {$DEFINE DELPHI} - {$DEFINE DELPHI11_UP} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI2007} - {$DEFINE DELPHI2007_UP} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI10} - {$DEFINE DELPHI} - {$DEFINE DELPHI10_UP} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI2006} - {$DEFINE DELPHI2006_UP} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI9} - {$DEFINE DELPHI} - {$DEFINE DELPHI9_UP} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI2005} - {$DEFINE DELPHI2005_UP} -{$ENDIF} - -{$IFDEF DELPHI8} - {$DEFINE DELPHI} - {$DEFINE DELPHI8_UP} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI7} - {$DEFINE DELPHI} - {$DEFINE DELPHI7_UP} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI6} - {$DEFINE DELPHI} - {$DEFINE DELPHI6_UP} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI5} - {$DEFINE DELPHI} - {$DEFINE DELPHI5_UP} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI4} - {$DEFINE DELPHI} - {$DEFINE DELPHI4_UP} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI3} - {$DEFINE DELPHI} - {$DEFINE DELPHI3_UP} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI2} - {$DEFINE DELPHI} - {$DEFINE DELPHI2_UP} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -{$IFDEF DELPHI1} - {$DEFINE DELPHI} - {$DEFINE DELPHI1_UP} -{$ENDIF} - -// BCBX_UP from BCBX mappings - -{$IFDEF BCB29} - {$DEFINE BCB} - {$DEFINE BCB29_UP} - {$DEFINE BCB28_UP} - {$DEFINE BCB27_UP} - {$DEFINE BCB26_UP} - {$DEFINE BCB25_UP} - {$DEFINE BCB24_UP} - {$DEFINE BCB23_UP} - {$DEFINE BCB22_UP} - {$DEFINE BCB21_UP} - {$DEFINE BCB20_UP} - {$DEFINE BCB19_UP} - {$DEFINE BCB18_UP} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB120_ATHENS} - {$DEFINE BCB120_ATHENS_UP} - {$DEFINE BCB110_ALEXANDRIA_UP} - {$DEFINE BCB104_SYDNEY_UP} - {$DEFINE BCB103_RIO_UP} - {$DEFINE BCB102_TOKYO_UP} - {$DEFINE BCB101_BERLIN_UP} - {$DEFINE BCB10_SEATTLE_UP} - {$DEFINE BCBXE8_UP} - {$DEFINE BCBXE7_UP} - {$DEFINE BCBXE6_UP} - {$DEFINE BCBXE5_UP} - {$DEFINE BCBXE4_UP} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} - - // NO BCB2014 defined, so need define below here. - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB28} - {$DEFINE BCB} - {$DEFINE BCB28_UP} - {$DEFINE BCB27_UP} - {$DEFINE BCB26_UP} - {$DEFINE BCB25_UP} - {$DEFINE BCB24_UP} - {$DEFINE BCB23_UP} - {$DEFINE BCB22_UP} - {$DEFINE BCB21_UP} - {$DEFINE BCB20_UP} - {$DEFINE BCB19_UP} - {$DEFINE BCB18_UP} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB110_ALEXANDRIA} - {$DEFINE BCB110_ALEXANDRIA_UP} - {$DEFINE BCB104_SYDNEY_UP} - {$DEFINE BCB103_RIO_UP} - {$DEFINE BCB102_TOKYO_UP} - {$DEFINE BCB101_BERLIN_UP} - {$DEFINE BCB10_SEATTLE_UP} - {$DEFINE BCBXE8_UP} - {$DEFINE BCBXE7_UP} - {$DEFINE BCBXE6_UP} - {$DEFINE BCBXE5_UP} - {$DEFINE BCBXE4_UP} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} - - // NO BCB2014 defined, so need define below here. - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB27} - {$DEFINE BCB} - {$DEFINE BCB27_UP} - {$DEFINE BCB26_UP} - {$DEFINE BCB25_UP} - {$DEFINE BCB24_UP} - {$DEFINE BCB23_UP} - {$DEFINE BCB22_UP} - {$DEFINE BCB21_UP} - {$DEFINE BCB20_UP} - {$DEFINE BCB19_UP} - {$DEFINE BCB18_UP} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB104_SYDNEY} - {$DEFINE BCB104_SYDNEY_UP} - {$DEFINE BCB103_RIO_UP} - {$DEFINE BCB102_TOKYO_UP} - {$DEFINE BCB101_BERLIN_UP} - {$DEFINE BCB10_SEATTLE_UP} - {$DEFINE BCBXE8_UP} - {$DEFINE BCBXE7_UP} - {$DEFINE BCBXE6_UP} - {$DEFINE BCBXE5_UP} - {$DEFINE BCBXE4_UP} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} - - // NO BCB2014 defined, so need define below here. - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB26} - {$DEFINE BCB} - {$DEFINE BCB26_UP} - {$DEFINE BCB25_UP} - {$DEFINE BCB24_UP} - {$DEFINE BCB23_UP} - {$DEFINE BCB22_UP} - {$DEFINE BCB21_UP} - {$DEFINE BCB20_UP} - {$DEFINE BCB19_UP} - {$DEFINE BCB18_UP} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB103_RIO} - {$DEFINE BCB103_RIO_UP} - {$DEFINE BCB102_TOKYO_UP} - {$DEFINE BCB101_BERLIN_UP} - {$DEFINE BCB10_SEATTLE_UP} - {$DEFINE BCBXE8_UP} - {$DEFINE BCBXE7_UP} - {$DEFINE BCBXE6_UP} - {$DEFINE BCBXE5_UP} - {$DEFINE BCBXE4_UP} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} - - // NO BCB2014 defined, so need define below here. - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB25} - {$DEFINE BCB} - {$DEFINE BCB25_UP} - {$DEFINE BCB24_UP} - {$DEFINE BCB23_UP} - {$DEFINE BCB22_UP} - {$DEFINE BCB21_UP} - {$DEFINE BCB20_UP} - {$DEFINE BCB19_UP} - {$DEFINE BCB18_UP} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB102_TOKYO} - {$DEFINE BCB102_TOKYO_UP} - {$DEFINE BCB101_BERLIN_UP} - {$DEFINE BCB10_SEATTLE_UP} - {$DEFINE BCBXE8_UP} - {$DEFINE BCBXE7_UP} - {$DEFINE BCBXE6_UP} - {$DEFINE BCBXE5_UP} - {$DEFINE BCBXE4_UP} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} - - // NO BCB2014 defined, so need define below here. - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - - -{$IFDEF BCB24} - {$DEFINE BCB} - {$DEFINE BCB24_UP} - {$DEFINE BCB23_UP} - {$DEFINE BCB22_UP} - {$DEFINE BCB21_UP} - {$DEFINE BCB20_UP} - {$DEFINE BCB19_UP} - {$DEFINE BCB18_UP} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB101_BERLIN} - {$DEFINE BCB101_BERLIN_UP} - {$DEFINE BCB10_SEATTLE_UP} - {$DEFINE BCBXE8_UP} - {$DEFINE BCBXE7_UP} - {$DEFINE BCBXE6_UP} - {$DEFINE BCBXE5_UP} - {$DEFINE BCBXE4_UP} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} - - // NO BCB2014 defined, so need define below here. - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB23} - {$DEFINE BCB} - {$DEFINE BCB23_UP} - {$DEFINE BCB22_UP} - {$DEFINE BCB21_UP} - {$DEFINE BCB20_UP} - {$DEFINE BCB19_UP} - {$DEFINE BCB18_UP} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB10_SEATTLE} - {$DEFINE BCB10_SEATTLE_UP} - {$DEFINE BCBXE8_UP} - {$DEFINE BCBXE7_UP} - {$DEFINE BCBXE6_UP} - {$DEFINE BCBXE5_UP} - {$DEFINE BCBXE4_UP} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} - - // NO BCB2014 defined, so need define below here. - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB22} - {$DEFINE BCB} - {$DEFINE BCB22_UP} - {$DEFINE BCB21_UP} - {$DEFINE BCB20_UP} - {$DEFINE BCB19_UP} - {$DEFINE BCB18_UP} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCBXE8} - {$DEFINE BCBXE8_UP} - {$DEFINE BCBXE7_UP} - {$DEFINE BCBXE6_UP} - {$DEFINE BCBXE5_UP} - {$DEFINE BCBXE4_UP} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} - - // NO BCB2014 defined, so need define below here. - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB21} - {$DEFINE BCB} - {$DEFINE BCB21_UP} - {$DEFINE BCB20_UP} - {$DEFINE BCB19_UP} - {$DEFINE BCB18_UP} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCBXE7} - {$DEFINE BCBXE7_UP} - {$DEFINE BCBXE6_UP} - {$DEFINE BCBXE5_UP} - {$DEFINE BCBXE4_UP} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} - - // NO BCB2014 defined, so need define below here. - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB20} - {$DEFINE BCB} - {$DEFINE BCB20_UP} - {$DEFINE BCB19_UP} - {$DEFINE BCB18_UP} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCBXE6} - {$DEFINE BCBXE6_UP} - {$DEFINE BCBXE5_UP} - {$DEFINE BCBXE4_UP} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} - - // NO BCB2014 defined, so need define below here. - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB19} - {$DEFINE BCB} - {$DEFINE BCB19_UP} - {$DEFINE BCB18_UP} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCBXE5} - {$DEFINE BCBXE5_UP} - {$DEFINE BCBXE4_UP} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} - - // NO BCB2014 defined, so need define below here. - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB18} - {$DEFINE BCB} - {$DEFINE BCB18_UP} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCBXE4} - {$DEFINE BCBXE4_UP} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} - - // NO BCB2014 defined, so need define below here. - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB17} - {$DEFINE BCB} - {$DEFINE BCB17_UP} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCBXE3} - {$DEFINE BCBXE3_UP} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} -{$ENDIF} - -{$IFDEF BCB2013} - {$DEFINE BCB2013_UP} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB16} - {$DEFINE BCB} - {$DEFINE BCB16_UP} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCBXE2} - {$DEFINE BCBXE2_UP} - {$DEFINE BCBXE_UP} -{$ENDIF} - -{$IFDEF BCB2012} - {$DEFINE BCB2012_UP} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB15} - {$DEFINE BCB} - {$DEFINE BCB15_UP} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCBXE} - {$DEFINE BCBXE_UP} -{$ENDIF} - -{$IFDEF BCB2011} - {$DEFINE BCB2011_UP} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB14} - {$DEFINE BCB} - {$DEFINE BCB14_UP} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB2010} - {$DEFINE BCB2010_UP} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB12} - {$DEFINE BCB} - {$DEFINE BCB12_UP} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB2009} - {$DEFINE BCB2009_UP} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB11} - {$DEFINE BCB} - {$DEFINE BCB11_UP} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB2007} - {$DEFINE BCB2007_UP} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB10} - {$DEFINE BCB} - {$DEFINE BCB10_UP} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB2006} - {$DEFINE BCB2006_UP} -{$ENDIF} - -{$IFDEF BCB7} - {$DEFINE BCB} - {$DEFINE BCB7_UP} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB6} - {$DEFINE BCB} - {$DEFINE BCB6_UP} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB5} - {$DEFINE BCB} - {$DEFINE BCB5_UP} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB4} - {$DEFINE BCB} - {$DEFINE BCB4_UP} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB3} - {$DEFINE BCB} - {$DEFINE BCB3_UP} - {$DEFINE BCB1_UP} -{$ENDIF} - -{$IFDEF BCB1} - {$DEFINE BCB} - {$DEFINE BCB1_UP} -{$ENDIF} - -// KYLIXX_UP from KYLIXX mappings - -{$IFDEF KYLIX3} - {$DEFINE KYLIX} - {$DEFINE KYLIX3_UP} - {$DEFINE KYLIX2_UP} - {$DEFINE KYLIX1_UP} -{$ENDIF} - -{$IFDEF KYLIX2} - {$DEFINE KYLIX} - {$DEFINE KYLIX2_UP} - {$DEFINE KYLIX1_UP} -{$ENDIF} - -{$IFDEF KYLIX1} - {$DEFINE KYLIX} - {$DEFINE KYLIX1_UP} -{$ENDIF} - -// BDSXX_UP from BDSXX mappings - -{$IFDEF BDS23} // 12.0 ATHENS - {$DEFINE BDS} - {$DEFINE BDS23_UP} - {$DEFINE BDS22_UP} - {$DEFINE BDS21_UP} - {$DEFINE BDS20_UP} - {$DEFINE BDS19_UP} - {$DEFINE BDS18_UP} - {$DEFINE BDS17_UP} - {$DEFINE BDS16_UP} - {$DEFINE BDS15_UP} - {$DEFINE BDS14_UP} - {$DEFINE BDS12_UP} - {$DEFINE BDS11_UP} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} - - // NO BDS2014 defined, so need define below here. - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS22} // 11.0 ALEXANDRIA - {$DEFINE BDS} - {$DEFINE BDS22_UP} - {$DEFINE BDS21_UP} - {$DEFINE BDS20_UP} - {$DEFINE BDS19_UP} - {$DEFINE BDS18_UP} - {$DEFINE BDS17_UP} - {$DEFINE BDS16_UP} - {$DEFINE BDS15_UP} - {$DEFINE BDS14_UP} - {$DEFINE BDS12_UP} - {$DEFINE BDS11_UP} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} - - // NO BDS2014 defined, so need define below here. - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS21} // 10.4 SYDNEY - {$DEFINE BDS} - {$DEFINE BDS21_UP} - {$DEFINE BDS20_UP} - {$DEFINE BDS19_UP} - {$DEFINE BDS18_UP} - {$DEFINE BDS17_UP} - {$DEFINE BDS16_UP} - {$DEFINE BDS15_UP} - {$DEFINE BDS14_UP} - {$DEFINE BDS12_UP} - {$DEFINE BDS11_UP} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} - - // NO BDS2014 defined, so need define below here. - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS20} // 10.3 RIO - {$DEFINE BDS} - {$DEFINE BDS20_UP} - {$DEFINE BDS19_UP} - {$DEFINE BDS18_UP} - {$DEFINE BDS17_UP} - {$DEFINE BDS16_UP} - {$DEFINE BDS15_UP} - {$DEFINE BDS14_UP} - {$DEFINE BDS12_UP} - {$DEFINE BDS11_UP} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} - - // NO BDS2014 defined, so need define below here. - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS19} // 10.2 Tokyo - {$DEFINE BDS} - {$DEFINE BDS19_UP} - {$DEFINE BDS18_UP} - {$DEFINE BDS17_UP} - {$DEFINE BDS16_UP} - {$DEFINE BDS15_UP} - {$DEFINE BDS14_UP} - {$DEFINE BDS12_UP} - {$DEFINE BDS11_UP} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} - - // NO BDS2014 defined, so need define below here. - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS18} // 10.1 Berlin - {$DEFINE BDS} - {$DEFINE BDS18_UP} - {$DEFINE BDS17_UP} - {$DEFINE BDS16_UP} - {$DEFINE BDS15_UP} - {$DEFINE BDS14_UP} - {$DEFINE BDS12_UP} - {$DEFINE BDS11_UP} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} - - // NO BDS2014 defined, so need define below here. - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS17} // 10 Seattle - {$DEFINE BDS} - {$DEFINE BDS17_UP} - {$DEFINE BDS16_UP} - {$DEFINE BDS15_UP} - {$DEFINE BDS14_UP} - {$DEFINE BDS12_UP} - {$DEFINE BDS11_UP} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} - - // NO BDS2014 defined, so need define below here. - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS16} - {$DEFINE BDS} - {$DEFINE BDS16_UP} - {$DEFINE BDS15_UP} - {$DEFINE BDS14_UP} - {$DEFINE BDS12_UP} - {$DEFINE BDS11_UP} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} - - // NO BDS2014 defined, so need define below here. - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS15} - {$DEFINE BDS} - {$DEFINE BDS15_UP} - {$DEFINE BDS14_UP} - {$DEFINE BDS12_UP} - {$DEFINE BDS11_UP} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} - - // NO BDS2014 defined, so need define below here. - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS14} - {$DEFINE BDS} - {$DEFINE BDS14_UP} - {$DEFINE BDS12_UP} - {$DEFINE BDS11_UP} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} - - // NO BDS2014 defined, so need define below here. - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS12} - {$DEFINE BDS} - {$DEFINE BDS12_UP} - {$DEFINE BDS11_UP} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} - - // NO BDS2014 defined, so need define below here. - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS11} - {$DEFINE BDS} - {$DEFINE BDS11_UP} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} - - // NO BDS2014 defined, so need define below here. - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS10} - {$DEFINE BDS} - {$DEFINE BDS10_UP} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} -{$ENDIF} - -{$IFDEF BDS2013} - {$DEFINE BDS2013_UP} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS9} - {$DEFINE BDS} - {$DEFINE BDS9_UP} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} -{$ENDIF} - -{$IFDEF BDS2012} - {$DEFINE BDS2012_UP} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS8} - {$DEFINE BDS} - {$DEFINE BDS8_UP} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} -{$ENDIF} - -{$IFDEF BDS2011} - {$DEFINE BDS2011_UP} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS7} - {$DEFINE BDS} - {$DEFINE BDS7_UP} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} -{$ENDIF} - -{$IFDEF BDS2010} - {$DEFINE BDS2010_UP} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS6} - {$DEFINE BDS} - {$DEFINE BDS6_UP} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} -{$ENDIF} - -{$IFDEF BDS2009} - {$DEFINE BDS2009_UP} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS5} - {$DEFINE BDS} - {$DEFINE BDS5_UP} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} -{$ENDIF} - -{$IFDEF BDS2007} - {$DEFINE BDS2007_UP} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS4} - {$DEFINE BDS} - {$DEFINE BDS4_UP} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} -{$ENDIF} - -{$IFDEF BDS2006} - {$DEFINE BDS2006_UP} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS3} - {$DEFINE BDS} - {$DEFINE BDS3_UP} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} -{$ENDIF} - -{$IFDEF BDS2005} - {$DEFINE BDS2005_UP} -{$ENDIF} - -{$IFDEF BDS2} - {$DEFINE BDS} - {$DEFINE BDS2_UP} - {$DEFINE BDS1_UP} -{$ENDIF} - -{$IFDEF BDS1} - {$DEFINE BDS} - {$DEFINE BDS1_UP} -{$ENDIF} - -// COMPILERX_UP from COMPILERX mappings - -{$IFDEF COMPILER29} // 12.0 ATHENS - {$DEFINE COMPILER29_UP} - {$DEFINE COMPILER28_UP} - {$DEFINE COMPILER27_UP} - {$DEFINE COMPILER26_UP} - {$DEFINE COMPILER25_UP} - {$DEFINE COMPILER24_UP} - {$DEFINE COMPILER23_UP} - {$DEFINE COMPILER22_UP} - {$DEFINE COMPILER21_UP} - {$DEFINE COMPILER20_UP} - {$DEFINE COMPILER19_UP} - {$DEFINE COMPILER18_UP} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER28} // 11.0 ALEXANDRIA - {$DEFINE COMPILER28_UP} - {$DEFINE COMPILER27_UP} - {$DEFINE COMPILER26_UP} - {$DEFINE COMPILER25_UP} - {$DEFINE COMPILER24_UP} - {$DEFINE COMPILER23_UP} - {$DEFINE COMPILER22_UP} - {$DEFINE COMPILER21_UP} - {$DEFINE COMPILER20_UP} - {$DEFINE COMPILER19_UP} - {$DEFINE COMPILER18_UP} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER27} // 10.4 SYDNEY - {$DEFINE COMPILER27_UP} - {$DEFINE COMPILER26_UP} - {$DEFINE COMPILER25_UP} - {$DEFINE COMPILER24_UP} - {$DEFINE COMPILER23_UP} - {$DEFINE COMPILER22_UP} - {$DEFINE COMPILER21_UP} - {$DEFINE COMPILER20_UP} - {$DEFINE COMPILER19_UP} - {$DEFINE COMPILER18_UP} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER26} // 10.3 RIO - {$DEFINE COMPILER26_UP} - {$DEFINE COMPILER25_UP} - {$DEFINE COMPILER24_UP} - {$DEFINE COMPILER23_UP} - {$DEFINE COMPILER22_UP} - {$DEFINE COMPILER21_UP} - {$DEFINE COMPILER20_UP} - {$DEFINE COMPILER19_UP} - {$DEFINE COMPILER18_UP} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER25} // 10.2 Tokyo - {$DEFINE COMPILER25_UP} - {$DEFINE COMPILER24_UP} - {$DEFINE COMPILER23_UP} - {$DEFINE COMPILER22_UP} - {$DEFINE COMPILER21_UP} - {$DEFINE COMPILER20_UP} - {$DEFINE COMPILER19_UP} - {$DEFINE COMPILER18_UP} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER24} // 10.1 Berlin - {$DEFINE COMPILER24_UP} - {$DEFINE COMPILER23_UP} - {$DEFINE COMPILER22_UP} - {$DEFINE COMPILER21_UP} - {$DEFINE COMPILER20_UP} - {$DEFINE COMPILER19_UP} - {$DEFINE COMPILER18_UP} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER23} // 10 Seattle - {$DEFINE COMPILER23_UP} - {$DEFINE COMPILER22_UP} - {$DEFINE COMPILER21_UP} - {$DEFINE COMPILER20_UP} - {$DEFINE COMPILER19_UP} - {$DEFINE COMPILER18_UP} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER22} - {$DEFINE COMPILER22_UP} - {$DEFINE COMPILER21_UP} - {$DEFINE COMPILER20_UP} - {$DEFINE COMPILER19_UP} - {$DEFINE COMPILER18_UP} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER21} - {$DEFINE COMPILER21_UP} - {$DEFINE COMPILER20_UP} - {$DEFINE COMPILER19_UP} - {$DEFINE COMPILER18_UP} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER20} - {$DEFINE COMPILER20_UP} - {$DEFINE COMPILER19_UP} - {$DEFINE COMPILER18_UP} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER19} - {$DEFINE COMPILER19_UP} - {$DEFINE COMPILER18_UP} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER18} - {$DEFINE COMPILER18_UP} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER17} - {$DEFINE COMPILER17_UP} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER16} - {$DEFINE COMPILER16_UP} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER15} - {$DEFINE COMPILER15_UP} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER14} - {$DEFINE COMPILER14_UP} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER12} - {$DEFINE COMPILER12_UP} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER11} - {$DEFINE COMPILER11_UP} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER10} - {$DEFINE COMPILER10_UP} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER9} - {$DEFINE COMPILER9_UP} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER8} - {$DEFINE COMPILER8_UP} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER7} - {$DEFINE COMPILER7_UP} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER6} - {$DEFINE COMPILER6_UP} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER5} - {$DEFINE COMPILER5_UP} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER4} - {$DEFINE COMPILER4_UP} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER35} - {$DEFINE COMPILER35_UP} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER3} - {$DEFINE COMPILER3_UP} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER2} - {$DEFINE COMPILER2_UP} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -{$IFDEF COMPILER1} - {$DEFINE COMPILER1_UP} -{$ENDIF} - -// VCLXX_UP from VCLXX mappings - -{$IFDEF UCL10} - {$DEFINE UCL10_UP} -{$ENDIF} - -{$IFDEF VCL71} - {$DEFINE VCL71_UP} - {$DEFINE VCL70_UP} - {$DEFINE VCL60_UP} - {$DEFINE VCL50_UP} - {$DEFINE VCL40_UP} - {$DEFINE VCL30_UP} - {$DEFINE VCL20_UP} - {$DEFINE VCL10_UP} -{$ENDIF} - -{$IFDEF VCL70} - {$DEFINE VCL70_UP} - {$DEFINE VCL60_UP} - {$DEFINE VCL50_UP} - {$DEFINE VCL40_UP} - {$DEFINE VCL30_UP} - {$DEFINE VCL20_UP} - {$DEFINE VCL10_UP} -{$ENDIF} - -{$IFDEF VCL60} - {$DEFINE VCL60_UP} - {$DEFINE VCL50_UP} - {$DEFINE VCL40_UP} - {$DEFINE VCL30_UP} - {$DEFINE VCL20_UP} - {$DEFINE VCL10_UP} -{$ENDIF} - -{$IFDEF VCL50} - {$DEFINE VCL50_UP} - {$DEFINE VCL40_UP} - {$DEFINE VCL30_UP} - {$DEFINE VCL20_UP} - {$DEFINE VCL10_UP} -{$ENDIF} - -{$IFDEF VCL40} - {$DEFINE VCL40_UP} - {$DEFINE VCL30_UP} - {$DEFINE VCL20_UP} - {$DEFINE VCL10_UP} -{$ENDIF} - -{$IFDEF VCL30} - {$DEFINE VCL30_UP} - {$DEFINE VCL20_UP} - {$DEFINE VCL10_UP} -{$ENDIF} - -{$IFDEF VCL20} - {$DEFINE VCL20_UP} - {$DEFINE VCL10_UP} -{$ENDIF} - -{$IFDEF VCL10} - {$DEFINE VCL10_UP} -{$ENDIF} - -// CLXXX_UP from CLXXX mappings - -{$IFDEF CLX10} - {$DEFINE CLX10_UP} -{$ENDIF} - -//============================================================================== -// ƽ̨ض -//============================================================================== - -{$IFDEF COMPILER1} - {$DEFINE WIN16} - {$DEFINE MSWINDOWS} -{$ENDIF} - -{$IFDEF BDS} - {$DEFINE DOTNET} -{$ENDIF} - -{$IFDEF WIN32} - {$DEFINE MSWINDOWS} -{$ENDIF} - -{$IFDEF LINUX} - {$DEFINE UNIX} - {$DEFINE COMPLIB_CLX} -{$ENDIF} - -{$IFNDEF COMPLIB_CLX} - {$DEFINE COMPLIB_VCL} -{$ENDIF} - -//============================================================================== -// ӳ汾ϢѺõָ -//============================================================================== - -{$IFDEF DELPHI} - {$DEFINE SUPPORT_PASCAL} -{$ENDIF} - -{$IFDEF BCB} - {$DEFINE SUPPORT_PASCAL} - {$DEFINE SUPPORT_CPLUSPLUS} -{$ENDIF} - -{$IFDEF DELPHI120_ATHENS_UP} - {$DEFINE LIST_INDEX_NATIVEINT} // Athens 12 TList use NativeInt for Index and Count instead of Integer - {$DEFINE IDE_HAS_TABMENU_COPY_PATH} // Athens 12 editor tab menu has item to copy path or filename - {$DEFINE IDE_HAS_DBCLICK_HIGHLIGHT} // Athens 12 editor double click selection highlight - {$DEFINE OTA_CODEEDITOR_SERVICE} // 11.3 ToolsAPI.Editor ӿڣʱ޷ 11.0/1/2 ֻ֣ܼӵ 12 -{$ENDIF} - -{$IFDEF DELPHI110_ALEXANDRIA_UP} - {$DEFINE NO_OLDCREATEORDER} // Alexandria 11 removed OldCreateOrder - {$DEFINE IDE_SUPPORT_HDPI} // Alexandria 11 supports HDPI using TVirtualImageList, etc. - {$DEFINE IDE_HAS_AUTO_READONLY} // Alexandria 11 supports auto open VCL source readonly - {$DEFINE IDE_HAS_MEMORY_VISUALIZAER} // Alexandria 11 has Memory Visualizer for Debug - {$DEFINE TSTRINGS_SETTEXTSTR_CANNULL} // Alexandria 11 TStrings.SetTextStr Ignore #0 Terminated Char - {$DEFINE MEMORYSTREAM_CAPACITY_NATIVEINT} // Alexandria 11 TMemoryStream Capacity is NativeInt instead of Longint -{$ENDIF} - -{$IFDEF DELPHI104_SYDNEY_UP} - {$DEFINE IDE_SUPPORT_LSP} // Sydney 10.4 ֧ LSP Է - {$DEFINE IDE_HAS_ERRORINSIGHT} // Sydney 10.4.2 ֱ֧༭ ErrorInsight - {$DEFINE IDE_EDITOR_CUSTOM_COLUMN} // Sydney 10.4 ϱ༭ Gutter ֧Զ壬ûӿڲݣԼ - {$DEFINE IDE_SWITCH_BUG} // Sydney 10.4.2 ڴļʱĪл̨ Bug -{$ENDIF} - -{$IFDEF DELPHI103_RIO_UP} - {$DEFINE SUPPORT_MACOS64} // Rio 10.3.2 ֧ 64 λ MacOS -{$ENDIF} - -{$IFDEF DELPHI102_TOKYO_UP} - {$DEFINE SUPPORT_LINUX64} // Tokyo 10.2 ֧ Linux 64 λ Server - {$DEFINE IDE_SUPPORT_THEMING} // Tokyo 10.2.2 ֧ IDE л -{$ENDIF} - -{$IFDEF DELPHI101_BERLIN_UP} - {$DEFINE IDE_NEW_EMBEDDED_DESIGNER} // 101B Re-opens "Embedded Designer" Option and Gives a New Container. -{$ENDIF} - -{$IFDEF DELPHI10_SEATTLE_UP} - {$DEFINE IDE_HAS_OWN_STRUCTUAL_HIGHLIGHT} // 10S has own Structual Highlight - {$DEFINE IDE_HAS_HIDE_NONVISUAL} // 10S has "Hide Nonvisual" Feature. -{$ENDIF} - -{$IFDEF DELPHIXE8_UP} - {$DEFINE INIFILE_READWRITE_INTEGER} // XE8 IniFile ReadInteger WriteInteger ʼ LongInt Ϊ Integer - {$DEFINE IDE_INTEGRATE_CASTALIA} // XE8/10S and above integrate Castalia. -{$ENDIF} - -{$IFDEF COMPILER21_UP} // COMPILER21 = XE7 - {$DEFINE NOT_SUPPORT_BDE} // BDE -{$ENDIF} - -{$IFDEF DELPHIXE7_UP} - {$DEFINE SUPPORT_TBYTES_OPERATION} // XE7 TBytes ʼ֧ӡȲ - {$DEFINE FMX_CONTROL_HAS_SIZE} // XE7 FMX Control Size -{$ENDIF} - -{$IFDEF DELPHIXE6_UP} - {$DEFINE SUPPORT_JSON} // XE6 System.JSON ⣬ DBX/REST -{$ENDIF} - -{$IFDEF DELPHIXE5_UP} - {$DEFINE SUPPORT_MOBILE} // XE5 ʼ֧ƶ - {$DEFINE IDE_HAS_INSIGHT} // XE5 has IDE Insight Bar -{$ENDIF} - -{$IFDEF DELPHIXE4_UP} - {$IFNDEF DISABLE_FMX} - {$DEFINE SUPPORT_FMX_FRAME} // XE4 FMX Supports FMX Frame - {$ENDIF} -{$ELSE} - {$DEFINE MEMO_CARETPOS_BUG} // Memo CaretPos Get Negative Error Value for Large File under XE3 or below -{$ENDIF} - -{$IFDEF DELPHIXE3_UP} - {$DEFINE SUPPORT_ATOMIC} // XE3 has Atomic Routines - {$DEFINE TCONTROL_HAS_STYLEELEMENTS} // XE3 TControl has StyleElements Property - {$DEFINE IDE_NP_FMX_DESIGN_BUG} // XE3 FMX Designer Cut/Copy/Paste cause AV Bug for -np switch -{$ENDIF} - -{$IFDEF DELPHIXE2_UP} - {$DEFINE SUPPORT_WIN64} // XE2 Supports Win64 - {$DEFINE SUPPORT_MACOS32} // XE2 Supports MacOS 32 - {$DEFINE SUPPORT_UNITNAME_DOT} - {$DEFINE SUPPORT_ENHANCED_INDEXEDPROPERTY} // XE2 New RTTI Supports IndexedProperty - {$DEFINE SUPPORT_ZLIB_WINDOWBITS} // XE2 ZLib Supports WindowBits - {$DEFINE SUPPORT_GDIPLUS} // XE2 Supports GDI+ - {$DEFINE SUPPORT_INT64ARRAY} // XE2 Defined Int64Array - {$DEFINE SUPPORT_ALPHACOLOR} // XE2 System.UITypes Has TAlphaColors -{$ENDIF} - -{$IFDEF DELPHIXE_UP} - {$DEFINE TSTRINGS_HAS_WRITEBOM} // XE TStrings has WriteBOM property. - {$DEFINE IDE_HAS_DEBUGGERVISUALIZER} // XE ToolsAPI has Debugger Visualizer Interfaces. - {$DEFINE IDE_HAS_STRINGS_VISUALIZAER} // XE has TStrings Visualizer for Debug -{$ENDIF} - -{$IFDEF BDS2012_UP} // 2012 = XE2 - {$DEFINE SUPPORT_32_AND_64} // XE2 Support Win32 and Win64 - {$IFNDEF DISABLE_FMX} - {$DEFINE SUPPORT_FMX} - {$ENDIF} - {$DEFINE SUPPORT_CROSS_PLATFORM} // XE2 ֿ֧ƽ̨ - {$DEFINE VERSIONINFO_PER_CONFIGURATION} // Every Configuruation can have a Version Info. - {$DEFINE OTA_ENVOPTIONS_PLATFORM_BUG} - // A Bug Can't get Correct Env Option Values for Current Platform. - {$DEFINE LIST_NEW_POINTER} -{$ENDIF} - -{$IFDEF BDS2010_UP} - {$DEFINE SUPPORT_INTERFACE_AS_OBJECT} - {$DEFINE SUPPORT_ENHANCED_RTTI} // New enhanced RTTI. - {$DEFINE SUPPORT_EXTERNAL_DELAYED} // External functions can be declared as 'delayed'. - {$DEFINE SUPPORT_CLASS_CONSTRUCTOR} // 2010 and above Supports class constructor and destructor - {$DEFINE SUPPORT_CLASS_DESTRUCTOR} - {$DEFINE IMAGELIST_BEGINENDUPDATE} // 2010 ʼImageList й BeginUpdate EndUpdate - {$DEFINE OTA_DEBUG_HAS_EVENTS} // 2010 µ DebuggerService ProcessDebugEvents - {$DEFINE IDE_HAS_NEW_COMPONENT_PALETTE} // IDE has a new style Component Palette. - {$DEFINE IDE_HAS_EDITOR_SEARCHPANEL} // Editor has a Search Panel - {$DEFINE IDE_HAS_DATETIME_HINT} // TDate/TTime/TDateTime shows Normally in Debug Hint -{$ENDIF} - -{$IFDEF BDS2010} - // 2010 EditView CursorPos EditPosition.InsertText ƫ - {$DEFINE EDITVIEW_SETCURSORPOS_BUG} -{$ENDIF} - -{$IFDEF BDS2009_UP} - {$DEFINE UNICODE_STRING} - {$DEFINE SUPPORT_ATTRIBUTE} // ֧ Attribute - {$DEFINE SUPPORT_GENERIC} // ַ֧ - {$DEFINE SUPPORT_ANSISTRING_CODEPAGE} // AnsiString ָ֧ҳ - {$DEFINE SUPPORT_ENCODING} // Unicode with TEncoding - {$DEFINE SUPPORT_PUINT64} // Has Pointer of UInt64 - {$DEFINE OBJECT_HAS_TOSTRING} // TObject.ToString Function - {$DEFINE OBJECT_HAS_EQUAL} // TObject.Equal Function - {$DEFINE OBJECT_HAS_GETHASHCODE} // TObject.GetHashCode Function - {$DEFINE TGRAPHIC_SUPPORT_PARTIALTRANSPARENCY} // TGraphic ֧ Alpha ͨ͸ - {$DEFINE SUPPORT_OTA_PROJECT_CONFIGURATION} - - {$DEFINE IDE_MAINFORM_EAT_MOUSEWHEEL} - // MainForm of 2009 or Above will eat Message in MouseWheelHandler - {$DEFINE IDE_CODEINSIGHT_AUTOINVOKE} - // IDE Code Insight has Auto Invoke Option - {$DEFINE EDITVIEW_CONVERTPOS_BUG} - // 2009 or Above IEditView.ConvertPos Incorrect when Meeting Unicode Chars. - - {$IFNDEF DELPHIXE2_UP} // 2009/2010/XE has a Project Version Number Bug. - {$DEFINE PROJECT_VERSION_NUMBER_BUG} - {$ENDIF} - {$DEFINE OTA_DPKOPTION_SETVALUE_CORRUPT_BUG} - // A OpenTools API Bug IOTAProjectOptions.SetOptionValue under 2009 or above: - // Set an Option Value to DPK Project Options maybe cause DPK Source Corrupt. -{$ELSE} - {$DEFINE ZLIB_STREAM_NOSIZE} // 2007 µ Zlib Ľѹ֧ Size -{$ENDIF} - -{$IFDEF BDS2009} - // 2009 CreateParams пܵѭ - {$DEFINE CREATE_PARAMS_BUG} - // 2009 EditView CursorPos EditPosition.InsertText ƫ - {$DEFINE EDITVIEW_SETCURSORPOS_BUG} -{$ENDIF} - -{$IFDEF BDS2007_UP} - {$DEFINE IDE_CONF_MANAGER} - {$DEFINE TBYTES_DEFINED} // 2007 Defined TBytes = array of Byte; - {$DEFINE PROJECT_FILENAME_DPROJ} // Project File is .dproj -{$ENDIF} - -{$IFDEF BDS2007} - // RAD Studio 2007 ¿ AutoComplete ᵼĺ˸ - {$DEFINE COMBOBOX_CHS_BUG} -{$ENDIF} - -{$IFDEF BDS2006_UP} - {$DEFINE SUPPORT_CLASS_VAR} // 2006 and above Supports class var - {$DEFINE TCONTROL_HAS_MARGINS} // 2006 and above TControl has Margins - {$DEFINE TCONTROL_HAS_EXPLICIT_BOUNDS} // 2006 and above TControl has Explicit Bounds - {$DEFINE TCONTROL_HAS_MOUSEENTERLEAVE} // 2006 and above TControl has Mouse Enter/Leave Events - {$DEFINE OTA_CODE_TEMPLATE_API} // 2006 and above Provides CodeTemplateAPI. - {$DEFINE OTA_DEBUG_HAS_ERBUSY} // 2006 µ Evaluate зֵ erBusy - {$DEFINE IDE_HAS_GUIDE_LINE} // 2006 and above has Designer Guide Line - {$DEFINE IDE_SYNC_EDIT_BLOCK} // 2006 and above Editor Supports Sync Block Edit - {$DEFINE EDITOR_TAB_ONLYFROM_WINCONTROL} - // From BDS 2006 IDEGraident Editor Tab is Only From WinControl, not TabSet/TabControl -{$ENDIF} - -{$IFDEF BDS2005_UP} - {$DEFINE OTA_PALETTE_API} // 2005 and above Provides PaletteAPI. - {$DEFINE IDE_EDITOR_ELIDE} // 2005 ϱ༭֧۵ - {$DEFINE IDE_FILE_HISTORY} // 2005 ϰ汾洢ļʷ汾 -{$ENDIF} - -{$IFDEF BDS2006} - {$DEFINE PROJECT_FILENAME_BDSPROJ} // Project File is .bdsproj -{$ENDIF} - -{$IFDEF BDS2005} - {$DEFINE PROJECT_FILENAME_BDSPROJ} // Project File is .bdsproj -{$ENDIF} - -{$IFDEF BDS} // 2005 - {$DEFINE SUPPORT_PASCAL} - {$DEFINE SUPPORT_CSHARP} - {$DEFINE SUPPORT_INLINE} - {$DEFINE SUPPORT_UINT64} - {$DEFINE IDE_WIDECONTROL} // 2005 ϵı༭ڲǿַ UTF-8Ƿ Unicode - {$DEFINE IDE_EDITOR_SUPPORT_FOLDING} // 2005 ϵı༭֧۵ - {$DEFINE OTA_NEW_BREAKPOINT_NOBUG} // 2005 ϵ NewBreakpoint ܹ - {$DEFINE IDE_ACTION_UPDATE_DELAY} // IDE's Action Menu Update will Delay in 2005 or Up. - {$DEFINE SUPPORT_WIDECHAR_IDENTIFIER} - - {$IFNDEF COMPILER12_UP} - // 2005~2007 Compiler is Ansi but Editor String is UTF-8 - {$DEFINE IDE_STRING_ANSI_UTF8} - {$ENDIF} -{$ENDIF} - -{$IFDEF DELPHI7_UP} - {$DEFINE SUPPORT_FORMAT_SETTINGS} // Delphi 7 ʼ֧ FormatSettings - {$DEFINE IDE_MENUBAR_VERTICAL_POSITION_BUG} - // Delphi 7 ϵ MenuBar ֱϵĵλü׳Ͻ - {$DEFINE IDE_MENUBAR_VERTICAL_NOSCROLL_BUG} - // Delphi 7 ϵ MenuBar ֱʱ -{$ENDIF} - -{$IFDEF COMPILER6_UP} - {$DEFINE SUPPORT_DEPRECATED} -{$ENDIF} - -{$IFDEF COMPILER6_UP} - {$DEFINE SUPPORT_ENUMVALUES} - {$DEFINE SUPPORT_VARIANTS} - {$DEFINE SUPPORT_IFDIRECTIVE} -{$ENDIF} - -{$IFDEF DELPHI5_UP} - {$IFNDEF BDS2005_UP} - {$DEFINE PROJECT_FILENAME_DPR} // Delphi 5/6/7 Project File is .dpr - {$ENDIF} -{$ENDIF} - -{$IFDEF COMPILER5} - {$DEFINE TSTREAM_LONGINT} // D6 ϵ TStream Int64 -{$ENDIF} - -{$IFDEF BCB5} - {$DEFINE BCB5OR6} // һ BCB5OR6 Է BCB5 BCB6 ʹ -{$ENDIF} - -{$IFDEF BCB6} - {$DEFINE BCB5OR6} -{$ENDIF} - -{$IFDEF BCB5OR6} - {$DEFINE NO_ZLIB} -{$ENDIF} - -{$IFDEF DELPHI5} - {$DEFINE DELPHI5OR6} // һ DELPHI5OR6 Է DELPHI5 DELPHI6 ʹ -{$ENDIF} - -{$IFDEF DELPHI6} - {$DEFINE DELPHI5OR6} -{$ENDIF} - -{$IFDEF COMPILER4_UP} - {$DEFINE SUPPORT_INT64} - {$DEFINE SUPPORT_DYNAMICARRAYS} - {$DEFINE SUPPORT_DEFAULTPARAMS} - {$DEFINE SUPPORT_REINTRODUCE} - {$DEFINE SUPPORT_OVERLOAD} -{$ENDIF} - -{$IFDEF COMPILER35_UP} - {$DEFINE SUPPORT_EXTSYM} - {$DEFINE SUPPORT_NODEFINE} -{$ENDIF} - -{$IFDEF COMPILER3_UP} - {$DEFINE SUPPORT_WIDESTRING} - {$DEFINE SUPPORT_INTERFACE} -{$ENDIF} - -{$IFDEF WIN64} - {$DEFINE EXTENDED_SIZE_8} // Win64 Extended ͳ 8 ֽ -{$ENDIF} - -{$IFDEF CPUARM} - {$DEFINE EXTENDED_SIZE_8} // ARM ƽ̨ Extended ͳ 8 ֽ -{$ENDIF} - -{$IFDEF WIN32} - {$DEFINE EXTENDED_SIZE_10} // Win32 Extended ͳ 10 ֽ -{$ENDIF} - -{$IFDEF MACOS64} - {$DEFINE EXTENDED_SIZE_16} // MacOS64 Extended ͳ 16 ֽ -{$ENDIF} - -{$IFDEF LINUX64} - {$DEFINE EXTENDED_SIZE_16} // Linux64 Extended ͳ 16 ֽ -{$ENDIF} - -//============================================================================== -// PascalScript ĵ -//============================================================================== - -{.$DEFINE ALLDEBUG} // òƲҪȽ - -//============================================================================== -// ֶ -//============================================================================== - -{$DEFINE GB2312} -{.$DEFINE BIG5} -{.$DEFINE ENGLISH} - -//============================================================================== -// ıָ -//============================================================================== - -{$A+ Force alignment on word/dword boundaries} -{$S+ stack checking} - -{$B- Short evaluation of boolean values} -{$H+ Long string support} -{$V- No var string checking} -{$X+ Extended syntax} -{$P+ Open string parameters} -{$J+ Writeable typed constants} -{$R- No Range checking} -{$OVERFLOWCHECKS OFF} - -{$IFDEF COMPILER6_UP} - {$WARN SYMBOL_PLATFORM OFF} - {$WARN UNIT_PLATFORM OFF} - {$WARN SYMBOL_DEPRECATED OFF} - {$WARN UNIT_DEPRECATED OFF} -{$ENDIF} - -{$IFDEF COMPILER7_UP} - {$WARN UNSAFE_CAST OFF} - {$WARN UNSAFE_CODE OFF} - {$WARN UNSAFE_TYPE OFF} -{$ENDIF} - -{$IFDEF BCB} - {$OBJEXPORTALL ON} -{$ENDIF} - -{$DEFINE CN_USE_MSXML} - -{$ENDIF FPC} - +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +{******************************************************************************} +{ } +{ עõԪΪָͱ汾Ϣļ } +{ õԪݲֲο JCL GExperts } +{ } +{******************************************************************************} + +//============================================================================== +// ѡ +//============================================================================== + +{$IFDEF FPC} + // Free Pascal Compiler 3.x Up Definitions + {$DEFINE SUPPORT_PASCAL} // Pascal + {$DEFINE SUPPORT_UINT64} // UInt64 + {$DEFINE SUPPORT_32_AND_64} // ֧ 32 64 λ NativeInt + {$DEFINE SUPPORT_ENCODING} // Unicode ַ֧ Encoding ת + {$DEFINE SUPPORT_INLINE} // ֧ inline + + {$DEFINE OBJECT_HAS_TOSTRING} // TObject.ToString + {$DEFINE TBYTES_DEFINED} + + // CPU FPC ӳ䵽 Delphi + {$IFDEF CPU386} // Intel 32 CPU + {$DEFINE CPU32BITS} + {$DEFINE CPUX86} + {$asmMode intel} + {$ENDIF} + {$IFDEF CPUi386} + {$DEFINE CPU32BITS} + {$DEFINE CPUX86} + {$asmMode intel} + {$ENDIF} + + {$IFDEF CPUAMD64} // Intel 64 CPU + {$DEFINE CPU64BITS} + {$DEFINE CPUX64} + {$asmMode intel} + {$ENDIF} + {$IFDEF CPUX86_64} + {$DEFINE CPU64BITS} + {$DEFINE CPUX64} + {$asmMode intel} + {$ENDIF} + {$IFDEF CPUIA64} + {$DEFINE CPU64BITS} + {$DEFINE CPUX64} + {$asmMode intel} + {$ENDIF} + + {$IFDEF CPUARM} // ARM 32 bit processor + {$DEFINE CPU32BITS} + {$DEFINE CPUARM} + {$DEFINE CPUARM32} + {$ENDIF} + + {$IFDEF CPUAARCH64} // ARM 64 bit processor + {$DEFINE CPU64BITS} + {$DEFINE CPUARM} + {$DEFINE CPUARM64} + {$ENDIF} + + {$mode Delphi} // Delphi Compatibility, not DelphiUnicodeעԴظ + + // ر Range Check Overflow Check + {$R- No Range checking} + {$OVERFLOWCHECKS OFF} + +{$ELSE FPC} // Below is for Delphi Compiler + +//{$DEFINE PERSONAL_EDITION} +{$DEFINE ENTERPRISE_EDITION} + +{$IFNDEF PERSONAL_EDITION} + {$DEFINE SUPPORT_DB} + {$DEFINE SUPPORT_ADO} +{$ENDIF} + +//============================================================================== +// 汾Ϣ +//============================================================================== + +{$IFDEF VER360} + {$DEFINE COMPILER29} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI29} + {$DEFINE DELPHI120_ATHENS} + {$DEFINE BCB28} + {$DEFINE BCB120_ATHENS} + {$DEFINE BDS23} +{$ENDIF} + +{$IFDEF VER350} + {$DEFINE COMPILER28} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI28} + {$DEFINE DELPHI110_ALEXANDRIA} + {$DEFINE BCB28} + {$DEFINE BCB110_ALEXANDRIA} + {$DEFINE BDS22} +{$ENDIF} + +{$IFDEF VER340} + {$DEFINE COMPILER27} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI27} + {$DEFINE DELPHI104_SYDNEY} + {$DEFINE BCB27} + {$DEFINE BCB104_SYDNEY} + {$DEFINE BDS21} +{$ENDIF} + +{$IFDEF VER330} + {$DEFINE COMPILER26} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI26} + {$DEFINE DELPHI103_RIO} + {$DEFINE BCB26} + {$DEFINE BCB103_RIO} + {$DEFINE BDS20} +{$ENDIF} + +{$IFDEF VER320} + {$DEFINE COMPILER25} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI25} + {$DEFINE DELPHI102_TOKYO} + {$DEFINE BCB25} + {$DEFINE BCB102_TOKYO} + {$DEFINE BDS19} +{$ENDIF} + +{$IFDEF VER310} + {$DEFINE COMPILER24} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI24} + {$DEFINE DELPHI101_BERLIN} + {$DEFINE BCB24} + {$DEFINE BCB101_BERLIN} + {$DEFINE BDS18} +{$ENDIF} + +{$IFDEF VER300} + {$DEFINE COMPILER23} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI23} + {$DEFINE DELPHI10_SEATTLE} + {$DEFINE BCB23} + {$DEFINE BCB10_SEATTLE} + {$DEFINE BDS17} +{$ENDIF} + +{$IFDEF VER290} + {$DEFINE COMPILER22} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI22} + {$DEFINE DELPHIXE8} + {$DEFINE BCB22} + {$DEFINE BCBXE8} + {$DEFINE BDS16} +{$ENDIF} + +{$IFDEF VER280} + {$DEFINE COMPILER21} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI21} + {$DEFINE DELPHIXE7} + {$DEFINE BCB21} + {$DEFINE BCBXE7} + {$DEFINE BDS15} +{$ENDIF} + +{$IFDEF VER270} + {$DEFINE COMPILER20} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI20} + {$DEFINE DELPHIXE6} + {$DEFINE BCB20} + {$DEFINE BCBXE6} + {$DEFINE BDS14} +{$ENDIF} + +{$IFDEF VER260} + {$DEFINE COMPILER19} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI19} + {$DEFINE DELPHIXE5} + {$DEFINE BCB19} + {$DEFINE BCBXE5} + {$DEFINE BDS12} +{$ENDIF} + +{$IFDEF VER250} + {$DEFINE COMPILER18} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI18} + {$DEFINE DELPHIXE4} + {$DEFINE BCB18} + {$DEFINE BCBXE4} + {$DEFINE BDS11} +{$ENDIF} + +{$IFDEF VER240} + {$DEFINE COMPILER17} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI17} + {$DEFINE DELPHIXE3} + {$DEFINE DELPHI2013} + {$DEFINE BCB17} + {$DEFINE BCBXE3} + {$DEFINE BCB2013} + {$DEFINE BDS10} + {$DEFINE BDS2013} +{$ENDIF} + +{$IFDEF VER230} + {$DEFINE COMPILER16} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI16} + {$DEFINE DELPHIXE2} + {$DEFINE DELPHI2012} + {$DEFINE BCB16} + {$DEFINE BCBXE2} + {$DEFINE BCB2012} + {$DEFINE BDS9} + {$DEFINE BDS2012} +{$ENDIF} + +{$IFDEF VER220} + {$DEFINE COMPILER15} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI15} + {$DEFINE DELPHIXE} + {$DEFINE DELPHI2011} + {$DEFINE BCB15} + {$DEFINE BCBXE} + {$DEFINE BCB2011} + {$DEFINE BDS8} + {$DEFINE BDS2011} +{$ENDIF} + +{$IFDEF VER210} + {$DEFINE COMPILER14} + {$DEFINE VCL71} + {$DEFINE DELPHI14} + {$DEFINE DELPHI2010} + {$DEFINE BCB14} + {$DEFINE BCB2010} + {$DEFINE BDS7} + {$DEFINE BDS2010} +{$ENDIF} + +{$IFDEF VER200} + {$DEFINE COMPILER12} + {$DEFINE VCL71} + {$DEFINE DELPHI12} + {$DEFINE DELPHI2009} + {$DEFINE BCB12} + {$DEFINE BCB2009} + {$DEFINE BDS6} + {$DEFINE BDS2009} +{$ENDIF} + +{$IFDEF VER185} + {$DEFINE COMPILER11} + {$DEFINE VCL71} + {$DEFINE DELPHI11} + {$DEFINE DELPHI2007} + {$DEFINE BCB11} + {$DEFINE BCB2007} + {$DEFINE BDS5} + {$DEFINE BDS2007} + {$UNDEF VER180} +{$ENDIF} + +{$IFDEF VER180} + {$DEFINE COMPILER10} + {$DEFINE VCL71} + {$DEFINE DELPHI10} + {$DEFINE DELPHI2006} + {$DEFINE BCB10} + {$DEFINE BCB2006} + {$DEFINE BDS4} + {$DEFINE BDS2006} +{$ENDIF} + +{$IFDEF VER170} + {$DEFINE COMPILER9} + {$DEFINE VCL71} + {$DEFINE DELPHI9} + {$DEFINE DELPHI2005} + {$DEFINE BDS3} + {$DEFINE BDS2005} +{$ENDIF} + +{$IFDEF VER160} + {$DEFINE COMPILER8} + {$DEFINE VCL71} + {$DEFINE DELPHI8} + {$DEFINE BDS2} +{$ENDIF} + +{$IFDEF VER150} + {$DEFINE COMPILER7} + {$IFDEF LINUX} + {$DEFINE CLX10} + {$ELSE} + {$DEFINE VCL70} + {$DEFINE CLX10} + {$IFDEF BCB} + {$DEFINE BCB7} + {$ELSE} + {$DEFINE DELPHI7} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER140} + {$DEFINE COMPILER6} + {$IFDEF LINUX} + {$DEFINE CLX10} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IFDEF CompilerVersion} + {$IF System.RTLVersion = 14.1} + {$DEFINE KYLIX2} + {$IFEND} + {$IF System.RTLVersion = 14.5} + {$DEFINE KYLIX3} + {$IFEND} + {$ELSE} + {$DEFINE KYLIX1} + {$ENDIF} + {$ENDIF} + {$ELSE} + {$DEFINE VCL60} + {$DEFINE CLX10} + {$IFDEF BCB} + {$DEFINE BCB6} + {$ELSE} + {$DEFINE DELPHI6} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER130} + {$DEFINE COMPILER5} + {$DEFINE VCL50} + {$IFDEF BCB} + {$DEFINE BCB5} + {$ELSE} + {$DEFINE DELPHI5} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER125} + {$DEFINE COMPILER4} + {$DEFINE VCL40} + {$DEFINE BCB4} +{$ENDIF} + +{$IFDEF VER120} + {$DEFINE COMPILER4} + {$DEFINE VCL40} + {$DEFINE DELPHI4} +{$ENDIF} + +{$IFDEF VER110} + {$DEFINE COMPILER35} + {$DEFINE VCL30} + {$DEFINE BCB3} +{$ENDIF} + +{$IFDEF VER100} + {$DEFINE COMPILER3} + {$DEFINE VCL30} + {$DEFINE DELPHI3} +{$ENDIF} + +{$IFDEF VER93} + {$DEFINE COMPILER2} + {$DEFINE VCL20} + {$DEFINE BCB1} +{$ENDIF} + +{$IFDEF VER90} + {$DEFINE COMPILER2} + {$DEFINE VCL20} + {$DEFINE DELPHI2} +{$ENDIF} + +{$IFDEF VER80} + {$DEFINE COMPILER1} + {$DEFINE VCL10} + {$DEFINE DELPHI1} +{$ENDIF} + +// DELPHIX_UP from DELPHIX mappings + +{$IFDEF DELPHI29} + {$DEFINE DELPHI} + {$DEFINE DELPHI29_UP} + {$DEFINE DELPHI28_UP} + {$DEFINE DELPHI27_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI120_ATHENS} + {$DEFINE DELPHI120_ATHENS_UP} + {$DEFINE DELPHI110_ALEXANDRIA_UP} + {$DEFINE DELPHI104_SYDNEY_UP} + {$DEFINE DELPHI103_RIO_UP} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI28} + {$DEFINE DELPHI} + {$DEFINE DELPHI28_UP} + {$DEFINE DELPHI27_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI110_ALEXANDRIA} + {$DEFINE DELPHI110_ALEXANDRIA_UP} + {$DEFINE DELPHI104_SYDNEY_UP} + {$DEFINE DELPHI103_RIO_UP} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI27} + {$DEFINE DELPHI} + {$DEFINE DELPHI27_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI104_SYDNEY} + {$DEFINE DELPHI104_SYDNEY_UP} + {$DEFINE DELPHI103_RIO_UP} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI26} + {$DEFINE DELPHI} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI103_RIO} + {$DEFINE DELPHI103_RIO_UP} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI25} + {$DEFINE DELPHI} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI102_TOKYO} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI24} + {$DEFINE DELPHI} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI101_BERLIN} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI23} + {$DEFINE DELPHI} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI10_SEATTLE} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI22} + {$DEFINE DELPHI} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE8} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI21} + {$DEFINE DELPHI} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE7} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI20} + {$DEFINE DELPHI} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE6} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI19} + {$DEFINE DELPHI} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE5} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI18} + {$DEFINE DELPHI} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE4} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI17} + {$DEFINE DELPHI} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE3} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} +{$ENDIF} + +{$IFDEF DELPHI2013} + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI16} + {$DEFINE DELPHI} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE2} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} +{$ENDIF} + +{$IFDEF DELPHI2012} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI15} + {$DEFINE DELPHI} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE} + {$DEFINE DELPHIXE_UP} +{$ENDIF} + +{$IFDEF DELPHI2011} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI14} + {$DEFINE DELPHI} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2010} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI12} + {$DEFINE DELPHI} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2009} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI11} + {$DEFINE DELPHI} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2007} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI10} + {$DEFINE DELPHI} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2006} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI9} + {$DEFINE DELPHI} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2005} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI8} + {$DEFINE DELPHI} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI7} + {$DEFINE DELPHI} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI6} + {$DEFINE DELPHI} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI5} + {$DEFINE DELPHI} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI4} + {$DEFINE DELPHI} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI3} + {$DEFINE DELPHI} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2} + {$DEFINE DELPHI} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI1} + {$DEFINE DELPHI} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +// BCBX_UP from BCBX mappings + +{$IFDEF BCB29} + {$DEFINE BCB} + {$DEFINE BCB29_UP} + {$DEFINE BCB28_UP} + {$DEFINE BCB27_UP} + {$DEFINE BCB26_UP} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB120_ATHENS} + {$DEFINE BCB120_ATHENS_UP} + {$DEFINE BCB110_ALEXANDRIA_UP} + {$DEFINE BCB104_SYDNEY_UP} + {$DEFINE BCB103_RIO_UP} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB28} + {$DEFINE BCB} + {$DEFINE BCB28_UP} + {$DEFINE BCB27_UP} + {$DEFINE BCB26_UP} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB110_ALEXANDRIA} + {$DEFINE BCB110_ALEXANDRIA_UP} + {$DEFINE BCB104_SYDNEY_UP} + {$DEFINE BCB103_RIO_UP} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB27} + {$DEFINE BCB} + {$DEFINE BCB27_UP} + {$DEFINE BCB26_UP} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB104_SYDNEY} + {$DEFINE BCB104_SYDNEY_UP} + {$DEFINE BCB103_RIO_UP} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB26} + {$DEFINE BCB} + {$DEFINE BCB26_UP} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB103_RIO} + {$DEFINE BCB103_RIO_UP} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB25} + {$DEFINE BCB} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB102_TOKYO} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + + +{$IFDEF BCB24} + {$DEFINE BCB} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB101_BERLIN} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB23} + {$DEFINE BCB} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB10_SEATTLE} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB22} + {$DEFINE BCB} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE8} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB21} + {$DEFINE BCB} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE7} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB20} + {$DEFINE BCB} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE6} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB19} + {$DEFINE BCB} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE5} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB18} + {$DEFINE BCB} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE4} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB17} + {$DEFINE BCB} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE3} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} +{$ENDIF} + +{$IFDEF BCB2013} + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB16} + {$DEFINE BCB} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE2} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} +{$ENDIF} + +{$IFDEF BCB2012} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB15} + {$DEFINE BCB} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE} + {$DEFINE BCBXE_UP} +{$ENDIF} + +{$IFDEF BCB2011} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB14} + {$DEFINE BCB} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB2010} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB12} + {$DEFINE BCB} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB2009} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB11} + {$DEFINE BCB} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB2007} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB10} + {$DEFINE BCB} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB2006} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB7} + {$DEFINE BCB} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB6} + {$DEFINE BCB} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB5} + {$DEFINE BCB} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB4} + {$DEFINE BCB} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB3} + {$DEFINE BCB} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB1} + {$DEFINE BCB} + {$DEFINE BCB1_UP} +{$ENDIF} + +// KYLIXX_UP from KYLIXX mappings + +{$IFDEF KYLIX3} + {$DEFINE KYLIX} + {$DEFINE KYLIX3_UP} + {$DEFINE KYLIX2_UP} + {$DEFINE KYLIX1_UP} +{$ENDIF} + +{$IFDEF KYLIX2} + {$DEFINE KYLIX} + {$DEFINE KYLIX2_UP} + {$DEFINE KYLIX1_UP} +{$ENDIF} + +{$IFDEF KYLIX1} + {$DEFINE KYLIX} + {$DEFINE KYLIX1_UP} +{$ENDIF} + +// BDSXX_UP from BDSXX mappings + +{$IFDEF BDS23} // 12.0 ATHENS + {$DEFINE BDS} + {$DEFINE BDS23_UP} + {$DEFINE BDS22_UP} + {$DEFINE BDS21_UP} + {$DEFINE BDS20_UP} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS22} // 11.0 ALEXANDRIA + {$DEFINE BDS} + {$DEFINE BDS22_UP} + {$DEFINE BDS21_UP} + {$DEFINE BDS20_UP} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS21} // 10.4 SYDNEY + {$DEFINE BDS} + {$DEFINE BDS21_UP} + {$DEFINE BDS20_UP} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS20} // 10.3 RIO + {$DEFINE BDS} + {$DEFINE BDS20_UP} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS19} // 10.2 Tokyo + {$DEFINE BDS} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS18} // 10.1 Berlin + {$DEFINE BDS} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS17} // 10 Seattle + {$DEFINE BDS} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS16} + {$DEFINE BDS} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS15} + {$DEFINE BDS} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS14} + {$DEFINE BDS} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS12} + {$DEFINE BDS} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS11} + {$DEFINE BDS} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS10} + {$DEFINE BDS} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2013} + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS9} + {$DEFINE BDS} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2012} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS8} + {$DEFINE BDS} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2011} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS7} + {$DEFINE BDS} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2010} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS6} + {$DEFINE BDS} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2009} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS5} + {$DEFINE BDS} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2007} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS4} + {$DEFINE BDS} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2006} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS3} + {$DEFINE BDS} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2005} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS2} + {$DEFINE BDS} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS1} + {$DEFINE BDS} + {$DEFINE BDS1_UP} +{$ENDIF} + +// COMPILERX_UP from COMPILERX mappings + +{$IFDEF COMPILER29} // 12.0 ATHENS + {$DEFINE COMPILER29_UP} + {$DEFINE COMPILER28_UP} + {$DEFINE COMPILER27_UP} + {$DEFINE COMPILER26_UP} + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER28} // 11.0 ALEXANDRIA + {$DEFINE COMPILER28_UP} + {$DEFINE COMPILER27_UP} + {$DEFINE COMPILER26_UP} + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER27} // 10.4 SYDNEY + {$DEFINE COMPILER27_UP} + {$DEFINE COMPILER26_UP} + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER26} // 10.3 RIO + {$DEFINE COMPILER26_UP} + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER25} // 10.2 Tokyo + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER24} // 10.1 Berlin + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER23} // 10 Seattle + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER22} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER21} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER20} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER19} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER18} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER17} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER16} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER15} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER14} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER12} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER11} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER10} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER9} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER8} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER7} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER6} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER5} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER4} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER35} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER3} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER2} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER1} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +// VCLXX_UP from VCLXX mappings + +{$IFDEF UCL10} + {$DEFINE UCL10_UP} +{$ENDIF} + +{$IFDEF VCL71} + {$DEFINE VCL71_UP} + {$DEFINE VCL70_UP} + {$DEFINE VCL60_UP} + {$DEFINE VCL50_UP} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL70} + {$DEFINE VCL70_UP} + {$DEFINE VCL60_UP} + {$DEFINE VCL50_UP} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL60} + {$DEFINE VCL60_UP} + {$DEFINE VCL50_UP} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL50} + {$DEFINE VCL50_UP} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL40} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL30} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL20} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL10} + {$DEFINE VCL10_UP} +{$ENDIF} + +// CLXXX_UP from CLXXX mappings + +{$IFDEF CLX10} + {$DEFINE CLX10_UP} +{$ENDIF} + +//============================================================================== +// ƽ̨ض +//============================================================================== + +{$IFDEF COMPILER1} + {$DEFINE WIN16} + {$DEFINE MSWINDOWS} +{$ENDIF} + +{$IFDEF BDS} + {$DEFINE DOTNET} +{$ENDIF} + +{$IFDEF WIN32} + {$DEFINE MSWINDOWS} +{$ENDIF} + +{$IFDEF LINUX} + {$DEFINE UNIX} + {$DEFINE COMPLIB_CLX} +{$ENDIF} + +{$IFNDEF COMPLIB_CLX} + {$DEFINE COMPLIB_VCL} +{$ENDIF} + +//============================================================================== +// ӳ汾ϢѺõָ +//============================================================================== + +{$IFDEF DELPHI} + {$DEFINE SUPPORT_PASCAL} +{$ENDIF} + +{$IFDEF BCB} + {$DEFINE SUPPORT_PASCAL} + {$DEFINE SUPPORT_CPLUSPLUS} +{$ENDIF} + +{$IFDEF DELPHI120_ATHENS_UP} + {$DEFINE LIST_INDEX_NATIVEINT} // Athens 12 TList use NativeInt for Index and Count instead of Integer + {$DEFINE IDE_HAS_TABMENU_COPY_PATH} // Athens 12 editor tab menu has item to copy path or filename + {$DEFINE IDE_HAS_DBCLICK_HIGHLIGHT} // Athens 12 editor double click selection highlight + {$DEFINE OTA_CODEEDITOR_SERVICE} // 11.3 ToolsAPI.Editor ӿڣʱ޷ 11.0/1/2 ֻ֣ܼӵ 12 +{$ENDIF} + +{$IFDEF DELPHI110_ALEXANDRIA_UP} + {$DEFINE NO_OLDCREATEORDER} // Alexandria 11 removed OldCreateOrder + {$DEFINE IDE_SUPPORT_HDPI} // Alexandria 11 supports HDPI using TVirtualImageList, etc. + {$DEFINE IDE_HAS_AUTO_READONLY} // Alexandria 11 supports auto open VCL source readonly + {$DEFINE IDE_HAS_MEMORY_VISUALIZAER} // Alexandria 11 has Memory Visualizer for Debug + {$DEFINE TSTRINGS_SETTEXTSTR_CANNULL} // Alexandria 11 TStrings.SetTextStr Ignore #0 Terminated Char + {$DEFINE MEMORYSTREAM_CAPACITY_NATIVEINT} // Alexandria 11 TMemoryStream Capacity is NativeInt instead of Longint +{$ENDIF} + +{$IFDEF DELPHI104_SYDNEY_UP} + {$DEFINE IDE_SUPPORT_LSP} // Sydney 10.4 ֧ LSP Է + {$DEFINE IDE_HAS_ERRORINSIGHT} // Sydney 10.4.2 ֱ֧༭ ErrorInsight + {$DEFINE IDE_EDITOR_CUSTOM_COLUMN} // Sydney 10.4 ϱ༭ Gutter ֧Զ壬ûӿڲݣԼ + {$DEFINE IDE_SWITCH_BUG} // Sydney 10.4.2 ڴļʱĪл̨ Bug +{$ENDIF} + +{$IFDEF DELPHI103_RIO_UP} + {$DEFINE SUPPORT_MACOS64} // Rio 10.3.2 ֧ 64 λ MacOS +{$ENDIF} + +{$IFDEF DELPHI102_TOKYO_UP} + {$DEFINE SUPPORT_LINUX64} // Tokyo 10.2 ֧ Linux 64 λ Server + {$DEFINE IDE_SUPPORT_THEMING} // Tokyo 10.2.2 ֧ IDE л +{$ENDIF} + +{$IFDEF DELPHI101_BERLIN_UP} + {$DEFINE IDE_NEW_EMBEDDED_DESIGNER} // 101B Re-opens "Embedded Designer" Option and Gives a New Container. +{$ENDIF} + +{$IFDEF DELPHI10_SEATTLE_UP} + {$DEFINE IDE_HAS_OWN_STRUCTUAL_HIGHLIGHT} // 10S has own Structual Highlight + {$DEFINE IDE_HAS_HIDE_NONVISUAL} // 10S has "Hide Nonvisual" Feature. +{$ENDIF} + +{$IFDEF DELPHIXE8_UP} + {$DEFINE INIFILE_READWRITE_INTEGER} // XE8 IniFile ReadInteger WriteInteger ʼ LongInt Ϊ Integer + {$DEFINE IDE_INTEGRATE_CASTALIA} // XE8/10S and above integrate Castalia. +{$ENDIF} + +{$IFDEF COMPILER21_UP} // COMPILER21 = XE7 + {$DEFINE NOT_SUPPORT_BDE} // BDE +{$ENDIF} + +{$IFDEF DELPHIXE7_UP} + {$DEFINE SUPPORT_TBYTES_OPERATION} // XE7 TBytes ʼ֧ӡȲ + {$DEFINE FMX_CONTROL_HAS_SIZE} // XE7 FMX Control Size +{$ENDIF} + +{$IFDEF DELPHIXE6_UP} + {$DEFINE SUPPORT_JSON} // XE6 System.JSON ⣬ DBX/REST +{$ENDIF} + +{$IFDEF DELPHIXE5_UP} + {$DEFINE SUPPORT_MOBILE} // XE5 ʼ֧ƶ + {$DEFINE IDE_HAS_INSIGHT} // XE5 has IDE Insight Bar +{$ENDIF} + +{$IFDEF DELPHIXE4_UP} + {$IFNDEF DISABLE_FMX} + {$DEFINE SUPPORT_FMX_FRAME} // XE4 FMX Supports FMX Frame + {$ENDIF} +{$ELSE} + {$DEFINE MEMO_CARETPOS_BUG} // Memo CaretPos Get Negative Error Value for Large File under XE3 or below +{$ENDIF} + +{$IFDEF DELPHIXE3_UP} + {$DEFINE SUPPORT_ATOMIC} // XE3 has Atomic Routines + {$DEFINE TCONTROL_HAS_STYLEELEMENTS} // XE3 TControl has StyleElements Property + {$DEFINE IDE_NP_FMX_DESIGN_BUG} // XE3 FMX Designer Cut/Copy/Paste cause AV Bug for -np switch +{$ENDIF} + +{$IFDEF DELPHIXE2_UP} + {$DEFINE SUPPORT_WIN64} // XE2 Supports Win64 + {$DEFINE SUPPORT_MACOS32} // XE2 Supports MacOS 32 + {$DEFINE SUPPORT_UNITNAME_DOT} + {$DEFINE SUPPORT_ENHANCED_INDEXEDPROPERTY} // XE2 New RTTI Supports IndexedProperty + {$DEFINE SUPPORT_ZLIB_WINDOWBITS} // XE2 ZLib Supports WindowBits + {$DEFINE SUPPORT_GDIPLUS} // XE2 Supports GDI+ + {$DEFINE SUPPORT_INT64ARRAY} // XE2 Defined Int64Array + {$DEFINE SUPPORT_ALPHACOLOR} // XE2 System.UITypes Has TAlphaColors +{$ENDIF} + +{$IFDEF DELPHIXE_UP} + {$DEFINE TSTRINGS_HAS_WRITEBOM} // XE TStrings has WriteBOM property. + {$DEFINE IDE_HAS_DEBUGGERVISUALIZER} // XE ToolsAPI has Debugger Visualizer Interfaces. + {$DEFINE IDE_HAS_STRINGS_VISUALIZAER} // XE has TStrings Visualizer for Debug +{$ENDIF} + +{$IFDEF BDS2012_UP} // 2012 = XE2 + {$DEFINE SUPPORT_32_AND_64} // XE2 Support Win32 and Win64 + {$IFNDEF DISABLE_FMX} + {$DEFINE SUPPORT_FMX} + {$ENDIF} + {$DEFINE SUPPORT_CROSS_PLATFORM} // XE2 ֿ֧ƽ̨ + {$DEFINE VERSIONINFO_PER_CONFIGURATION} // Every Configuruation can have a Version Info. + {$DEFINE OTA_ENVOPTIONS_PLATFORM_BUG} + // A Bug Can't get Correct Env Option Values for Current Platform. + {$DEFINE LIST_NEW_POINTER} +{$ENDIF} + +{$IFDEF BDS2010_UP} + {$DEFINE SUPPORT_INTERFACE_AS_OBJECT} + {$DEFINE SUPPORT_ENHANCED_RTTI} // New enhanced RTTI. + {$DEFINE SUPPORT_EXTERNAL_DELAYED} // External functions can be declared as 'delayed'. + {$DEFINE SUPPORT_CLASS_CONSTRUCTOR} // 2010 and above Supports class constructor and destructor + {$DEFINE SUPPORT_CLASS_DESTRUCTOR} + {$DEFINE IMAGELIST_BEGINENDUPDATE} // 2010 ʼImageList й BeginUpdate EndUpdate + {$DEFINE OTA_DEBUG_HAS_EVENTS} // 2010 µ DebuggerService ProcessDebugEvents + {$DEFINE IDE_HAS_NEW_COMPONENT_PALETTE} // IDE has a new style Component Palette. + {$DEFINE IDE_HAS_EDITOR_SEARCHPANEL} // Editor has a Search Panel + {$DEFINE IDE_HAS_DATETIME_HINT} // TDate/TTime/TDateTime shows Normally in Debug Hint +{$ENDIF} + +{$IFDEF BDS2010} + // 2010 EditView CursorPos EditPosition.InsertText ƫ + {$DEFINE EDITVIEW_SETCURSORPOS_BUG} +{$ENDIF} + +{$IFDEF BDS2009_UP} + {$DEFINE UNICODE_STRING} + {$DEFINE SUPPORT_ATTRIBUTE} // ֧ Attribute + {$DEFINE SUPPORT_GENERIC} // ַ֧ + {$DEFINE SUPPORT_ANSISTRING_CODEPAGE} // AnsiString ָ֧ҳ + {$DEFINE SUPPORT_ENCODING} // Unicode with TEncoding + {$DEFINE SUPPORT_PUINT64} // Has Pointer of UInt64 + {$DEFINE OBJECT_HAS_TOSTRING} // TObject.ToString Function + {$DEFINE OBJECT_HAS_EQUAL} // TObject.Equal Function + {$DEFINE OBJECT_HAS_GETHASHCODE} // TObject.GetHashCode Function + {$DEFINE TGRAPHIC_SUPPORT_PARTIALTRANSPARENCY} // TGraphic ֧ Alpha ͨ͸ + {$DEFINE SUPPORT_OTA_PROJECT_CONFIGURATION} + + {$DEFINE IDE_MAINFORM_EAT_MOUSEWHEEL} + // MainForm of 2009 or Above will eat Message in MouseWheelHandler + {$DEFINE IDE_CODEINSIGHT_AUTOINVOKE} + // IDE Code Insight has Auto Invoke Option + {$DEFINE EDITVIEW_CONVERTPOS_BUG} + // 2009 or Above IEditView.ConvertPos Incorrect when Meeting Unicode Chars. + + {$IFNDEF DELPHIXE2_UP} // 2009/2010/XE has a Project Version Number Bug. + {$DEFINE PROJECT_VERSION_NUMBER_BUG} + {$ENDIF} + {$DEFINE OTA_DPKOPTION_SETVALUE_CORRUPT_BUG} + // A OpenTools API Bug IOTAProjectOptions.SetOptionValue under 2009 or above: + // Set an Option Value to DPK Project Options maybe cause DPK Source Corrupt. +{$ELSE} + {$DEFINE ZLIB_STREAM_NOSIZE} // 2007 µ Zlib Ľѹ֧ Size +{$ENDIF} + +{$IFDEF BDS2009} + // 2009 CreateParams пܵѭ + {$DEFINE CREATE_PARAMS_BUG} + // 2009 EditView CursorPos EditPosition.InsertText ƫ + {$DEFINE EDITVIEW_SETCURSORPOS_BUG} +{$ENDIF} + +{$IFDEF BDS2007_UP} + {$DEFINE IDE_CONF_MANAGER} + {$DEFINE TBYTES_DEFINED} // 2007 Defined TBytes = array of Byte; + {$DEFINE PROJECT_FILENAME_DPROJ} // Project File is .dproj +{$ENDIF} + +{$IFDEF BDS2007} + // RAD Studio 2007 ¿ AutoComplete ᵼĺ˸ + {$DEFINE COMBOBOX_CHS_BUG} +{$ENDIF} + +{$IFDEF BDS2006_UP} + {$DEFINE SUPPORT_CLASS_VAR} // 2006 and above Supports class var + {$DEFINE TCONTROL_HAS_MARGINS} // 2006 and above TControl has Margins + {$DEFINE TCONTROL_HAS_EXPLICIT_BOUNDS} // 2006 and above TControl has Explicit Bounds + {$DEFINE TCONTROL_HAS_MOUSEENTERLEAVE} // 2006 and above TControl has Mouse Enter/Leave Events + {$DEFINE OTA_CODE_TEMPLATE_API} // 2006 and above Provides CodeTemplateAPI. + {$DEFINE OTA_DEBUG_HAS_ERBUSY} // 2006 µ Evaluate зֵ erBusy + {$DEFINE IDE_HAS_GUIDE_LINE} // 2006 and above has Designer Guide Line + {$DEFINE IDE_SYNC_EDIT_BLOCK} // 2006 and above Editor Supports Sync Block Edit + {$DEFINE EDITOR_TAB_ONLYFROM_WINCONTROL} + // From BDS 2006 IDEGraident Editor Tab is Only From WinControl, not TabSet/TabControl +{$ENDIF} + +{$IFDEF BDS2005_UP} + {$DEFINE OTA_PALETTE_API} // 2005 and above Provides PaletteAPI. + {$DEFINE IDE_EDITOR_ELIDE} // 2005 ϱ༭֧۵ + {$DEFINE IDE_FILE_HISTORY} // 2005 ϰ汾洢ļʷ汾 +{$ENDIF} + +{$IFDEF BDS2006} + {$DEFINE PROJECT_FILENAME_BDSPROJ} // Project File is .bdsproj +{$ENDIF} + +{$IFDEF BDS2005} + {$DEFINE PROJECT_FILENAME_BDSPROJ} // Project File is .bdsproj +{$ENDIF} + +{$IFDEF BDS} // 2005 + {$DEFINE SUPPORT_PASCAL} + {$DEFINE SUPPORT_CSHARP} + {$DEFINE SUPPORT_INLINE} + {$DEFINE SUPPORT_UINT64} + {$DEFINE IDE_WIDECONTROL} // 2005 ϵı༭ڲǿַ UTF-8Ƿ Unicode + {$DEFINE IDE_EDITOR_SUPPORT_FOLDING} // 2005 ϵı༭֧۵ + {$DEFINE OTA_NEW_BREAKPOINT_NOBUG} // 2005 ϵ NewBreakpoint ܹ + {$DEFINE IDE_ACTION_UPDATE_DELAY} // IDE's Action Menu Update will Delay in 2005 or Up. + {$DEFINE SUPPORT_WIDECHAR_IDENTIFIER} + + {$IFNDEF COMPILER12_UP} + // 2005~2007 Compiler is Ansi but Editor String is UTF-8 + {$DEFINE IDE_STRING_ANSI_UTF8} + {$ENDIF} +{$ENDIF} + +{$IFDEF DELPHI7_UP} + {$DEFINE SUPPORT_FORMAT_SETTINGS} // Delphi 7 ʼ֧ FormatSettings + {$DEFINE IDE_MENUBAR_VERTICAL_POSITION_BUG} + // Delphi 7 ϵ MenuBar ֱϵĵλü׳Ͻ + {$DEFINE IDE_MENUBAR_VERTICAL_NOSCROLL_BUG} + // Delphi 7 ϵ MenuBar ֱʱ +{$ENDIF} + +{$IFDEF COMPILER6_UP} + {$DEFINE SUPPORT_DEPRECATED} +{$ENDIF} + +{$IFDEF COMPILER6_UP} + {$DEFINE SUPPORT_ENUMVALUES} + {$DEFINE SUPPORT_VARIANTS} + {$DEFINE SUPPORT_IFDIRECTIVE} +{$ENDIF} + +{$IFDEF DELPHI5_UP} + {$IFNDEF BDS2005_UP} + {$DEFINE PROJECT_FILENAME_DPR} // Delphi 5/6/7 Project File is .dpr + {$ENDIF} +{$ENDIF} + +{$IFDEF COMPILER5} + {$DEFINE TSTREAM_LONGINT} // D6 ϵ TStream Int64 +{$ENDIF} + +{$IFDEF BCB5} + {$DEFINE BCB5OR6} // һ BCB5OR6 Է BCB5 BCB6 ʹ +{$ENDIF} + +{$IFDEF BCB6} + {$DEFINE BCB5OR6} +{$ENDIF} + +{$IFDEF BCB5OR6} + {$DEFINE NO_ZLIB} +{$ENDIF} + +{$IFDEF DELPHI5} + {$DEFINE DELPHI5OR6} // һ DELPHI5OR6 Է DELPHI5 DELPHI6 ʹ +{$ENDIF} + +{$IFDEF DELPHI6} + {$DEFINE DELPHI5OR6} +{$ENDIF} + +{$IFDEF COMPILER4_UP} + {$DEFINE SUPPORT_INT64} + {$DEFINE SUPPORT_DYNAMICARRAYS} + {$DEFINE SUPPORT_DEFAULTPARAMS} + {$DEFINE SUPPORT_REINTRODUCE} + {$DEFINE SUPPORT_OVERLOAD} +{$ENDIF} + +{$IFDEF COMPILER35_UP} + {$DEFINE SUPPORT_EXTSYM} + {$DEFINE SUPPORT_NODEFINE} +{$ENDIF} + +{$IFDEF COMPILER3_UP} + {$DEFINE SUPPORT_WIDESTRING} + {$DEFINE SUPPORT_INTERFACE} +{$ENDIF} + +{$IFDEF WIN64} + {$DEFINE EXTENDED_SIZE_8} // Win64 Extended ͳ 8 ֽ +{$ENDIF} + +{$IFDEF CPUARM} + {$DEFINE EXTENDED_SIZE_8} // ARM ƽ̨ Extended ͳ 8 ֽ +{$ENDIF} + +{$IFDEF WIN32} + {$DEFINE EXTENDED_SIZE_10} // Win32 Extended ͳ 10 ֽ +{$ENDIF} + +{$IFDEF MACOS64} + {$DEFINE EXTENDED_SIZE_16} // MacOS64 Extended ͳ 16 ֽ +{$ENDIF} + +{$IFDEF LINUX64} + {$DEFINE EXTENDED_SIZE_16} // Linux64 Extended ͳ 16 ֽ +{$ENDIF} + +//============================================================================== +// PascalScript ĵ +//============================================================================== + +{.$DEFINE ALLDEBUG} // òƲҪȽ + +//============================================================================== +// ֶ +//============================================================================== + +{$DEFINE GB2312} +{.$DEFINE BIG5} +{.$DEFINE ENGLISH} + +//============================================================================== +// ıָ +//============================================================================== + +{$A+ Force alignment on word/dword boundaries} +{$S+ stack checking} + +{$B- Short evaluation of boolean values} +{$H+ Long string support} +{$V- No var string checking} +{$X+ Extended syntax} +{$P+ Open string parameters} +{$J+ Writeable typed constants} +{$R- No Range checking} +{$OVERFLOWCHECKS OFF} + +{$IFDEF COMPILER6_UP} + {$WARN SYMBOL_PLATFORM OFF} + {$WARN UNIT_PLATFORM OFF} + {$WARN SYMBOL_DEPRECATED OFF} + {$WARN UNIT_DEPRECATED OFF} +{$ENDIF} + +{$IFDEF COMPILER7_UP} + {$WARN UNSAFE_CAST OFF} + {$WARN UNSAFE_CODE OFF} + {$WARN UNSAFE_TYPE OFF} +{$ENDIF} + +{$IFDEF BCB} + {$OBJEXPORTALL ON} +{$ENDIF} + +{$DEFINE CN_USE_MSXML} + +{$ENDIF FPC} + diff --git a/CnPack/Crypto/CnAES.pas b/CnPack/Crypto/CnAES.pas index 8f0a8da..c2f7692 100644 --- a/CnPack/Crypto/CnAES.pas +++ b/CnPack/Crypto/CnAES.pas @@ -1,7569 +1,7569 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} -(******************************************************************************) -(* *) -(* Advanced Encryption Standard (AES) *) -(* *) -(* Copyright (c) 1998-2001 *) -(* EldoS, Alexander Ionov *) -(* *) -(******************************************************************************) - -unit CnAES; -{* |

-================================================================================
-* ƣ
-* ԪƣAES ԳƼӽ㷨ʵֵԪ
-* ԪߣCnPack  (master@cnpack.org)
-*            EldoS, Alexander Ionov ĵԪֲ书ܣԭаȨϢ
-*     עԪʵ AES 128/192/256 ԳƼӽ㷨ֿС̶ 16 ֽڣģʽ
-*           Ķ뷽ʽĩβ 0Ԫڲ֧ PKCS ȿ뷽ʽҪⲿ
-*           CnPemUtils.pas Ԫе PKCS ϵкԼӽݽж⴦
-*
-*           ߰汾 Delphi 뾡ʹ AnsiString 汾ĺʮƳ⣩
-*           ⲻַӰӽܽ
-*
-*           䣺============= Java Ĭϵ AES Ӧ˴ AES256 ============
-*           ⣬C++Builder 5/6 ¶ overload ĺʴжϴӶ
-*           ҵΣʱԪ˴ overload  Delphi ´ڣ
-*           ٷװ˲ֲͬĺ֧ C++Builder 5/6 ±С
-*
-*           ECB/CBC ǿģʽҪ롣CFB/OFB/CTR ĵģʽ뵽顣
-*
-*           ⣬CTR ģʽ RFC 3686 淶紫ݵ 4 ֽ Nonce8 ֽ
-*           ʼ4 ֽֽļƴ 16 ֽڵijʼ
-*            AES 㣬ӽܾΪĶ
-*
-* ƽ̨Delphi5 + Win 7
-* ޸ļ¼2024.07.25 V1.3
-*                CTR ģʽ֧֣ѭ RFC 3686 淶
-*           2024.05.26 V1.2
-*               䲿֧ C++Builder ĺ
-*           2022.06.21 V1.1
-*               뼸ֽ鵽ʮַ֮ļӽܺ
-*           2021.12.11 V1.2
-*                CFB/OFB ģʽ֧
-*           2019.04.15 V1.1
-*               ֧ Win32/Win64/MacOS
-*           2015.01.21 V1.0
-*               Ԫ
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - Classes, SysUtils, CnNative; - -const - CN_AES_BLOCKSIZE = 16; - {* AES ķܿСλ٣Ϊ 16 ֽ} - -type - TCnKeyBitType = (kbt128, kbt192, kbt256); - {* AES λ16 ֽڡ24 ֽں 32 ֽ} - - ECnAESException = class(Exception); - {* AES 쳣} - - TCnAESBuffer = array [0..15] of Byte; - {* AES ӽܿ 16 ֽ} - - TCnAESKey128 = array [0..15] of Byte; - {* AES128 Կṹ16 ֽ} - - TCnAESKey192 = array [0..23] of Byte; - {* AES192 Կṹ24 ֽ} - - TCnAESKey256 = array [0..31] of Byte; - {* AES256 Կṹ32 ֽ} - - TCnAESExpandedKey128 = array [0..43] of Cardinal; - {* AES128 չԿṹ} - - TCnAESExpandedKey192 = array [0..53] of Cardinal; - {* AES192 չԿṹ} - - TCnAESExpandedKey256 = array [0..63] of Cardinal; - {* AES256 չԿṹ} - - PCnAESBuffer = ^TCnAESBuffer; - PCnAESKey128 = ^TCnAESKey128; - PCnAESKey192 = ^TCnAESKey192; - PCnAESKey256 = ^TCnAESKey256; - PCnAESExpandedKey128 = ^TCnAESExpandedKey128; - PCnAESExpandedKey192 = ^TCnAESExpandedKey192; - PCnAESExpandedKey256 = ^TCnAESExpandedKey256; - - TCnAESCTRNonce = array[0..3] of Byte; - {* CTR ģʽµ Nonce ṹ4 ֽ} - TCnAESCTRIv = array[0..7] of Byte; - {* CTR ģʽµijʼṹ8 ֽ} - -// Key Expansion Routines for Encryption - -procedure ExpandAESKeyForEncryption128(const Key: TCnAESKey128; - var ExpandedKey: TCnAESExpandedKey128); -{* ڼܳչ AES128 Կ - - - const Key: TCnAESKey128 - չ AES128 Կ - var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ - - ֵޣ -} - -procedure ExpandAESKeyForEncryption192(const Key: TCnAESKey192; - var ExpandedKey: TCnAESExpandedKey192); -{* ڼܳչ AES192 Կ - - - const Key: TCnAESKey192 - չ AES192 Կ - var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ - - ֵޣ -} - -procedure ExpandAESKeyForEncryption256(const Key: TCnAESKey256; - var ExpandedKey: TCnAESExpandedKey256); -{* ڼܳչ AES256 Կ - - - const Key: TCnAESKey256 - չ AES256 Կ - var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ - - ֵޣ -} - -// Block Encryption Routines ܣInBuf OutBuf ͬһ - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; - var OutBuf: TCnAESBuffer); overload; -{* AES128 ܿ飬 Delphi ¿á - - - const InBuf: TCnAESBuffer - ܵݿ - const Key: TCnAESExpandedKey128 - չ AES128 Կ - var OutBuf: TCnAESBuffer - ĵݿ - - ֵޣ -} -procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; - var OutBuf: TCnAESBuffer); overload; -{* AES192 ܿ飬 Delphi ¿á - - - const InBuf: TCnAESBuffer - ܵݿ - const Key: TCnAESExpandedKey192 - չ AES192 Կ - var OutBuf: TCnAESBuffer - ĵݿ - - ֵޣ -} -procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; - var OutBuf: TCnAESBuffer); overload; -{* AES256 ܿ飬 Delphi ¿á - - - const InBuf: TCnAESBuffer - ܵݿ - const Key: TCnAESExpandedKey256 - չ AES256 Կ - var OutBuf: TCnAESBuffer - ĵݿ - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure EncryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; - var OutBuf: TCnAESBuffer); -{* AES128 ܿ飬InBuf OutBuf ͬһ - - - const InBuf: TCnAESBuffer - ܵݿ - const Key: TCnAESExpandedKey128 - չ AES128 Կ - var OutBuf: TCnAESBuffer - ĵݿ - - ֵޣ -} -procedure EncryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; - var OutBuf: TCnAESBuffer); -{* AES192 ܿ飬InBuf OutBuf ͬһ - - - const InBuf: TCnAESBuffer - ܵݿ - const Key: TCnAESExpandedKey192 - չ AES192 Կ - var OutBuf: TCnAESBuffer - ĵݿ - - ֵޣ -} -procedure EncryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; - var OutBuf: TCnAESBuffer); -{* AES256 ܿ飬InBuf OutBuf ͬһ - - - const InBuf: TCnAESBuffer - ܵݿ - const Key: TCnAESExpandedKey256 - չ AES256 Կ - var OutBuf: TCnAESBuffer - ĵݿ - - ֵޣ -} - -// Stream Encryption Routines (ECB mode) ECB - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; Dest: TStream); overload; -{* AES128 ECB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); overload; -{* AES128 ECB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; Dest: TStream); overload; -{* AES256 ECB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); overload; -{* AES192 ECB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; Dest: TStream); overload; -{* AES256 ECB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); overload; -{* AES256 ECB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - Dest: TStream - - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure EncryptAES128StreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; Dest: TStream); -{* AES128 ECB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); -{* AES128 ECB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAES192StreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; Dest: TStream); -{* AES192 ECB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); -{* AES192 ECB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAES256StreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; Dest: TStream); -{* AES256 ECB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); -{* AES256 ECB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - Dest: TStream - - - ֵޣ -} - -// Stream Encryption Routines (CBC mode) CBC - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES128 CBC ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES128 CBC ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES192 CBC ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES192 CBC ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES256 CBC ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES256 CBC ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure EncryptAES128StreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES128 CBC ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES128 CBC ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAES192StreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES192 CBC ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES192 CBC ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAES256StreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES256 CBC ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES256 CBC ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -// Stream Encryption Routines (CFB mode) CFB - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES128 CFB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES128 CFB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES192 CFB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES192 CFB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES256 CFB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES256 CFB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure EncryptAES128StreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES128 CFB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES128 CFB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES192StreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES192 CFB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES192 CFB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES256StreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES256 CFB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES256 CFB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -// Stream Encryption Routines (OFB mode) OFB - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES128 OFB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES128 OFB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES192 OFB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES192 OFB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES256 OFB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES256 OFB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure EncryptAES128StreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES128 OFB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES128 OFB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAES192StreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES192 OFB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - ?? - - ֵޣ -} -procedure EncryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES192 OFB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure EncryptAES256StreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES256 OFB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES256 OFB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -// Stream Encryption Routines (CTR mode) CTR - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); overload; -{* AES128 CTR ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); overload; -{* AES128 CTR ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); overload; -{* AES192 CTR ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); overload; -{* AES192 CTR ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); overload; -{* AES256 CTR ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); overload; -{* AES256 CTR ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure EncryptAES128StreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -{* AES128 CTR ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -{* AES128 CTR ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES192StreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -{* AES192 CTR ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -{* AES192 CTR ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES256StreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -{* AES256 CTR ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure EncryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -{* AES256 CTR ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -// Key Transformation Routines for Decryption - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey128); overload; -{* ڽܳչ AES128 Կ - - - var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ - - ֵޣ -} - -procedure ExpandAESKeyForDecryption(const Key: TCnAESKey128; - var ExpandedKey: TCnAESExpandedKey128); overload; -{* ڽܳչ AES128 Կ - - - const Key: TCnAESKey128 - չ AES128 Կ - var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ - - ֵޣ -} - -procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey192); overload; -{* ڽܳչ AES192 Կ - - - var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ - - ֵޣ -} -procedure ExpandAESKeyForDecryption(const Key: TCnAESKey192; - var ExpandedKey: TCnAESExpandedKey192); overload; -{* ڽܳչ AES192 Կ - - - const Key: TCnAESKey192 - չ AES192 Կ - var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ - - ֵޣ -} - -procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey256); overload; -{* ڽܳչ AES256 Կ - - - var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ - - ֵޣ -} -procedure ExpandAESKeyForDecryption(const Key: TCnAESKey256; - var ExpandedKey: TCnAESExpandedKey256); overload; -{* ڽܳչ AES256 Կ - - - const Key: TCnAESKey256 - չ AES256 Կ - var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure ExpandAESKeyForDecryption128(var ExpandedKey: TCnAESExpandedKey128); -{* ڽܳչ AES128 Կ - - - var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ - - ֵޣ -} -procedure ExpandAESKeyForDecryption128Expanded(const Key: TCnAESKey128; - var ExpandedKey: TCnAESExpandedKey128); -{* ڽܳչ AES128 Կ - - - const Key: TCnAESKey128 - չ AES128 Կ - var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ - - ֵޣ -} - -procedure ExpandAESKeyForDecryption192(var ExpandedKey: TCnAESExpandedKey192); -{* ڽܳչ AES192 Կ - - - var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ - - ֵޣ -} -procedure ExpandAESKeyForDecryption192Expanded(const Key: TCnAESKey192; - var ExpandedKey: TCnAESExpandedKey192); -{* ڽܳչ AES192 Կ - - - const Key: TCnAESKey192 - չ AES192 Կ - var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ - - ֵޣ -} - -procedure ExpandAESKeyForDecryption256(var ExpandedKey: TCnAESExpandedKey256); -{* ڽܳչ AES256 Կ - - - var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ - - ֵޣ -} -procedure ExpandAESKeyForDecryption256Expanded(const Key: TCnAESKey256; - var ExpandedKey: TCnAESExpandedKey256); -{* ڽܳչ AES256 Կ - - - const Key: TCnAESKey256 - չ AES256 Կ - var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ - - ֵޣ -} - -// Block Decryption Routines - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; - var OutBuf: TCnAESBuffer); overload; -{* AES128 ܿ飬 Delphi ¿á - - - const InBuf: TCnAESBuffer - ܵݿ - const Key: TCnAESExpandedKey128 - չ AES128 Կ - var OutBuf: TCnAESBuffer - ĵݿ - - ֵޣ -} - -procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; - var OutBuf: TCnAESBuffer); overload; -{* AES192 ܿ飬 Delphi ¿á - - - const InBuf: TCnAESBuffer - ܵݿ - const Key: TCnAESExpandedKey192 - չ AES192 Կ - var OutBuf: TCnAESBuffer - ĵݿ - - ֵޣ -} - -procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; - var OutBuf: TCnAESBuffer); overload; -{* AES256 ܿ飬 Delphi ¿á - - - const InBuf: TCnAESBuffer - ܵݿ - const Key: TCnAESExpandedKey256 - չ AES256 Կ - var OutBuf: TCnAESBuffer - ĵݿ - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure DecryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; - var OutBuf: TCnAESBuffer); -{* AES128 ܿ飬InBuf OutBuf ͬһ - - - const InBuf: TCnAESBuffer - ܵݿ - const Key: TCnAESExpandedKey128 - չ AES128 Կ - var OutBuf: TCnAESBuffer - ĵݿ - - ֵޣ -} -procedure DecryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; - var OutBuf: TCnAESBuffer); -{* AES192 ܿ飬InBuf OutBuf ͬһ - - - const InBuf: TCnAESBuffer - ܵݿ - const Key: TCnAESExpandedKey192 - չ AES192 Կ - var OutBuf: TCnAESBuffer - ĵݿ - - ֵޣ -} -procedure DecryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; - var OutBuf: TCnAESBuffer); -{* AES256 ܿ飬InBuf OutBuf ͬһ - - - const InBuf: TCnAESBuffer - ܵݿ - const Key: TCnAESExpandedKey256 - չ AES256 Կ - var OutBuf: TCnAESBuffer - ĵݿ - - ֵޣ -} - -// Stream Decryption Routines (ECB mode) ECB - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; Dest: TStream); overload; -{* AES128 ECB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); overload; -{* AES128 ECB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - Dest: TStream - - - ֵޣ -} - -procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; Dest: TStream); overload; -{* AES192 ECB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); overload; -{* AES192 ECB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - Dest: TStream - - - ֵޣ -} - -procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; Dest: TStream); overload; -{* AES256 ECB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); overload; -{* AES256 ECB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - Dest: TStream - - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure DecryptAES128StreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; Dest: TStream); -{* AES128 ECB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); -{* AES128 ECB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - Dest: TStream - - - ֵޣ -} - -procedure DecryptAES192StreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; Dest: TStream); -{* AES192 ECB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); -{* AES192 ECB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - Dest: TStream - - - ֵޣ -} - -procedure DecryptAES256StreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; Dest: TStream); -{* AES256 ECB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); -{* AES156 ECB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - Dest: TStream - - - ֵޣ -} - -// Stream Decryption Routines (CBC mode) CBC - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES128 CBC ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES128 CBC ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES192 CBC ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES192 CBC ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES256 CBC ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES256 CBC ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure DecryptAES128StreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES128 CBC ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES128 CBC ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES192StreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES192 CBC ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES192 CBC ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES256StreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES256 CBC ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES256 CBC ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -// Stream Decryption Routines (CFB mode) CFB - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES128 CFB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES128 CFB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES192 CFB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES192 CFB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES256 CFB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES256 CFB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure DecryptAES128StreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES128 CFB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES128 CFB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES192StreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES192 CFB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES192 CFB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES256StreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES256 CFB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES256 CFB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -// Stream Decryption Routines (OFB mode) OFB - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES128 OFB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES128 OFB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES192 OFB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES192 OFB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; -{* AES256 OFB ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); overload; -{* AES256 OFB ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure DecryptAES128StreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES128 OFB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES128 OFB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES192StreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES192 OFB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES192 OFB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES256StreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -{* AES256 OFB ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -{* AES256 OFB ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const InitVector: TCnAESBuffer - 16 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -// Stream Decryption Routines (CTR mode) CTR - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); overload; -{* AES128 CTR ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); overload; -{* AES128 CTR ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); overload; -{* AES192 CTR ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); overload; -{* AES192 CTR ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); overload; -{* AES256 CTR ģʽ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); overload; -{* AES256 CTR ģʽʹչԿ Delphi ¿á - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -{$ENDIF} - -// Delphi C++Builder ¾ -procedure DecryptAES128StreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -{* AES128 CTR ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey128 - 16 ֽ AES128 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -{* AES128 CTR ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES192StreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -{* AES192 CTR ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey192 - 24 ֽ AES192 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -{* AES192 CTR ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES256StreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -{* AES256 CTR ģʽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnAESKey256 - 32 ֽ AES256 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} -procedure DecryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -{* AES256 CTR ģʽʹչԿ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const InitVector: TCnAESCTRIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -// ============== ַʮַ֮ļӽ =================== - -function AESEncryptEcbStrToHex(Value: AnsiString; Key: AnsiString; - KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES ECB ģʽַתʮơ - - - Value: AnsiString - ַܵ - Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ʮַ -} - -function AESDecryptEcbStrFromHex(const HexStr: AnsiString; Key: AnsiString; - KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES ECB ʮַ - - - const HexStr: AnsiString - ܵʮַ - Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ַ -} - -function AESEncryptCbcStrToHex(Value: AnsiString; Key: AnsiString; - const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES CBC ģʽַתʮơ - - - Value: AnsiString - ַܵ - Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 - const Iv: TCnAESBuffer - 16 ֽڳʼ - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ʮַ -} - -function AESDecryptCbcStrFromHex(const HexStr: AnsiString; Key: AnsiString; - const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES CBC ʮַ - - - const HexStr: AnsiString - ܵʮַ - Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 - const Iv: TCnAESBuffer - 16 ֽڳʼ - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ַ -} - -function AESEncryptCfbStrToHex(Value: AnsiString; Key: AnsiString; - const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES CFB ģʽַתʮơ - - - Value: AnsiString - ַܵ - Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 - const Iv: TCnAESBuffer - 16 ֽڳʼ - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ʮַ -} - -function AESDecryptCfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; - const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES CFB ʮַ - - - const HexStr: AnsiString - ܵʮַ - Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 - const Iv: TCnAESBuffer - 16 ֽڳʼ - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ַ -} - -function AESEncryptOfbStrToHex(Value: AnsiString; Key: AnsiString; - const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES OFB ģʽַתʮơ - - - Value: AnsiString - ַܵ - Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 - const Iv: TCnAESBuffer - 16 ֽڳʼ - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ʮַ -} - -function AESDecryptOfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; - const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES OFB ʮַ - - - const HexStr: AnsiString - ܵʮַ - Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 - const Iv: TCnAESBuffer - 16 ֽڳʼ - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ַ -} - -function AESEncryptCtrStrToHex(Value: AnsiString; Key: AnsiString; - const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES CTR ģʽַתʮơ - - - Value: AnsiString - ַܵ - Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const Iv: TCnAESCTRIv - 8 ֽڳʼ - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ʮַ -} - -function AESDecryptCtrStrFromHex(const HexStr: AnsiString; Key: AnsiString; - const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES CTR ʮַ - - - const HexStr: AnsiString - ܵʮַ - Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 - const Nonce: TCnAESCTRNonce - 4 ֽ Nonce - const Iv: TCnAESCTRIv - 8 ֽڳʼ - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ַ -} - -// ================= ֽֽ֮ļӽ ==================== - -function AESEncryptEcbBytes(Value: TBytes; Key: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES ECB ģʽֽ顣 - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESDecryptEcbBytes(Value: TBytes; Key: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES ECB ģʽֽ顣 - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESEncryptCbcBytes(Value: TBytes; Key: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES CBC ģʽֽ顣 - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESDecryptCbcBytes(Value: TBytes; Key: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES CBC ģʽֽ顣 - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESEncryptCfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES CFB ģʽֽ顣 - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESDecryptCfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES CFB ģʽֽ顣 - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESEncryptOfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES OFB ģʽֽ顣 - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESDecryptOfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES OFB ģʽֽ顣 - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESEncryptCtrBytes(Value: TBytes; Key: TBytes; Nonce: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES CTR ģʽֽ顣 - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Nonce: TBytes - 4 ֽ Nonce 飬̫ضϣ 0 - Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESDecryptCtrBytes(Value: TBytes; Key: TBytes; Nonce: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES CTR ģʽֽ顣 - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Nonce: TBytes - 4 ֽ Nonce 飬̫ضϣ 0 - Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -// ============== ֽʮַ֮ļӽ ================= - -function AESEncryptEcbBytesToHex(Value: TBytes; Key: TBytes; - KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES ECB ģʽֽ鲢תʮơ - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ʮַ -} - -function AESDecryptEcbBytesFromHex(const HexStr: AnsiString; Key: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES ECB ʮַֽ顣 - - - const HexStr: AnsiString - ܵʮַ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESEncryptCbcBytesToHex(Value: TBytes; Key: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES CBC ģʽֽ鲢תʮơ - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ʮַ -} - -function AESDecryptCbcBytesFromHex(const HexStr: AnsiString; Key: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES CBC ʮַֽ顣 - - - const HexStr: AnsiString - ܵʮַ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESEncryptCfbBytesToHex(Value: TBytes; Key: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES CFB ģʽֽ鲢תʮơ - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ʮַ -} - -function AESDecryptCfbBytesFromHex(const HexStr: AnsiString; Key: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES CFB ʮַֽ顣 - - - const HexStr: AnsiString - ܵʮַ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESEncryptOfbBytesToHex(Value: TBytes; Key: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES OFB ģʽֽ鲢תʮơ - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ʮַ -} - -function AESDecryptOfbBytesFromHex(const HexStr: AnsiString; Key: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES OFB ʮַֽ顣 - - - const HexStr: AnsiString - ܵʮַ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -function AESEncryptCtrBytesToHex(Value: TBytes; Key: TBytes; Nonce: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): AnsiString; -{* AES CTR ģʽֽ鲢תʮơ - - - Value: TBytes - ֽܵ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Nonce: TBytes - 4 ֽ Nonce ֽ飬̫ضϣ 0 - Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵAnsiString - ʮַ -} - -function AESDecryptCtrBytesFromHex(const HexStr: AnsiString; Key: TBytes; Nonce: TBytes; Iv: TBytes; - KeyBit: TCnKeyBitType = kbt128): TBytes; -{* AES CTR ʮַֽ顣 - - - const HexStr: AnsiString - ܵʮַ - Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 - Nonce: TBytes - 4 ֽ Nonce ֽ飬̫ضϣ 0 - Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 - KeyBit: TCnKeyBitType - AES - - ֵTBytes - ֽ -} - -implementation - -resourcestring - SCnErrorAESInvalidInBufSize = 'Invalid Buffer Size for Decryption'; - SCnErrorAESReadError = 'Stream Read Error'; - SCnErrorAESWriteError = 'Stream Write Error'; - -function Min(A, B: Integer): Integer; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - if A < B then - Result := A - else - Result := B; -end; - -const - Rcon: array [1..30] of Cardinal = ( - $00000001, $00000002, $00000004, $00000008, $00000010, $00000020, - $00000040, $00000080, $0000001B, $00000036, $0000006C, $000000D8, - $000000AB, $0000004D, $0000009A, $0000002F, $0000005E, $000000BC, - $00000063, $000000C6, $00000097, $00000035, $0000006A, $000000D4, - $000000B3, $0000007D, $000000FA, $000000EF, $000000C5, $00000091 - ); - - ForwardTable: array [0..255] of Cardinal = ( - $A56363C6, $847C7CF8, $997777EE, $8D7B7BF6, $0DF2F2FF, $BD6B6BD6, $B16F6FDE, $54C5C591, - $50303060, $03010102, $A96767CE, $7D2B2B56, $19FEFEE7, $62D7D7B5, $E6ABAB4D, $9A7676EC, - $45CACA8F, $9D82821F, $40C9C989, $877D7DFA, $15FAFAEF, $EB5959B2, $C947478E, $0BF0F0FB, - $ECADAD41, $67D4D4B3, $FDA2A25F, $EAAFAF45, $BF9C9C23, $F7A4A453, $967272E4, $5BC0C09B, - $C2B7B775, $1CFDFDE1, $AE93933D, $6A26264C, $5A36366C, $413F3F7E, $02F7F7F5, $4FCCCC83, - $5C343468, $F4A5A551, $34E5E5D1, $08F1F1F9, $937171E2, $73D8D8AB, $53313162, $3F15152A, - $0C040408, $52C7C795, $65232346, $5EC3C39D, $28181830, $A1969637, $0F05050A, $B59A9A2F, - $0907070E, $36121224, $9B80801B, $3DE2E2DF, $26EBEBCD, $6927274E, $CDB2B27F, $9F7575EA, - $1B090912, $9E83831D, $742C2C58, $2E1A1A34, $2D1B1B36, $B26E6EDC, $EE5A5AB4, $FBA0A05B, - $F65252A4, $4D3B3B76, $61D6D6B7, $CEB3B37D, $7B292952, $3EE3E3DD, $712F2F5E, $97848413, - $F55353A6, $68D1D1B9, $00000000, $2CEDEDC1, $60202040, $1FFCFCE3, $C8B1B179, $ED5B5BB6, - $BE6A6AD4, $46CBCB8D, $D9BEBE67, $4B393972, $DE4A4A94, $D44C4C98, $E85858B0, $4ACFCF85, - $6BD0D0BB, $2AEFEFC5, $E5AAAA4F, $16FBFBED, $C5434386, $D74D4D9A, $55333366, $94858511, - $CF45458A, $10F9F9E9, $06020204, $817F7FFE, $F05050A0, $443C3C78, $BA9F9F25, $E3A8A84B, - $F35151A2, $FEA3A35D, $C0404080, $8A8F8F05, $AD92923F, $BC9D9D21, $48383870, $04F5F5F1, - $DFBCBC63, $C1B6B677, $75DADAAF, $63212142, $30101020, $1AFFFFE5, $0EF3F3FD, $6DD2D2BF, - $4CCDCD81, $140C0C18, $35131326, $2FECECC3, $E15F5FBE, $A2979735, $CC444488, $3917172E, - $57C4C493, $F2A7A755, $827E7EFC, $473D3D7A, $AC6464C8, $E75D5DBA, $2B191932, $957373E6, - $A06060C0, $98818119, $D14F4F9E, $7FDCDCA3, $66222244, $7E2A2A54, $AB90903B, $8388880B, - $CA46468C, $29EEEEC7, $D3B8B86B, $3C141428, $79DEDEA7, $E25E5EBC, $1D0B0B16, $76DBDBAD, - $3BE0E0DB, $56323264, $4E3A3A74, $1E0A0A14, $DB494992, $0A06060C, $6C242448, $E45C5CB8, - $5DC2C29F, $6ED3D3BD, $EFACAC43, $A66262C4, $A8919139, $A4959531, $37E4E4D3, $8B7979F2, - $32E7E7D5, $43C8C88B, $5937376E, $B76D6DDA, $8C8D8D01, $64D5D5B1, $D24E4E9C, $E0A9A949, - $B46C6CD8, $FA5656AC, $07F4F4F3, $25EAEACF, $AF6565CA, $8E7A7AF4, $E9AEAE47, $18080810, - $D5BABA6F, $887878F0, $6F25254A, $722E2E5C, $241C1C38, $F1A6A657, $C7B4B473, $51C6C697, - $23E8E8CB, $7CDDDDA1, $9C7474E8, $211F1F3E, $DD4B4B96, $DCBDBD61, $868B8B0D, $858A8A0F, - $907070E0, $423E3E7C, $C4B5B571, $AA6666CC, $D8484890, $05030306, $01F6F6F7, $120E0E1C, - $A36161C2, $5F35356A, $F95757AE, $D0B9B969, $91868617, $58C1C199, $271D1D3A, $B99E9E27, - $38E1E1D9, $13F8F8EB, $B398982B, $33111122, $BB6969D2, $70D9D9A9, $898E8E07, $A7949433, - $B69B9B2D, $221E1E3C, $92878715, $20E9E9C9, $49CECE87, $FF5555AA, $78282850, $7ADFDFA5, - $8F8C8C03, $F8A1A159, $80898909, $170D0D1A, $DABFBF65, $31E6E6D7, $C6424284, $B86868D0, - $C3414182, $B0999929, $772D2D5A, $110F0F1E, $CBB0B07B, $FC5454A8, $D6BBBB6D, $3A16162C - ); - - LastForwardTable: array [0..255] of Cardinal = ( - $00000063, $0000007C, $00000077, $0000007B, $000000F2, $0000006B, $0000006F, $000000C5, - $00000030, $00000001, $00000067, $0000002B, $000000FE, $000000D7, $000000AB, $00000076, - $000000CA, $00000082, $000000C9, $0000007D, $000000FA, $00000059, $00000047, $000000F0, - $000000AD, $000000D4, $000000A2, $000000AF, $0000009C, $000000A4, $00000072, $000000C0, - $000000B7, $000000FD, $00000093, $00000026, $00000036, $0000003F, $000000F7, $000000CC, - $00000034, $000000A5, $000000E5, $000000F1, $00000071, $000000D8, $00000031, $00000015, - $00000004, $000000C7, $00000023, $000000C3, $00000018, $00000096, $00000005, $0000009A, - $00000007, $00000012, $00000080, $000000E2, $000000EB, $00000027, $000000B2, $00000075, - $00000009, $00000083, $0000002C, $0000001A, $0000001B, $0000006E, $0000005A, $000000A0, - $00000052, $0000003B, $000000D6, $000000B3, $00000029, $000000E3, $0000002F, $00000084, - $00000053, $000000D1, $00000000, $000000ED, $00000020, $000000FC, $000000B1, $0000005B, - $0000006A, $000000CB, $000000BE, $00000039, $0000004A, $0000004C, $00000058, $000000CF, - $000000D0, $000000EF, $000000AA, $000000FB, $00000043, $0000004D, $00000033, $00000085, - $00000045, $000000F9, $00000002, $0000007F, $00000050, $0000003C, $0000009F, $000000A8, - $00000051, $000000A3, $00000040, $0000008F, $00000092, $0000009D, $00000038, $000000F5, - $000000BC, $000000B6, $000000DA, $00000021, $00000010, $000000FF, $000000F3, $000000D2, - $000000CD, $0000000C, $00000013, $000000EC, $0000005F, $00000097, $00000044, $00000017, - $000000C4, $000000A7, $0000007E, $0000003D, $00000064, $0000005D, $00000019, $00000073, - $00000060, $00000081, $0000004F, $000000DC, $00000022, $0000002A, $00000090, $00000088, - $00000046, $000000EE, $000000B8, $00000014, $000000DE, $0000005E, $0000000B, $000000DB, - $000000E0, $00000032, $0000003A, $0000000A, $00000049, $00000006, $00000024, $0000005C, - $000000C2, $000000D3, $000000AC, $00000062, $00000091, $00000095, $000000E4, $00000079, - $000000E7, $000000C8, $00000037, $0000006D, $0000008D, $000000D5, $0000004E, $000000A9, - $0000006C, $00000056, $000000F4, $000000EA, $00000065, $0000007A, $000000AE, $00000008, - $000000BA, $00000078, $00000025, $0000002E, $0000001C, $000000A6, $000000B4, $000000C6, - $000000E8, $000000DD, $00000074, $0000001F, $0000004B, $000000BD, $0000008B, $0000008A, - $00000070, $0000003E, $000000B5, $00000066, $00000048, $00000003, $000000F6, $0000000E, - $00000061, $00000035, $00000057, $000000B9, $00000086, $000000C1, $0000001D, $0000009E, - $000000E1, $000000F8, $00000098, $00000011, $00000069, $000000D9, $0000008E, $00000094, - $0000009B, $0000001E, $00000087, $000000E9, $000000CE, $00000055, $00000028, $000000DF, - $0000008C, $000000A1, $00000089, $0000000D, $000000BF, $000000E6, $00000042, $00000068, - $00000041, $00000099, $0000002D, $0000000F, $000000B0, $00000054, $000000BB, $00000016 - ); - - InverseTable: array [0..255] of Cardinal = ( - $50A7F451, $5365417E, $C3A4171A, $965E273A, $CB6BAB3B, $F1459D1F, $AB58FAAC, $9303E34B, - $55FA3020, $F66D76AD, $9176CC88, $254C02F5, $FCD7E54F, $D7CB2AC5, $80443526, $8FA362B5, - $495AB1DE, $671BBA25, $980EEA45, $E1C0FE5D, $02752FC3, $12F04C81, $A397468D, $C6F9D36B, - $E75F8F03, $959C9215, $EB7A6DBF, $DA595295, $2D83BED4, $D3217458, $2969E049, $44C8C98E, - $6A89C275, $78798EF4, $6B3E5899, $DD71B927, $B64FE1BE, $17AD88F0, $66AC20C9, $B43ACE7D, - $184ADF63, $82311AE5, $60335197, $457F5362, $E07764B1, $84AE6BBB, $1CA081FE, $942B08F9, - $58684870, $19FD458F, $876CDE94, $B7F87B52, $23D373AB, $E2024B72, $578F1FE3, $2AAB5566, - $0728EBB2, $03C2B52F, $9A7BC586, $A50837D3, $F2872830, $B2A5BF23, $BA6A0302, $5C8216ED, - $2B1CCF8A, $92B479A7, $F0F207F3, $A1E2694E, $CDF4DA65, $D5BE0506, $1F6234D1, $8AFEA6C4, - $9D532E34, $A055F3A2, $32E18A05, $75EBF6A4, $39EC830B, $AAEF6040, $069F715E, $51106EBD, - $F98A213E, $3D06DD96, $AE053EDD, $46BDE64D, $B58D5491, $055DC471, $6FD40604, $FF155060, - $24FB9819, $97E9BDD6, $CC434089, $779ED967, $BD42E8B0, $888B8907, $385B19E7, $DBEEC879, - $470A7CA1, $E90F427C, $C91E84F8, $00000000, $83868009, $48ED2B32, $AC70111E, $4E725A6C, - $FBFF0EFD, $5638850F, $1ED5AE3D, $27392D36, $64D90F0A, $21A65C68, $D1545B9B, $3A2E3624, - $B1670A0C, $0FE75793, $D296EEB4, $9E919B1B, $4FC5C080, $A220DC61, $694B775A, $161A121C, - $0ABA93E2, $E52AA0C0, $43E0223C, $1D171B12, $0B0D090E, $ADC78BF2, $B9A8B62D, $C8A91E14, - $8519F157, $4C0775AF, $BBDD99EE, $FD607FA3, $9F2601F7, $BCF5725C, $C53B6644, $347EFB5B, - $7629438B, $DCC623CB, $68FCEDB6, $63F1E4B8, $CADC31D7, $10856342, $40229713, $2011C684, - $7D244A85, $F83DBBD2, $1132F9AE, $6DA129C7, $4B2F9E1D, $F330B2DC, $EC52860D, $D0E3C177, - $6C16B32B, $99B970A9, $FA489411, $2264E947, $C48CFCA8, $1A3FF0A0, $D82C7D56, $EF903322, - $C74E4987, $C1D138D9, $FEA2CA8C, $360BD498, $CF81F5A6, $28DE7AA5, $268EB7DA, $A4BFAD3F, - $E49D3A2C, $0D927850, $9BCC5F6A, $62467E54, $C2138DF6, $E8B8D890, $5EF7392E, $F5AFC382, - $BE805D9F, $7C93D069, $A92DD56F, $B31225CF, $3B99ACC8, $A77D1810, $6E639CE8, $7BBB3BDB, - $097826CD, $F418596E, $01B79AEC, $A89A4F83, $656E95E6, $7EE6FFAA, $08CFBC21, $E6E815EF, - $D99BE7BA, $CE366F4A, $D4099FEA, $D67CB029, $AFB2A431, $31233F2A, $3094A5C6, $C066A235, - $37BC4E74, $A6CA82FC, $B0D090E0, $15D8A733, $4A9804F1, $F7DAEC41, $0E50CD7F, $2FF69117, - $8DD64D76, $4DB0EF43, $544DAACC, $DF0496E4, $E3B5D19E, $1B886A4C, $B81F2CC1, $7F516546, - $04EA5E9D, $5D358C01, $737487FA, $2E410BFB, $5A1D67B3, $52D2DB92, $335610E9, $1347D66D, - $8C61D79A, $7A0CA137, $8E14F859, $893C13EB, $EE27A9CE, $35C961B7, $EDE51CE1, $3CB1477A, - $59DFD29C, $3F73F255, $79CE1418, $BF37C773, $EACDF753, $5BAAFD5F, $146F3DDF, $86DB4478, - $81F3AFCA, $3EC468B9, $2C342438, $5F40A3C2, $72C31D16, $0C25E2BC, $8B493C28, $41950DFF, - $7101A839, $DEB30C08, $9CE4B4D8, $90C15664, $6184CB7B, $70B632D5, $745C6C48, $4257B8D0 - ); - - LastInverseTable: array [0..255] of Cardinal = ( - $00000052, $00000009, $0000006A, $000000D5, $00000030, $00000036, $000000A5, $00000038, - $000000BF, $00000040, $000000A3, $0000009E, $00000081, $000000F3, $000000D7, $000000FB, - $0000007C, $000000E3, $00000039, $00000082, $0000009B, $0000002F, $000000FF, $00000087, - $00000034, $0000008E, $00000043, $00000044, $000000C4, $000000DE, $000000E9, $000000CB, - $00000054, $0000007B, $00000094, $00000032, $000000A6, $000000C2, $00000023, $0000003D, - $000000EE, $0000004C, $00000095, $0000000B, $00000042, $000000FA, $000000C3, $0000004E, - $00000008, $0000002E, $000000A1, $00000066, $00000028, $000000D9, $00000024, $000000B2, - $00000076, $0000005B, $000000A2, $00000049, $0000006D, $0000008B, $000000D1, $00000025, - $00000072, $000000F8, $000000F6, $00000064, $00000086, $00000068, $00000098, $00000016, - $000000D4, $000000A4, $0000005C, $000000CC, $0000005D, $00000065, $000000B6, $00000092, - $0000006C, $00000070, $00000048, $00000050, $000000FD, $000000ED, $000000B9, $000000DA, - $0000005E, $00000015, $00000046, $00000057, $000000A7, $0000008D, $0000009D, $00000084, - $00000090, $000000D8, $000000AB, $00000000, $0000008C, $000000BC, $000000D3, $0000000A, - $000000F7, $000000E4, $00000058, $00000005, $000000B8, $000000B3, $00000045, $00000006, - $000000D0, $0000002C, $0000001E, $0000008F, $000000CA, $0000003F, $0000000F, $00000002, - $000000C1, $000000AF, $000000BD, $00000003, $00000001, $00000013, $0000008A, $0000006B, - $0000003A, $00000091, $00000011, $00000041, $0000004F, $00000067, $000000DC, $000000EA, - $00000097, $000000F2, $000000CF, $000000CE, $000000F0, $000000B4, $000000E6, $00000073, - $00000096, $000000AC, $00000074, $00000022, $000000E7, $000000AD, $00000035, $00000085, - $000000E2, $000000F9, $00000037, $000000E8, $0000001C, $00000075, $000000DF, $0000006E, - $00000047, $000000F1, $0000001A, $00000071, $0000001D, $00000029, $000000C5, $00000089, - $0000006F, $000000B7, $00000062, $0000000E, $000000AA, $00000018, $000000BE, $0000001B, - $000000FC, $00000056, $0000003E, $0000004B, $000000C6, $000000D2, $00000079, $00000020, - $0000009A, $000000DB, $000000C0, $000000FE, $00000078, $000000CD, $0000005A, $000000F4, - $0000001F, $000000DD, $000000A8, $00000033, $00000088, $00000007, $000000C7, $00000031, - $000000B1, $00000012, $00000010, $00000059, $00000027, $00000080, $000000EC, $0000005F, - $00000060, $00000051, $0000007F, $000000A9, $00000019, $000000B5, $0000004A, $0000000D, - $0000002D, $000000E5, $0000007A, $0000009F, $00000093, $000000C9, $0000009C, $000000EF, - $000000A0, $000000E0, $0000003B, $0000004D, $000000AE, $0000002A, $000000F5, $000000B0, - $000000C8, $000000EB, $000000BB, $0000003C, $00000083, $00000053, $00000099, $00000061, - $00000017, $0000002B, $00000004, $0000007E, $000000BA, $00000077, $000000D6, $00000026, - $000000E1, $00000069, $00000014, $00000063, $00000055, $00000021, $0000000C, $0000007D - ); - -procedure ExpandAESKeyForEncryption128(const Key: TCnAESKey128; var ExpandedKey: - TCnAESExpandedKey128); -var - I, J: Integer; - T: Cardinal; - W0, W1, W2, W3: Cardinal; -begin - ExpandedKey[0] := PCardinal(@Key[0])^; - ExpandedKey[1] := PCardinal(@Key[4])^; - ExpandedKey[2] := PCardinal(@Key[8])^; - ExpandedKey[3] := PCardinal(@Key[12])^; - I := 0; J := 1; - repeat - T := (ExpandedKey[I + 3] shl 24) or (ExpandedKey[I + 3] shr 8); - W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)]; - W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)]; - ExpandedKey[I + 4] := ExpandedKey[I] xor - (W0 xor ((W1 shl 8) or (W1 shr 24)) xor - ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J]; - Inc(J); - ExpandedKey[I + 5] := ExpandedKey[I + 1] xor ExpandedKey[I + 4]; - ExpandedKey[I + 6] := ExpandedKey[I + 2] xor ExpandedKey[I + 5]; - ExpandedKey[I + 7] := ExpandedKey[I + 3] xor ExpandedKey[I + 6]; - Inc(I, 4); - until I >= 40; -end; - -procedure ExpandAESKeyForEncryption192(const Key: TCnAESKey192; var ExpandedKey: - TCnAESExpandedKey192); -var - I, J: Integer; - T: Cardinal; - W0, W1, W2, W3: Cardinal; -begin - ExpandedKey[0] := PCardinal(@Key[0])^; - ExpandedKey[1] := PCardinal(@Key[4])^; - ExpandedKey[2] := PCardinal(@Key[8])^; - ExpandedKey[3] := PCardinal(@Key[12])^; - ExpandedKey[4] := PCardinal(@Key[16])^; - ExpandedKey[5] := PCardinal(@Key[20])^; - I := 0; J := 1; - repeat - T := (ExpandedKey[I + 5] shl 24) or (ExpandedKey[I + 5] shr 8); - W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)]; - W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)]; - ExpandedKey[I + 6] := ExpandedKey[I] xor - (W0 xor ((W1 shl 8) or (W1 shr 24)) xor - ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J]; - Inc(J); - ExpandedKey[I + 7] := ExpandedKey[I + 1] xor ExpandedKey[I + 6]; - ExpandedKey[I + 8] := ExpandedKey[I + 2] xor ExpandedKey[I + 7]; - ExpandedKey[I + 9] := ExpandedKey[I + 3] xor ExpandedKey[I + 8]; - ExpandedKey[I + 10] := ExpandedKey[I + 4] xor ExpandedKey[I + 9]; - ExpandedKey[I + 11] := ExpandedKey[I + 5] xor ExpandedKey[I + 10]; - Inc(I, 6); - until I >= 46; -end; - -procedure ExpandAESKeyForEncryption256(const Key: TCnAESKey256; var ExpandedKey: - TCnAESExpandedKey256); -var - I, J: Integer; - T: Cardinal; - W0, W1, W2, W3: Cardinal; -begin - ExpandedKey[0] := PCardinal(@Key[0])^; - ExpandedKey[1] := PCardinal(@Key[4])^; - ExpandedKey[2] := PCardinal(@Key[8])^; - ExpandedKey[3] := PCardinal(@Key[12])^; - ExpandedKey[4] := PCardinal(@Key[16])^; - ExpandedKey[5] := PCardinal(@Key[20])^; - ExpandedKey[6] := PCardinal(@Key[24])^; - ExpandedKey[7] := PCardinal(@Key[28])^; - I := 0; J := 1; - repeat - T := (ExpandedKey[I + 7] shl 24) or (ExpandedKey[I + 7] shr 8); - W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)]; - W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)]; - ExpandedKey[I + 8] := ExpandedKey[I] xor - (W0 xor ((W1 shl 8) or (W1 shr 24)) xor - ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J]; - Inc(J); - ExpandedKey[I + 9] := ExpandedKey[I + 1] xor ExpandedKey[I + 8]; - ExpandedKey[I + 10] := ExpandedKey[I + 2] xor ExpandedKey[I + 9]; - ExpandedKey[I + 11] := ExpandedKey[I + 3] xor ExpandedKey[I + 10]; - W0 := LastForwardTable[Byte(ExpandedKey[I + 11])]; - W1 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 8)]; - W2 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 16)]; - W3 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 24)]; - ExpandedKey[I + 12] := ExpandedKey[I + 4] xor - (W0 xor ((W1 shl 8) or (W1 shr 24)) xor - ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))); - ExpandedKey[I + 13] := ExpandedKey[I + 5] xor ExpandedKey[I + 12]; - ExpandedKey[I + 14] := ExpandedKey[I + 6] xor ExpandedKey[I + 13]; - ExpandedKey[I + 15] := ExpandedKey[I + 7] xor ExpandedKey[I + 14]; - Inc(I, 8); - until I >= 52; -end; - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; - var OutBuf: TCnAESBuffer); -begin - EncryptAES128(InBuf, Key, OutBuf); -end; - -procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; - var OutBuf: TCnAESBuffer); -begin - EncryptAES192(InBuf, Key, OutBuf); -end; - -procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; - var OutBuf: TCnAESBuffer); -begin - EncryptAES256(InBuf, Key, OutBuf); -end; - -{$ENDIF} - -procedure EncryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; - var OutBuf: TCnAESBuffer); -var - T0, T1: array [0..3] of Cardinal; - W0, W1, W2, W3: Cardinal; -begin - // initializing - T0[0] := PCardinal(@InBuf[0])^ xor Key[0]; - T0[1] := PCardinal(@InBuf[4])^ xor Key[1]; - T0[2] := PCardinal(@InBuf[8])^ xor Key[2]; - T0[3] := PCardinal(@InBuf[12])^ xor Key[3]; - - // performing transformation 9 times - // round 1 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; - // round 2 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; - // round 3 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; - // round 4 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; - // round 5 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; - // round 6 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; - // round 7 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; - // round 8 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; - // round 9 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; - // last round of transformations - W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)]; - W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; - W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)]; - W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; - W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)]; - W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; - W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)]; - W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; - - // finalizing - PCardinal(@OutBuf[0])^ := T0[0]; - PCardinal(@OutBuf[4])^ := T0[1]; - PCardinal(@OutBuf[8])^ := T0[2]; - PCardinal(@OutBuf[12])^ := T0[3]; -end; - -procedure EncryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; - var OutBuf: TCnAESBuffer); -var - T0, T1: array [0..3] of Cardinal; - W0, W1, W2, W3: Cardinal; -begin - // initializing - T0[0] := PCardinal(@InBuf[0])^ xor Key[0]; - T0[1] := PCardinal(@InBuf[4])^ xor Key[1]; - T0[2] := PCardinal(@InBuf[8])^ xor Key[2]; - T0[3] := PCardinal(@InBuf[12])^ xor Key[3]; - - // performing transformation 11 times - // round 1 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; - // round 2 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; - // round 3 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; - // round 4 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; - // round 5 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; - // round 6 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; - // round 7 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; - // round 8 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; - // round 9 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; - // round 10 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; - // round 11 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; - // last round of transformations - W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)]; - W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[48]; - W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)]; - W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[49]; - W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)]; - W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[50]; - W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)]; - W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[51]; - - // finalizing - PCardinal(@OutBuf[0])^ := T0[0]; - PCardinal(@OutBuf[4])^ := T0[1]; - PCardinal(@OutBuf[8])^ := T0[2]; - PCardinal(@OutBuf[12])^ := T0[3]; -end; - -procedure EncryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; - var OutBuf: TCnAESBuffer); -var - T0, T1: array [0..3] of Cardinal; - W0, W1, W2, W3: Cardinal; -begin - // initializing - T0[0] := PCardinal(@InBuf[0])^ xor Key[0]; - T0[1] := PCardinal(@InBuf[4])^ xor Key[1]; - T0[2] := PCardinal(@InBuf[8])^ xor Key[2]; - T0[3] := PCardinal(@InBuf[12])^ xor Key[3]; - - // performing transformation 13 times - // round 1 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; - // round 2 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; - // round 3 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; - // round 4 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; - // round 5 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; - // round 6 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; - // round 7 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; - // round 8 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; - // round 9 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; - // round 10 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; - // round 11 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; - // round 12 - W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; - W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[48]; - W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; - W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[49]; - W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; - W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[50]; - W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; - W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[51]; - // round 13 - W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; - W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[52]; - W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; - W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[53]; - W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; - W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[54]; - W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; - W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[55]; - // last round of transformations - W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)]; - W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[56]; - W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)]; - W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[57]; - W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)]; - W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[58]; - W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)]; - W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[59]; - - // finalizing - PCardinal(@OutBuf[0])^ := T0[0]; - PCardinal(@OutBuf[4])^ := T0[1]; - PCardinal(@OutBuf[8])^ := T0[2]; - PCardinal(@OutBuf[12])^ := T0[3]; -end; - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey128); -begin - ExpandAESKeyForDecryption128(ExpandedKey); -end; - -procedure ExpandAESKeyForDecryption(const Key: TCnAESKey128; - var ExpandedKey: TCnAESExpandedKey128); -begin - ExpandAESKeyForDecryption128Expanded(Key, ExpandedKey); -end; - -procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey192); -begin - ExpandAESKeyForDecryption192(ExpandedKey); -end; - -procedure ExpandAESKeyForDecryption(const Key: TCnAESKey192; - var ExpandedKey: TCnAESExpandedKey192); -begin - ExpandAESKeyForDecryption192Expanded(Key, ExpandedKey); -end; - -procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey256); -begin - ExpandAESKeyForDecryption256(ExpandedKey); -end; - -procedure ExpandAESKeyForDecryption(const Key: TCnAESKey256; - var ExpandedKey: TCnAESExpandedKey256); -begin - ExpandAESKeyForDecryption256Expanded(Key, ExpandedKey); -end; - -{$ENDIF} - -procedure ExpandAESKeyForDecryption128(var ExpandedKey: TCnAESExpandedKey128); -var - I: Integer; - U, F2, F4, F8, F9: Cardinal; -begin - for I := 1 to 9 do - begin - F9 := ExpandedKey[I * 4]; - U := F9 and $80808080; - F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F2 and $80808080; - F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F4 and $80808080; - F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - F9 := F9 xor F8; - ExpandedKey[I * 4] := F2 xor F4 xor F8 xor - (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor - (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); - F9 := ExpandedKey[I * 4 + 1]; - U := F9 and $80808080; - F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F2 and $80808080; - F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F4 and $80808080; - F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - F9 := F9 xor F8; - ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor - (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor - (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); - F9 := ExpandedKey[I * 4 + 2]; - U := F9 and $80808080; - F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F2 and $80808080; - F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F4 and $80808080; - F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - F9 := F9 xor F8; - ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor - (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor - (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); - F9 := ExpandedKey[I * 4 + 3]; - U := F9 and $80808080; - F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F2 and $80808080; - F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F4 and $80808080; - F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - F9 := F9 xor F8; - ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor - (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor - (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); - end; -end; - -procedure ExpandAESKeyForDecryption128Expanded(const Key: TCnAESKey128; var ExpandedKey: - TCnAESExpandedKey128); -begin - ExpandAESKeyForEncryption128(Key, ExpandedKey); - ExpandAESKeyForDecryption128(ExpandedKey); -end; - -procedure ExpandAESKeyForDecryption192(var ExpandedKey: TCnAESExpandedKey192); -var - I: Integer; - U, F2, F4, F8, F9: Cardinal; -begin - for I := 1 to 11 do - begin - F9 := ExpandedKey[I * 4]; - U := F9 and $80808080; - F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F2 and $80808080; - F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F4 and $80808080; - F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - F9 := F9 xor F8; - ExpandedKey[I * 4] := F2 xor F4 xor F8 xor - (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor - (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); - F9 := ExpandedKey[I * 4 + 1]; - U := F9 and $80808080; - F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F2 and $80808080; - F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F4 and $80808080; - F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - F9 := F9 xor F8; - ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor - (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor - (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); - F9 := ExpandedKey[I * 4 + 2]; - U := F9 and $80808080; - F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F2 and $80808080; - F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F4 and $80808080; - F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - F9 := F9 xor F8; - ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor - (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor - (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); - F9 := ExpandedKey[I * 4 + 3]; - U := F9 and $80808080; - F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F2 and $80808080; - F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F4 and $80808080; - F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - F9 := F9 xor F8; - ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor - (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor - (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); - end; -end; - -procedure ExpandAESKeyForDecryption192Expanded(const Key: TCnAESKey192; var ExpandedKey: - TCnAESExpandedKey192); -begin - ExpandAESKeyForEncryption192(Key, ExpandedKey); - ExpandAESKeyForDecryption192(ExpandedKey); -end; - -procedure ExpandAESKeyForDecryption256(var ExpandedKey: TCnAESExpandedKey256); -var - I: Integer; - U, F2, F4, F8, F9: Cardinal; -begin - for I := 1 to 13 do - begin - F9 := ExpandedKey[I * 4]; - U := F9 and $80808080; - F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F2 and $80808080; - F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F4 and $80808080; - F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - F9 := F9 xor F8; - ExpandedKey[I * 4] := F2 xor F4 xor F8 xor - (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor - (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); - F9 := ExpandedKey[I * 4 + 1]; - U := F9 and $80808080; - F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F2 and $80808080; - F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F4 and $80808080; - F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - F9 := F9 xor F8; - ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor - (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor - (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); - F9 := ExpandedKey[I * 4 + 2]; - U := F9 and $80808080; - F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F2 and $80808080; - F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F4 and $80808080; - F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - F9 := F9 xor F8; - ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor - (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor - (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); - F9 := ExpandedKey[I * 4 + 3]; - U := F9 and $80808080; - F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F2 and $80808080; - F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - U := F4 and $80808080; - F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); - F9 := F9 xor F8; - ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor - (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor - (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); - end; -end; - -procedure ExpandAESKeyForDecryption256Expanded(const Key: TCnAESKey256; var ExpandedKey: - TCnAESExpandedKey256); -begin - ExpandAESKeyForEncryption256(Key, ExpandedKey); - ExpandAESKeyForDecryption256(ExpandedKey); -end; - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; - var OutBuf: TCnAESBuffer); -begin - DecryptAES128(InBuf, Key, OutBuf); -end; - -procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; - var OutBuf: TCnAESBuffer); -begin - DecryptAES192(InBuf, Key, OutBuf); -end; - -procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; - var OutBuf: TCnAESBuffer); -begin - DecryptAES256(InBuf, Key, OutBuf); -end; - -{$ENDIF} - -procedure DecryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; - var OutBuf: TCnAESBuffer); -var - T0, T1: array [0..3] of Cardinal; - W0, W1, W2, W3: Cardinal; -begin - // initializing - T0[0] := PCardinal(@InBuf[0])^ xor Key[40]; - T0[1] := PCardinal(@InBuf[4])^ xor Key[41]; - T0[2] := PCardinal(@InBuf[8])^ xor Key[42]; - T0[3] := PCardinal(@InBuf[12])^ xor Key[43]; - - // performing transformations 9 times - // round 1 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; - // round 2 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; - // round 3 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; - // round 4 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; - // round 5 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; - // round 6 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; - // round 7 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; - // round 8 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; - // round 9 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; - // last round of transformations - W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)]; - W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[0]; - W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)]; - W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[1]; - W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)]; - W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[2]; - W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)]; - W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[3]; - - // finalizing - PCardinal(@OutBuf[0])^ := T0[0]; - PCardinal(@OutBuf[4])^ := T0[1]; - PCardinal(@OutBuf[8])^ := T0[2]; - PCardinal(@OutBuf[12])^ := T0[3]; -end; - -procedure DecryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; - var OutBuf: TCnAESBuffer); -var - T0, T1: array [0..3] of Cardinal; - W0, W1, W2, W3: Cardinal; -begin - // initializing - T0[0] := PCardinal(@InBuf[0])^ xor Key[48]; - T0[1] := PCardinal(@InBuf[4])^ xor Key[49]; - T0[2] := PCardinal(@InBuf[8])^ xor Key[50]; - T0[3] := PCardinal(@InBuf[12])^ xor Key[51]; - - // performing transformations 11 times - // round 1 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; - // round 2 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; - // round 3 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; - // round 4 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; - // round 5 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; - // round 6 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; - // round 7 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; - // round 8 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; - // round 9 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; - // round 10 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; - // round 11 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; - // last round of transformations - W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)]; - W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[0]; - W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)]; - W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[1]; - W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)]; - W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[2]; - W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)]; - W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[3]; - - // finalizing - PCardinal(@OutBuf[0])^ := T0[0]; - PCardinal(@OutBuf[4])^ := T0[1]; - PCardinal(@OutBuf[8])^ := T0[2]; - PCardinal(@OutBuf[12])^ := T0[3]; -end; - -procedure DecryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; - var OutBuf: TCnAESBuffer); -var - T0, T1: array [0..3] of Cardinal; - W0, W1, W2, W3: Cardinal; -begin - // initializing - T0[0] := PCardinal(@InBuf[0])^ xor Key[56]; - T0[1] := PCardinal(@InBuf[4])^ xor Key[57]; - T0[2] := PCardinal(@InBuf[8])^ xor Key[58]; - T0[3] := PCardinal(@InBuf[12])^ xor Key[59]; - - // performing transformations 13 times - // round 1 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[52]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[53]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[54]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[55]; - // round 2 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[48]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[49]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[50]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[51]; - // round 3 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; - // round 4 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; - // round 5 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; - // round 6 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; - // round 7 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; - // round 8 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; - // round 9 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; - // round 10 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; - // round 11 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; - // round 12 - W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; - W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; - W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; - W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; - W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; - W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; - W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; - W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; - // round 13 - W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; - W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; - T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; - W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; - W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; - T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; - W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; - W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; - T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; - W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; - W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; - T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; - // last round of transformations - W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)]; - W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)]; - T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[0]; - W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)]; - W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)]; - T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[1]; - W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)]; - W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)]; - T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[2]; - W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)]; - W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)]; - T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) - xor ((W3 shl 24) or (W3 shr 8))) xor Key[3]; - - // finalizing - PCardinal(@OutBuf[0])^ := T0[0]; - PCardinal(@OutBuf[4])^ := T0[1]; - PCardinal(@OutBuf[8])^ := T0[2]; - PCardinal(@OutBuf[12])^ := T0[3]; -end; - -// Stream Encryption Routines (ECB mode) - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; Dest: TStream); -begin - EncryptAES128StreamECB(Source, Count, Key, Dest); -end; - -procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); -begin - EncryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); -end; - -procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; Dest: TStream); -begin - EncryptAES192StreamECB(Source, Count, Key, Dest); -end; - -procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); -begin - EncryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); -end; - -procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; Dest: TStream); -begin - EncryptAES256StreamECB(Source, Count, Key, Dest); -end; - -procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); -begin - EncryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); -end; - -{$ENDIF} - -procedure EncryptAES128StreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey128; -begin - ExpandAESKeyForEncryption128(Key, ExpandedKey); - EncryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); -end; - -procedure EncryptAES192StreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey192; -begin - ExpandAESKeyForEncryption192(Key, ExpandedKey); - EncryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); -end; - -procedure EncryptAES256StreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey256; -begin - ExpandAESKeyForEncryption256(Key, ExpandedKey); - EncryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); -end; - -procedure EncryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES128(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); - EncryptAES128(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -procedure EncryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES192(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); - EncryptAES192(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -procedure EncryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES256(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); - EncryptAES256(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -// Stream Decryption Routines (ECB mode) - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; Dest: TStream); -begin - DecryptAES128StreamECB(Source, Count, Key, Dest); -end; - -procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); -begin - DecryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); -end; - -procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; Dest: TStream); -begin - DecryptAES192StreamECB(Source, Count, Key, Dest); -end; - -procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); -begin - DecryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); -end; - -procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; Dest: TStream); -begin - DecryptAES256StreamECB(Source, Count, Key, Dest); -end; - -procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); -begin - DecryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); -end; - -{$ENDIF} - -procedure DecryptAES128StreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey128; -begin - ExpandAESKeyForDecryption128Expanded(Key, ExpandedKey); - DecryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); -end; - -procedure DecryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - if (Count mod SizeOf(TCnAESBuffer)) > 0 then - raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - DecryptAES128(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - Dec(Count, SizeOf(TCnAESBuffer)); - end; -end; - -procedure DecryptAES192StreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey192; -begin - ExpandAESKeyForDecryption192Expanded(Key, ExpandedKey); - DecryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); -end; - -procedure DecryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - if (Count mod SizeOf(TCnAESBuffer)) > 0 then - raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - DecryptAES192(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - Dec(Count, SizeOf(TCnAESBuffer)); - end; -end; - -procedure DecryptAES256StreamECB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey256; -begin - ExpandAESKeyForDecryption256Expanded(Key, ExpandedKey); - DecryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); -end; - -procedure DecryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - if (Count mod SizeOf(TCnAESBuffer)) > 0 then - raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - DecryptAES256(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - Dec(Count, SizeOf(TCnAESBuffer)); - end; -end; - -// Stream Encryption Routines (CBC mode) - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -begin - EncryptAES128StreamCBC(Source, Count, Key, InitVector, Dest); -end; - -procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - EncryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -begin - EncryptAES192StreamCBC(Source, Count, Key, InitVector, Dest); -end; - -procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - EncryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -begin - EncryptAES256StreamCBC(Source, Count, Key, InitVector, Dest); -end; - -procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - EncryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -{$ENDIF} - -procedure EncryptAES128StreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey128; -begin - ExpandAESKeyForEncryption128(Key, ExpandedKey); - EncryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut, Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); // Ҫÿһ鶼 - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; // ԭʼ IV - EncryptAES128(TempIn, ExpandedKey, TempOut); // ټ - Done := Dest.Write(TempOut, SizeOf(TempOut)); // д - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - Vector := TempOut; // ݴԭʼ IV һʹ - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; - EncryptAES128(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -procedure EncryptAES192StreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey192; -begin - ExpandAESKeyForEncryption192(Key, ExpandedKey); - EncryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut, Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; - EncryptAES192(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - Vector := TempOut; - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; - EncryptAES192(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -procedure EncryptAES256StreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey256; -begin - ExpandAESKeyForEncryption256(Key, ExpandedKey); - EncryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut, Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; - EncryptAES256(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - Vector := TempOut; - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; - EncryptAES256(TempIn, ExpandedKey, TempOut); - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -// Stream Decryption Routines (CBC mode) - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -begin - DecryptAES128StreamCBC(Source, Count, Key, InitVector, Dest); -end; - -procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - DecryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -begin - DecryptAES192StreamCBC(Source, Count, Key, InitVector, Dest); -end; - -procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - DecryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -begin - DecryptAES256StreamCBC(Source, Count, Key, InitVector, Dest); -end; - -procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - DecryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -{$ENDIF} - -procedure DecryptAES128StreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey128; -begin - ExpandAESKeyForDecryption128Expanded(Key, ExpandedKey); - DecryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Vector1, Vector2: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - if (Count mod SizeOf(TCnAESBuffer)) > 0 then - raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); - Vector1 := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorAESReadError); - Vector2 := TempIn; - DecryptAES128(TempIn, ExpandedKey, TempOut); - PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@Vector1[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@Vector1[12])^; - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError(SCnErrorAESWriteError); - Vector1 := Vector2; - Dec(Count, SizeOf(TCnAESBuffer)); - end; -end; - -procedure DecryptAES192StreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey192; -begin - ExpandAESKeyForDecryption192Expanded(Key, ExpandedKey); - DecryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Vector1, Vector2: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - if (Count mod SizeOf(TCnAESBuffer)) > 0 then - raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); - Vector1 := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorAESReadError); - Vector2 := TempIn; - DecryptAES192(TempIn, ExpandedKey, TempOut); - PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@Vector1[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@Vector1[12])^; - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError(SCnErrorAESWriteError); - Vector1 := Vector2; - Dec(Count, SizeOf(TCnAESBuffer)); - end; -end; - -procedure DecryptAES256StreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey256; -begin - ExpandAESKeyForDecryption256Expanded(Key, ExpandedKey); - DecryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Vector1, Vector2: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - if (Count mod SizeOf(TCnAESBuffer)) > 0 then - raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); // CBC Ϊ AES ֿܲģԱ - Vector1 := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorAESReadError); - Vector2 := TempIn; - DecryptAES256(TempIn, ExpandedKey, TempOut); // Ƚ - PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; // ܺݺ Iv õ - PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@Vector1[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@Vector1[12])^; - Done := Dest.Write(TempOut, SizeOf(TempOut)); // дȥ - if Done < SizeOf(TempOut) then - raise EStreamError(SCnErrorAESWriteError); - Vector1 := Vector2; // ȡ Iv Ϊһκͽ - Dec(Count, SizeOf(TCnAESBuffer)); - end; -end; - -// Stream Encryption Routines (CFB mode) - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -begin - EncryptAES128StreamCFB(Source, Count, Key, InitVector, Dest); -end; - -procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - EncryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -begin - EncryptAES192StreamCFB(Source, Count, Key, InitVector, Dest); -end; - -procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - EncryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -begin - EncryptAES256StreamCFB(Source, Count, Key, InitVector, Dest); -end; - -procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - EncryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -{$ENDIF} - -procedure EncryptAES128StreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey128; -begin - ExpandAESKeyForEncryption128(Key, ExpandedKey); - EncryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut, Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES128(Vector, ExpandedKey, TempOut); // Key ȼ Iv - PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ - PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempOut, SizeOf(TempOut)); // ĽдĽ - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - Vector := TempOut; // Ľȡ Iv һּ - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES128(Vector, ExpandedKey, TempOut); - PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempOut, Count); // дֻijȵIJ֣ - if Done < Count then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -procedure EncryptAES192StreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey192; -begin - ExpandAESKeyForEncryption192(Key, ExpandedKey); - EncryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut, Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES192(Vector, ExpandedKey, TempOut); - PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - Vector := TempOut; - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES192(Vector, ExpandedKey, TempOut); - PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempOut, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -procedure EncryptAES256StreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey256; -begin - ExpandAESKeyForEncryption256(Key, ExpandedKey); - EncryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut, Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES256(Vector, ExpandedKey, TempOut); - PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorAESWriteError); - Vector := TempOut; - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES256(Vector, ExpandedKey, TempOut); - PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempOut, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -// Stream Decryption Routines (CFB mode) - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -begin - DecryptAES128StreamCFB(Source, Count, Key, InitVector, Dest); -end; - -procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - DecryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -begin - DecryptAES192StreamCFB(Source, Count, Key, InitVector, Dest); -end; - -procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - DecryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -begin - DecryptAES256StreamCFB(Source, Count, Key, InitVector, Dest); -end; - -procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - DecryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -{$ENDIF} - -procedure DecryptAES128StreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey128; -begin - ExpandAESKeyForEncryption128(Key, ExpandedKey); - DecryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - // CFB Ϊ AES ֿܲĶ򣨳Ŀɶ - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); // - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorAESReadError); - EncryptAES128(Vector, ExpandedKey, TempOut); // Iv ȼܡעǼܣǽܣ - PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ - PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; - Done := Dest.Write(TempOut, SizeOf(TempOut)); // дȥ - if Done < SizeOf(TempOut) then - raise EStreamError(SCnErrorAESWriteError); - Vector := TempIn; // ȡ Iv Ϊһμ - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then // һ鲻Ϊ - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError(SCnErrorAESReadError); - EncryptAES128(Vector, ExpandedKey, TempOut); - PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ - PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; - Done := Dest.Write(TempOut, Count); // дȥ - if Done < Count then - raise EStreamError(SCnErrorAESWriteError); - end; -end; - -procedure DecryptAES192StreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey192; -begin - ExpandAESKeyForEncryption192(Key, ExpandedKey); - DecryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorAESReadError); - EncryptAES192(Vector, ExpandedKey, TempOut); - PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError(SCnErrorAESWriteError); - Vector := TempIn; - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError(SCnErrorAESReadError); - EncryptAES192(Vector, ExpandedKey, TempOut); - PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; - Done := Dest.Write(TempOut, Count); - if Done < Count then - raise EStreamError(SCnErrorAESWriteError); - end; -end; - -procedure DecryptAES256StreamCFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey256; -begin - ExpandAESKeyForEncryption256(Key, ExpandedKey); - DecryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorAESReadError); - EncryptAES256(Vector, ExpandedKey, TempOut); - PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError(SCnErrorAESWriteError); - Vector := TempIn; - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError(SCnErrorAESReadError); - EncryptAES256(Vector, ExpandedKey, TempOut); - PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; - PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; - PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; - Done := Dest.Write(TempOut, Count); - if Done < Count then - raise EStreamError(SCnErrorAESWriteError); - end; -end; - -// Stream Encryption Routines (OFB mode) - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -begin - EncryptAES128StreamOFB(Source, Count, Key, InitVector, Dest); -end; - -procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - EncryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -begin - EncryptAES192StreamOFB(Source, Count, Key, InitVector, Dest); -end; - -procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - EncryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -begin - EncryptAES256StreamOFB(Source, Count, Key, InitVector, Dest); -end; - -procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - EncryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -{$ENDIF} - -procedure EncryptAES128StreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey128; -begin - ExpandAESKeyForEncryption128(Key, ExpandedKey); - EncryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut, Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES128(Vector, ExpandedKey, TempOut); // Key ȼ Iv - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESWriteError); - Vector := TempOut; // ܽȡ Iv һּܣעⲻ - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES128(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ - if Done < Count then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -procedure EncryptAES192StreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey192; -begin - ExpandAESKeyForEncryption192(Key, ExpandedKey); - EncryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut, Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES192(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESWriteError); - Vector := TempOut; - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES192(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -procedure EncryptAES256StreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey256; -begin - ExpandAESKeyForEncryption256(Key, ExpandedKey); - EncryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure EncryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut, Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES256(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESWriteError); - Vector := TempOut; - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - EncryptAES256(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -// Stream Decryption Routines (OFB mode) - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -begin - DecryptAES128StreamOFB(Source, Count, Key, InitVector, Dest); -end; - -procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - DecryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -begin - DecryptAES192StreamOFB(Source, Count, Key, InitVector, Dest); -end; - -procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - DecryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -begin - DecryptAES256StreamOFB(Source, Count, Key, InitVector, Dest); -end; - -procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -begin - DecryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -{$ENDIF} - -procedure DecryptAES128StreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey128; -begin - ExpandAESKeyForEncryption128(Key, ExpandedKey); - DecryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - // OFB Ϊ AES ֿܲĶ򣨳Ŀɶ - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); // - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorAESReadError); - EncryptAES128(Vector, ExpandedKey, TempOut); // Iv ȼܡעǼܣǽܣ - PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ - PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; - Done := Dest.Write(TempIn, SizeOf(TempIn)); // дȥ - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorAESWriteError); - Vector := TempOut; // ȡ Iv Ϊһǰ - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then // һ鲻Ϊ - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError(SCnErrorAESReadError); - EncryptAES128(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ - PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; - Done := Dest.Write(TempIn, Count); // дȥ - if Done < Count then - raise EStreamError(SCnErrorAESWriteError); - end; -end; - -procedure DecryptAES192StreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey192; -begin - ExpandAESKeyForEncryption192(Key, ExpandedKey); - DecryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorAESReadError); - EncryptAES192(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; - Done := Dest.Write(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorAESWriteError); - Vector := TempOut; - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError(SCnErrorAESReadError); - EncryptAES192(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; - Done := Dest.Write(TempIn, Count); - if Done < Count then - raise EStreamError(SCnErrorAESWriteError); - end; -end; - -procedure DecryptAES256StreamOFB(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey256; -begin - ExpandAESKeyForEncryption256(Key, ExpandedKey); - DecryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); -end; - -procedure DecryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; - Dest: TStream); -var - TempIn, TempOut: TCnAESBuffer; - Vector: TCnAESBuffer; - Done: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Vector := InitVector; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorAESReadError); - EncryptAES256(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; - Done := Dest.Write(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorAESWriteError); - Vector := TempOut; - Dec(Count, SizeOf(TCnAESBuffer)); - end; - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError(SCnErrorAESReadError); - EncryptAES256(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; - Done := Dest.Write(TempIn, Count); - if Done < Count then - raise EStreamError(SCnErrorAESWriteError); - end; -end; - -// Stream Encryption Routines (CTR mode) - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - EncryptAES128StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); -end; - -procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - EncryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - EncryptAES192StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); -end; - -procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - EncryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - EncryptAES256StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); -end; - -procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - EncryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -{$ENDIF} - -procedure EncryptAES128StreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey128; -begin - ExpandAESKeyForEncryption128(Key, ExpandedKey); - EncryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -procedure EncryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -var - TempIn, TempOut, Vector: TCnAESBuffer; - Done, Cnt, T: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Cnt := 1; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - - Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); - Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); - T := UInt32HostToNetwork(Cnt); - Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); - - EncryptAES128(Vector, ExpandedKey, TempOut); // Key ȼƴ Iv - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESWriteError); - - Inc(Cnt); // һ - Dec(Count, SizeOf(TCnAESBuffer)); - end; - - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - - Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); - Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); - T := UInt32HostToNetwork(Cnt); - Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); - - EncryptAES128(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ - if Done < Count then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -procedure EncryptAES192StreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey192; -begin - ExpandAESKeyForEncryption192(Key, ExpandedKey); - EncryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -procedure EncryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -var - TempIn, TempOut, Vector: TCnAESBuffer; - Done, Cnt, T: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Cnt := 1; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - - Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); - Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); - T := UInt32HostToNetwork(Cnt); - Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); - - EncryptAES192(Vector, ExpandedKey, TempOut); // Key ȼƴ Iv - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESWriteError); - - Inc(Cnt); // һ - Dec(Count, SizeOf(TCnAESBuffer)); - end; - - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - - Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); - Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); - T := UInt32HostToNetwork(Cnt); - Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); - - EncryptAES192(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ - if Done < Count then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -procedure EncryptAES256StreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey256; -begin - ExpandAESKeyForEncryption256(Key, ExpandedKey); - EncryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -procedure EncryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -var - TempIn, TempOut, Vector: TCnAESBuffer; - Done, Cnt, T: Cardinal; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else Count := Min(Count, Source.Size - Source.Position); - if Count = 0 then Exit; - - Cnt := 1; - while Count >= SizeOf(TCnAESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESReadError); - - Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); - Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); - T := UInt32HostToNetwork(Cnt); - Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); - - EncryptAES256(Vector, ExpandedKey, TempOut); // Key ȼƴ Iv - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorAESWriteError); - - Inc(Cnt); // һ - Dec(Count, SizeOf(TCnAESBuffer)); - end; - - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorAESReadError); - - Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); - Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); - T := UInt32HostToNetwork(Cnt); - Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); - - EncryptAES256(Vector, ExpandedKey, TempOut); - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; - PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; - PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; - Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ - if Done < Count then - raise EStreamError.Create(SCnErrorAESWriteError); - end; -end; - -// Stream Decryption Routines (CTR mode) - -{$IFNDEF BCB5OR6} - -// C++Builder overload ⣬ Delphi ¿ -procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - DecryptAES128StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); -end; - -procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - DecryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - DecryptAES192StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); -end; - -procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - DecryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - DecryptAES256StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); -end; - -procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - DecryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -{$ENDIF} - -procedure DecryptAES128StreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey128; -begin - ExpandAESKeyForEncryption128(Key, ExpandedKey); - DecryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -procedure DecryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - EncryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -procedure DecryptAES192StreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey192; -begin - ExpandAESKeyForEncryption192(Key, ExpandedKey); - DecryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -procedure DecryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - EncryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -procedure DecryptAES256StreamCTR(Source: TStream; Count: Cardinal; - const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -var - ExpandedKey: TCnAESExpandedKey256; -begin - ExpandAESKeyForEncryption256(Key, ExpandedKey); - DecryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -procedure DecryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; - const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; - const InitVector: TCnAESCTRIv; Dest: TStream); -begin - EncryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); -end; - -// AES ECB ַתʮ -function AESEncryptEcbStrToHex(Value: AnsiString; Key: AnsiString; - KeyBit: TCnKeyBitType): AnsiString; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; -begin - Result := ''; - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[1])^, Length(Value)); - SS.Position := 0; - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - EncryptAES128StreamECB(SS, 0, AESKey128, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - EncryptAES192StreamECB(SS, 0, AESKey192, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - EncryptAES256StreamECB(SS, 0, AESKey256, DS); - end; - end; - - Result := AnsiString(DataToHex(DS.Memory, DS.Size)); - finally - SS.Free; - DS.Free; - end; -end; - -// AES ECB ʮַ -function AESDecryptEcbStrFromHex(const HexStr: AnsiString; Key: AnsiString; - KeyBit: TCnKeyBitType): AnsiString; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - Tmp: TBytes; -begin - Result := ''; - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - Tmp := HexToBytes(string(HexStr)); - SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); - SS.Position := 0; - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - DecryptAES128StreamECB(SS, SS.Size - SS.Position, AESKey128, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - DecryptAES192StreamECB(SS, SS.Size - SS.Position, AESKey192, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - DecryptAES256StreamECB(SS, SS.Size - SS.Position, AESKey256, DS); - end; - end; - - SetLength(Result, DS.Size); - Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES CBC ַתʮ -function AESEncryptCbcStrToHex(Value: AnsiString; Key: AnsiString; - const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; -begin - Result := ''; - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[1])^, Length(Value)); - SS.Position := 0; - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - EncryptAES128StreamCBC(SS, 0, AESKey128, Iv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - EncryptAES192StreamCBC(SS, 0, AESKey192, Iv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - EncryptAES256StreamCBC(SS, 0, AESKey256, Iv, DS); - end; - end; - - Result := AnsiString(DataToHex(DS.Memory, DS.Size)); - finally - SS.Free; - DS.Free; - end; -end; - -// AES CBC ʮַ -function AESDecryptCbcStrFromHex(const HexStr: AnsiString; Key: AnsiString; - const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - Tmp: TBytes; -begin - Result := ''; - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - Tmp := HexToBytes(string(HexStr)); - SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); - SS.Position := 0; - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - DecryptAES128StreamCBC(SS, SS.Size - SS.Position, AESKey128, Iv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - DecryptAES192StreamCBC(SS, SS.Size - SS.Position, AESKey192, Iv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - DecryptAES256StreamCBC(SS, SS.Size - SS.Position, AESKey256, Iv, DS); - end; - end; - - SetLength(Result, DS.Size); - Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES CFB ģʽַתʮ -function AESEncryptCfbStrToHex(Value: AnsiString; Key: AnsiString; - const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; -begin - Result := ''; - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[1])^, Length(Value)); - SS.Position := 0; - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - EncryptAES128StreamCFB(SS, 0, AESKey128, Iv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - EncryptAES192StreamCFB(SS, 0, AESKey192, Iv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - EncryptAES256StreamCFB(SS, 0, AESKey256, Iv, DS); - end; - end; - - Result := AnsiString(DataToHex(DS.Memory, DS.Size)); - finally - SS.Free; - DS.Free; - end; -end; - -// AES CFB ʮַ -function AESDecryptCfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; - const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - Tmp: TBytes; -begin - Result := ''; - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - Tmp := HexToBytes(string(HexStr)); - SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); - SS.Position := 0; - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - DecryptAES128StreamCFB(SS, SS.Size - SS.Position, AESKey128, Iv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - DecryptAES192StreamCFB(SS, SS.Size - SS.Position, AESKey192, Iv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - DecryptAES256StreamCFB(SS, SS.Size - SS.Position, AESKey256, Iv, DS); - end; - end; - - SetLength(Result, DS.Size); - Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES OFB ģʽַתʮ -function AESEncryptOfbStrToHex(Value: AnsiString; Key: AnsiString; - const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; -begin - Result := ''; - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[1])^, Length(Value)); - SS.Position := 0; - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - EncryptAES128StreamOFB(SS, 0, AESKey128, Iv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - EncryptAES192StreamOFB(SS, 0, AESKey192, Iv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - EncryptAES256StreamOFB(SS, 0, AESKey256, Iv, DS); - end; - end; - - Result := AnsiString(DataToHex(DS.Memory, DS.Size)); - finally - SS.Free; - DS.Free; - end; -end; - -// AES OFB ʮַ -function AESDecryptOfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; - const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - Tmp: TBytes; -begin - Result := ''; - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - Tmp := HexToBytes(string(HexStr)); - SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); - SS.Position := 0; - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - DecryptAES128StreamOFB(SS, SS.Size - SS.Position, AESKey128, Iv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - DecryptAES192StreamOFB(SS, SS.Size - SS.Position, AESKey192, Iv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - DecryptAES256StreamOFB(SS, SS.Size - SS.Position, AESKey256, Iv, DS); - end; - end; - - SetLength(Result, DS.Size); - Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES CTR ģʽַתʮ -function AESEncryptCtrStrToHex(Value: AnsiString; Key: AnsiString; - const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType): AnsiString; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; -begin - Result := ''; - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[1])^, Length(Value)); - SS.Position := 0; - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - EncryptAES128StreamCTR(SS, 0, AESKey128, Nonce, Iv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - EncryptAES192StreamCTR(SS, 0, AESKey192, Nonce, Iv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - EncryptAES256StreamCTR(SS, 0, AESKey256, Nonce, Iv, DS); - end; - end; - - Result := AnsiString(DataToHex(DS.Memory, DS.Size)); - finally - SS.Free; - DS.Free; - end; -end; - -// AES CTR ʮַ -function AESDecryptCtrStrFromHex(const HexStr: AnsiString; Key: AnsiString; - const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType): AnsiString; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - Tmp: TBytes; -begin - Result := ''; - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - Tmp := HexToBytes(string(HexStr)); - SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); - SS.Position := 0; - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - DecryptAES128StreamCTR(SS, SS.Size - SS.Position, AESKey128, Nonce, Iv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - DecryptAES192StreamCTR(SS, SS.Size - SS.Position, AESKey192, Nonce, Iv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - DecryptAES256StreamCTR(SS, SS.Size - SS.Position, AESKey256, Nonce, Iv, DS); - end; - end; - - SetLength(Result, DS.Size); - Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES ECB ģʽֽ -function AESEncryptEcbBytes(Value, Key: TBytes; KeyBit: TCnKeyBitType): TBytes; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; -begin - if Length(Value) <= 0 then - begin - Result := nil; - Exit; - end; - - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[0])^, Length(Value)); - SS.Position := 0; - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - EncryptAES128StreamECB(SS, 0, AESKey128, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - EncryptAES192StreamECB(SS, 0, AESKey192, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - EncryptAES256StreamECB(SS, 0, AESKey256, DS); - end; - end; - - SetLength(Result, DS.Size); - DS.Position := 0; - DS.Read(Result[0], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES ECB ģʽֽ -function AESDecryptEcbBytes(Value, Key: TBytes; KeyBit: TCnKeyBitType): TBytes; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; -begin - if Length(Value) <= 0 then - begin - Result := nil; - Exit; - end; - - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[0])^, Length(Value)); - SS.Position := 0; - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - DecryptAES128StreamECB(SS, SS.Size - SS.Position, AESKey128, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - DecryptAES192StreamECB(SS, SS.Size - SS.Position, AESKey192, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - DecryptAES256StreamECB(SS, SS.Size - SS.Position, AESKey256, DS); - end; - end; - - SetLength(Result, DS.Size); - DS.Position := 0; - DS.Read(Result[0], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES CBC ģʽֽ -function AESEncryptCbcBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - AESIv: TCnAESBuffer; -begin - if Length(Value) <= 0 then - begin - Result := nil; - Exit; - end; - - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[0])^, Length(Value)); - SS.Position := 0; - - FillChar(AESIv, SizeOF(AESIv), 0); - Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - EncryptAES128StreamCBC(SS, 0, AESKey128, AESIv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - EncryptAES192StreamCBC(SS, 0, AESKey192, AESIv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - EncryptAES256StreamCBC(SS, 0, AESKey256, AESIv, DS); - end; - end; - - SetLength(Result, DS.Size); - DS.Position := 0; - DS.Read(Result[0], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES CBC ģʽֽ -function AESDecryptCbcBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - AESIv: TCnAESBuffer; -begin - if Length(Value) <= 0 then - begin - Result := nil; - Exit; - end; - - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[0])^, Length(Value)); - SS.Position := 0; - - FillChar(AESIv, SizeOF(AESIv), 0); - Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - DecryptAES128StreamCBC(SS, SS.Size - SS.Position, AESKey128, AESIv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - DecryptAES192StreamCBC(SS, SS.Size - SS.Position, AESKey192, AESIv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - DecryptAES256StreamCBC(SS, SS.Size - SS.Position, AESKey256, AESIv, DS); - end; - end; - - SetLength(Result, DS.Size); - DS.Position := 0; - DS.Read(Result[0], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES CFB ģʽֽ -function AESEncryptCfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - AESIv: TCnAESBuffer; -begin - if Length(Value) <= 0 then - begin - Result := nil; - Exit; - end; - - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[0])^, Length(Value)); - SS.Position := 0; - - FillChar(AESIv, SizeOF(AESIv), 0); - Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - EncryptAES128StreamCFB(SS, 0, AESKey128, AESIv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - EncryptAES192StreamCFB(SS, 0, AESKey192, AESIv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - EncryptAES256StreamCFB(SS, 0, AESKey256, AESIv, DS); - end; - end; - - SetLength(Result, DS.Size); - DS.Position := 0; - DS.Read(Result[0], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES CFB ģʽֽ -function AESDecryptCfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - AESIv: TCnAESBuffer; -begin - if Length(Value) <= 0 then - begin - Result := nil; - Exit; - end; - - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[0])^, Length(Value)); - SS.Position := 0; - - FillChar(AESIv, SizeOF(AESIv), 0); - Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - DecryptAES128StreamCFB(SS, SS.Size - SS.Position, AESKey128, AESIv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - DecryptAES192StreamCFB(SS, SS.Size - SS.Position, AESKey192, AESIv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - DecryptAES256StreamCFB(SS, SS.Size - SS.Position, AESKey256, AESIv, DS); - end; - end; - - SetLength(Result, DS.Size); - DS.Position := 0; - DS.Read(Result[0], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES OFB ģʽֽ -function AESEncryptOfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - AESIv: TCnAESBuffer; -begin - if Length(Value) <= 0 then - begin - Result := nil; - Exit; - end; - - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[0])^, Length(Value)); - SS.Position := 0; - - FillChar(AESIv, SizeOF(AESIv), 0); - Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - EncryptAES128StreamOFB(SS, 0, AESKey128, AESIv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - EncryptAES192StreamOFB(SS, 0, AESKey192, AESIv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - EncryptAES256StreamOFB(SS, 0, AESKey256, AESIv, DS); - end; - end; - - SetLength(Result, DS.Size); - DS.Position := 0; - DS.Read(Result[0], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES OFB ģʽֽ -function AESDecryptOfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - AESIv: TCnAESBuffer; -begin - if Length(Value) <= 0 then - begin - Result := nil; - Exit; - end; - - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[0])^, Length(Value)); - SS.Position := 0; - - FillChar(AESIv, SizeOF(AESIv), 0); - Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - DecryptAES128StreamOFB(SS, SS.Size - SS.Position, AESKey128, AESIv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - DecryptAES192StreamOFB(SS, SS.Size - SS.Position, AESKey192, AESIv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - DecryptAES256StreamOFB(SS, SS.Size - SS.Position, AESKey256, AESIv, DS); - end; - end; - - SetLength(Result, DS.Size); - DS.Position := 0; - DS.Read(Result[0], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES CTR ģʽֽ -function AESEncryptCtrBytes(Value, Key, Nonce, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - AESIv: TCnAESCTRIv; - AESNonce: TCnAESCTRNonce; -begin - if Length(Value) <= 0 then - begin - Result := nil; - Exit; - end; - - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[0])^, Length(Value)); - SS.Position := 0; - - FillChar(AESIv, SizeOF(AESIv), 0); - Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); - - FillChar(AESNonce, SizeOF(AESNonce), 0); - Move(PAnsiChar(Nonce)^, AESNonce, Min(SizeOf(AESNonce), Length(Nonce))); - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - EncryptAES128StreamCTR(SS, 0, AESKey128, AESNonce, AESIv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - EncryptAES192StreamCTR(SS, 0, AESKey192, AESNonce, AESIv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - EncryptAES256StreamCTR(SS, 0, AESKey256, AESNonce, AESIv, DS); - end; - end; - - SetLength(Result, DS.Size); - DS.Position := 0; - DS.Read(Result[0], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES CTR ģʽֽ -function AESDecryptCtrBytes(Value, Key, Nonce, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; -var - SS, DS: TMemoryStream; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - AESIv: TCnAESCTRIv; - AESNonce: TCnAESCTRNonce; -begin - if Length(Value) <= 0 then - begin - Result := nil; - Exit; - end; - - SS := nil; - DS := nil; - - try - SS := TMemoryStream.Create; - SS.Write(PAnsiChar(@Value[0])^, Length(Value)); - SS.Position := 0; - - FillChar(AESIv, SizeOF(AESIv), 0); - Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); - - FillChar(AESNonce, SizeOF(AESNonce), 0); - Move(PAnsiChar(Nonce)^, AESNonce, Min(SizeOf(AESNonce), Length(Nonce))); - DS := TMemoryStream.Create; - - case KeyBit of - kbt128: - begin - FillChar(AESKey128, SizeOf(AESKey128), 0); - Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); - DecryptAES128StreamCTR(SS, SS.Size - SS.Position, AESKey128, AESNonce, AESIv, DS); - end; - kbt192: - begin - FillChar(AESKey192, SizeOf(AESKey192), 0); - Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); - DecryptAES192StreamCTR(SS, SS.Size - SS.Position, AESKey192, AESNonce, AESIv, DS); - end; - kbt256: - begin - FillChar(AESKey256, SizeOf(AESKey256), 0); - Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); - DecryptAES256StreamCTR(SS, SS.Size - SS.Position, AESKey256, AESNonce, AESIv, DS); - end; - end; - - SetLength(Result, DS.Size); - DS.Position := 0; - DS.Read(Result[0], DS.Size); - finally - SS.Free; - DS.Free; - end; -end; - -// AES ECB ģʽֽ鲢תʮ -function AESEncryptEcbBytesToHex(Value, Key: TBytes; KeyBit: TCnKeyBitType): AnsiString; -begin - Result := AnsiString(BytesToHex(AESEncryptEcbBytes(Value, Key, KeyBit))); -end; - -// AES ECB ʮַֽ -function AESDecryptEcbBytesFromHex(const HexStr: AnsiString; Key: TBytes; - KeyBit: TCnKeyBitType): TBytes; -begin - Result := AESDecryptEcbBytes(HexToBytes(string(HexStr)), Key, KeyBit); -end; - -// AES CBC ģʽֽ鲢תʮ -function AESEncryptCbcBytesToHex(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; -begin - Result := AnsiString(BytesToHex(AESEncryptCbcBytes(Value, Key, Iv, KeyBit))); -end; - -// AES CBC ʮַֽ -function AESDecryptCbcBytesFromHex(const HexStr: AnsiString; Key, Iv: TBytes; - KeyBit: TCnKeyBitType): TBytes; -begin - Result := AESDecryptCbcBytes(HexToBytes(string(HexStr)), Key, Iv, KeyBit); -end; - -// AES CFB ģʽֽ鲢תʮ -function AESEncryptCfbBytesToHex(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; -begin - Result := AnsiString(BytesToHex(AESEncryptCfbBytes(Value, Key, Iv, KeyBit))); -end; - -// AES CFB ʮַֽ -function AESDecryptCfbBytesFromHex(const HexStr: AnsiString; Key, Iv: TBytes; - KeyBit: TCnKeyBitType): TBytes; -begin - Result := AESDecryptCfbBytes(HexToBytes(string(HexStr)), Key, Iv, KeyBit); -end; - -// AES OFB ģʽֽ鲢תʮ -function AESEncryptOfbBytesToHex(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; -begin - Result := AnsiString(BytesToHex(AESEncryptOfbBytes(Value, Key, Iv, KeyBit))); -end; - -// AES OFB ʮַֽ -function AESDecryptOfbBytesFromHex(const HexStr: AnsiString; Key, Iv: TBytes; - KeyBit: TCnKeyBitType): TBytes; -begin - Result := AESDecryptOfbBytes(HexToBytes(string(HexStr)), Key, Iv, KeyBit); -end; - -// AES CTR ģʽֽ鲢תʮ -function AESEncryptCtrBytesToHex(Value, Key, Nonce, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; -begin - Result := AnsiString(BytesToHex(AESEncryptCtrBytes(Value, Key, Nonce, Iv, KeyBit))); -end; - -// AES CTR ʮַֽ -function AESDecryptCtrBytesFromHex(const HexStr: AnsiString; Key, Nonce, Iv: TBytes; - KeyBit: TCnKeyBitType): TBytes; -begin - Result := AESDecryptCtrBytes(HexToBytes(string(HexStr)), Key, Nonce, Iv, KeyBit); -end; - -end. - +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} +(******************************************************************************) +(* *) +(* Advanced Encryption Standard (AES) *) +(* *) +(* Copyright (c) 1998-2001 *) +(* EldoS, Alexander Ionov *) +(* *) +(******************************************************************************) + +unit CnAES; +{* |
+================================================================================
+* ƣ
+* ԪƣAES ԳƼӽ㷨ʵֵԪ
+* ԪߣCnPack  (master@cnpack.org)
+*            EldoS, Alexander Ionov ĵԪֲ书ܣԭаȨϢ
+*     עԪʵ AES 128/192/256 ԳƼӽ㷨ֿС̶ 16 ֽڣģʽ
+*           Ķ뷽ʽĩβ 0Ԫڲ֧ PKCS ȿ뷽ʽҪⲿ
+*           CnPemUtils.pas Ԫе PKCS ϵкԼӽݽж⴦
+*
+*           ߰汾 Delphi 뾡ʹ AnsiString 汾ĺʮƳ⣩
+*           ⲻַӰӽܽ
+*
+*           䣺============= Java Ĭϵ AES Ӧ˴ AES256 ============
+*           ⣬C++Builder 5/6 ¶ overload ĺʴжϴӶ
+*           ҵΣʱԪ˴ overload  Delphi ´ڣ
+*           ٷװ˲ֲͬĺ֧ C++Builder 5/6 ±С
+*
+*           ECB/CBC ǿģʽҪ롣CFB/OFB/CTR ĵģʽ뵽顣
+*
+*           ⣬CTR ģʽ RFC 3686 淶紫ݵ 4 ֽ Nonce8 ֽ
+*           ʼ4 ֽֽļƴ 16 ֽڵijʼ
+*            AES 㣬ӽܾΪĶ
+*
+* ƽ̨Delphi5 + Win 7
+* ޸ļ¼2024.07.25 V1.3
+*                CTR ģʽ֧֣ѭ RFC 3686 淶
+*           2024.05.26 V1.2
+*               䲿֧ C++Builder ĺ
+*           2022.06.21 V1.1
+*               뼸ֽ鵽ʮַ֮ļӽܺ
+*           2021.12.11 V1.2
+*                CFB/OFB ģʽ֧
+*           2019.04.15 V1.1
+*               ֧ Win32/Win64/MacOS
+*           2015.01.21 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + Classes, SysUtils, CnNative; + +const + CN_AES_BLOCKSIZE = 16; + {* AES ķܿСλ٣Ϊ 16 ֽ} + +type + TCnKeyBitType = (kbt128, kbt192, kbt256); + {* AES λ16 ֽڡ24 ֽں 32 ֽ} + + ECnAESException = class(Exception); + {* AES 쳣} + + TCnAESBuffer = array [0..15] of Byte; + {* AES ӽܿ 16 ֽ} + + TCnAESKey128 = array [0..15] of Byte; + {* AES128 Կṹ16 ֽ} + + TCnAESKey192 = array [0..23] of Byte; + {* AES192 Կṹ24 ֽ} + + TCnAESKey256 = array [0..31] of Byte; + {* AES256 Կṹ32 ֽ} + + TCnAESExpandedKey128 = array [0..43] of Cardinal; + {* AES128 չԿṹ} + + TCnAESExpandedKey192 = array [0..53] of Cardinal; + {* AES192 չԿṹ} + + TCnAESExpandedKey256 = array [0..63] of Cardinal; + {* AES256 չԿṹ} + + PCnAESBuffer = ^TCnAESBuffer; + PCnAESKey128 = ^TCnAESKey128; + PCnAESKey192 = ^TCnAESKey192; + PCnAESKey256 = ^TCnAESKey256; + PCnAESExpandedKey128 = ^TCnAESExpandedKey128; + PCnAESExpandedKey192 = ^TCnAESExpandedKey192; + PCnAESExpandedKey256 = ^TCnAESExpandedKey256; + + TCnAESCTRNonce = array[0..3] of Byte; + {* CTR ģʽµ Nonce ṹ4 ֽ} + TCnAESCTRIv = array[0..7] of Byte; + {* CTR ģʽµijʼṹ8 ֽ} + +// Key Expansion Routines for Encryption + +procedure ExpandAESKeyForEncryption128(const Key: TCnAESKey128; + var ExpandedKey: TCnAESExpandedKey128); +{* ڼܳչ AES128 Կ + + + const Key: TCnAESKey128 - չ AES128 Կ + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForEncryption192(const Key: TCnAESKey192; + var ExpandedKey: TCnAESExpandedKey192); +{* ڼܳչ AES192 Կ + + + const Key: TCnAESKey192 - չ AES192 Կ + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForEncryption256(const Key: TCnAESKey256; + var ExpandedKey: TCnAESExpandedKey256); +{* ڼܳչ AES256 Կ + + + const Key: TCnAESKey256 - չ AES256 Կ + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} + +// Block Encryption Routines ܣInBuf OutBuf ͬһ + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); overload; +{* AES128 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey128 - չ AES128 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); overload; +{* AES192 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey192 - չ AES192 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); overload; +{* AES256 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey256 - չ AES256 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +{* AES128 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey128 - չ AES128 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure EncryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +{* AES192 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey192 - չ AES192 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure EncryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +{* AES256 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey256 - չ AES256 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +// Stream Encryption Routines (ECB mode) ECB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); overload; +{* AES128 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); overload; +{* AES128 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); overload; +{* AES256 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); overload; +{* AES192 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); overload; +{* AES256 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); overload; +{* AES256 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +{* AES128 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +{* AES128 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES192StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +{* AES192 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +{* AES192 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES256StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +{* AES256 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +{* AES256 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + Dest: TStream - + + ֵޣ +} + +// Stream Encryption Routines (CBC mode) CBC + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES192StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES256StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Encryption Routines (CFB mode) CFB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Encryption Routines (OFB mode) OFB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES192StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - ?? + + ֵޣ +} +procedure EncryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES256StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Encryption Routines (CTR mode) CTR + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES128 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES128 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES192 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES192 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES256 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES256 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES128 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES128 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES192 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES192 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES256 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES256 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Key Transformation Routines for Decryption + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey128); overload; +{* ڽܳչ AES128 Կ + + + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey128; + var ExpandedKey: TCnAESExpandedKey128); overload; +{* ڽܳչ AES128 Կ + + + const Key: TCnAESKey128 - չ AES128 Կ + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey192); overload; +{* ڽܳչ AES192 Կ + + + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey192; + var ExpandedKey: TCnAESExpandedKey192); overload; +{* ڽܳչ AES192 Կ + + + const Key: TCnAESKey192 - չ AES192 Կ + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey256); overload; +{* ڽܳչ AES256 Կ + + + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey256; + var ExpandedKey: TCnAESExpandedKey256); overload; +{* ڽܳչ AES256 Կ + + + const Key: TCnAESKey256 - չ AES256 Կ + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure ExpandAESKeyForDecryption128(var ExpandedKey: TCnAESExpandedKey128); +{* ڽܳչ AES128 Կ + + + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption128Expanded(const Key: TCnAESKey128; + var ExpandedKey: TCnAESExpandedKey128); +{* ڽܳչ AES128 Կ + + + const Key: TCnAESKey128 - չ AES128 Կ + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption192(var ExpandedKey: TCnAESExpandedKey192); +{* ڽܳչ AES192 Կ + + + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption192Expanded(const Key: TCnAESKey192; + var ExpandedKey: TCnAESExpandedKey192); +{* ڽܳչ AES192 Կ + + + const Key: TCnAESKey192 - չ AES192 Կ + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption256(var ExpandedKey: TCnAESExpandedKey256); +{* ڽܳչ AES256 Կ + + + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption256Expanded(const Key: TCnAESKey256; + var ExpandedKey: TCnAESExpandedKey256); +{* ڽܳչ AES256 Կ + + + const Key: TCnAESKey256 - չ AES256 Կ + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} + +// Block Decryption Routines + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); overload; +{* AES128 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey128 - չ AES128 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); overload; +{* AES192 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey192 - չ AES192 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); overload; +{* AES256 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey256 - չ AES256 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +{* AES128 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey128 - չ AES128 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure DecryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +{* AES192 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey192 - չ AES192 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure DecryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +{* AES256 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey256 - չ AES256 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +// Stream Decryption Routines (ECB mode) ECB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); overload; +{* AES128 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); overload; +{* AES128 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); overload; +{* AES192 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); overload; +{* AES192 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); overload; +{* AES256 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); overload; +{* AES256 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +{* AES128 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +{* AES128 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAES192StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +{* AES192 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +{* AES192 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAES256StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +{* AES256 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +{* AES156 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + Dest: TStream - + + ֵޣ +} + +// Stream Decryption Routines (CBC mode) CBC + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Decryption Routines (CFB mode) CFB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Decryption Routines (OFB mode) OFB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Decryption Routines (CTR mode) CTR + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES128 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES128 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES192 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES192 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES256 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES256 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES128 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES128 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES192 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES192 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES256 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES256 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// ============== ַʮַ֮ļӽ =================== + +function AESEncryptEcbStrToHex(Value: AnsiString; Key: AnsiString; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES ECB ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptEcbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES ECB ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +function AESEncryptCbcStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CBC ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCbcStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CBC ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +function AESEncryptCfbStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CFB ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CFB ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +function AESEncryptOfbStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES OFB ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptOfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES OFB ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +function AESEncryptCtrStrToHex(Value: AnsiString; Key: AnsiString; + const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CTR ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const Iv: TCnAESCTRIv - 8 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCtrStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CTR ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const Iv: TCnAESCTRIv - 8 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +// ================= ֽֽ֮ļӽ ==================== + +function AESEncryptEcbBytes(Value: TBytes; Key: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES ECB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptEcbBytes(Value: TBytes; Key: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES ECB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCbcBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CBC ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptCbcBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CBC ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CFB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptCfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CFB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptOfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES OFB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptOfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES OFB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCtrBytes(Value: TBytes; Key: TBytes; Nonce: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CTR ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Nonce: TBytes - 4 ֽ Nonce 飬̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptCtrBytes(Value: TBytes; Key: TBytes; Nonce: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CTR ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Nonce: TBytes - 4 ֽ Nonce 飬̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +// ============== ֽʮַ֮ļӽ ================= + +function AESEncryptEcbBytesToHex(Value: TBytes; Key: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES ECB ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptEcbBytesFromHex(const HexStr: AnsiString; Key: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES ECB ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCbcBytesToHex(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CBC ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCbcBytesFromHex(const HexStr: AnsiString; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CBC ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCfbBytesToHex(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CFB ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCfbBytesFromHex(const HexStr: AnsiString; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CFB ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptOfbBytesToHex(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES OFB ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptOfbBytesFromHex(const HexStr: AnsiString; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES OFB ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCtrBytesToHex(Value: TBytes; Key: TBytes; Nonce: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CTR ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Nonce: TBytes - 4 ֽ Nonce ֽ飬̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCtrBytesFromHex(const HexStr: AnsiString; Key: TBytes; Nonce: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CTR ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Nonce: TBytes - 4 ֽ Nonce ֽ飬̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +implementation + +resourcestring + SCnErrorAESInvalidInBufSize = 'Invalid Buffer Size for Decryption'; + SCnErrorAESReadError = 'Stream Read Error'; + SCnErrorAESWriteError = 'Stream Write Error'; + +function Min(A, B: Integer): Integer; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + if A < B then + Result := A + else + Result := B; +end; + +const + Rcon: array [1..30] of Cardinal = ( + $00000001, $00000002, $00000004, $00000008, $00000010, $00000020, + $00000040, $00000080, $0000001B, $00000036, $0000006C, $000000D8, + $000000AB, $0000004D, $0000009A, $0000002F, $0000005E, $000000BC, + $00000063, $000000C6, $00000097, $00000035, $0000006A, $000000D4, + $000000B3, $0000007D, $000000FA, $000000EF, $000000C5, $00000091 + ); + + ForwardTable: array [0..255] of Cardinal = ( + $A56363C6, $847C7CF8, $997777EE, $8D7B7BF6, $0DF2F2FF, $BD6B6BD6, $B16F6FDE, $54C5C591, + $50303060, $03010102, $A96767CE, $7D2B2B56, $19FEFEE7, $62D7D7B5, $E6ABAB4D, $9A7676EC, + $45CACA8F, $9D82821F, $40C9C989, $877D7DFA, $15FAFAEF, $EB5959B2, $C947478E, $0BF0F0FB, + $ECADAD41, $67D4D4B3, $FDA2A25F, $EAAFAF45, $BF9C9C23, $F7A4A453, $967272E4, $5BC0C09B, + $C2B7B775, $1CFDFDE1, $AE93933D, $6A26264C, $5A36366C, $413F3F7E, $02F7F7F5, $4FCCCC83, + $5C343468, $F4A5A551, $34E5E5D1, $08F1F1F9, $937171E2, $73D8D8AB, $53313162, $3F15152A, + $0C040408, $52C7C795, $65232346, $5EC3C39D, $28181830, $A1969637, $0F05050A, $B59A9A2F, + $0907070E, $36121224, $9B80801B, $3DE2E2DF, $26EBEBCD, $6927274E, $CDB2B27F, $9F7575EA, + $1B090912, $9E83831D, $742C2C58, $2E1A1A34, $2D1B1B36, $B26E6EDC, $EE5A5AB4, $FBA0A05B, + $F65252A4, $4D3B3B76, $61D6D6B7, $CEB3B37D, $7B292952, $3EE3E3DD, $712F2F5E, $97848413, + $F55353A6, $68D1D1B9, $00000000, $2CEDEDC1, $60202040, $1FFCFCE3, $C8B1B179, $ED5B5BB6, + $BE6A6AD4, $46CBCB8D, $D9BEBE67, $4B393972, $DE4A4A94, $D44C4C98, $E85858B0, $4ACFCF85, + $6BD0D0BB, $2AEFEFC5, $E5AAAA4F, $16FBFBED, $C5434386, $D74D4D9A, $55333366, $94858511, + $CF45458A, $10F9F9E9, $06020204, $817F7FFE, $F05050A0, $443C3C78, $BA9F9F25, $E3A8A84B, + $F35151A2, $FEA3A35D, $C0404080, $8A8F8F05, $AD92923F, $BC9D9D21, $48383870, $04F5F5F1, + $DFBCBC63, $C1B6B677, $75DADAAF, $63212142, $30101020, $1AFFFFE5, $0EF3F3FD, $6DD2D2BF, + $4CCDCD81, $140C0C18, $35131326, $2FECECC3, $E15F5FBE, $A2979735, $CC444488, $3917172E, + $57C4C493, $F2A7A755, $827E7EFC, $473D3D7A, $AC6464C8, $E75D5DBA, $2B191932, $957373E6, + $A06060C0, $98818119, $D14F4F9E, $7FDCDCA3, $66222244, $7E2A2A54, $AB90903B, $8388880B, + $CA46468C, $29EEEEC7, $D3B8B86B, $3C141428, $79DEDEA7, $E25E5EBC, $1D0B0B16, $76DBDBAD, + $3BE0E0DB, $56323264, $4E3A3A74, $1E0A0A14, $DB494992, $0A06060C, $6C242448, $E45C5CB8, + $5DC2C29F, $6ED3D3BD, $EFACAC43, $A66262C4, $A8919139, $A4959531, $37E4E4D3, $8B7979F2, + $32E7E7D5, $43C8C88B, $5937376E, $B76D6DDA, $8C8D8D01, $64D5D5B1, $D24E4E9C, $E0A9A949, + $B46C6CD8, $FA5656AC, $07F4F4F3, $25EAEACF, $AF6565CA, $8E7A7AF4, $E9AEAE47, $18080810, + $D5BABA6F, $887878F0, $6F25254A, $722E2E5C, $241C1C38, $F1A6A657, $C7B4B473, $51C6C697, + $23E8E8CB, $7CDDDDA1, $9C7474E8, $211F1F3E, $DD4B4B96, $DCBDBD61, $868B8B0D, $858A8A0F, + $907070E0, $423E3E7C, $C4B5B571, $AA6666CC, $D8484890, $05030306, $01F6F6F7, $120E0E1C, + $A36161C2, $5F35356A, $F95757AE, $D0B9B969, $91868617, $58C1C199, $271D1D3A, $B99E9E27, + $38E1E1D9, $13F8F8EB, $B398982B, $33111122, $BB6969D2, $70D9D9A9, $898E8E07, $A7949433, + $B69B9B2D, $221E1E3C, $92878715, $20E9E9C9, $49CECE87, $FF5555AA, $78282850, $7ADFDFA5, + $8F8C8C03, $F8A1A159, $80898909, $170D0D1A, $DABFBF65, $31E6E6D7, $C6424284, $B86868D0, + $C3414182, $B0999929, $772D2D5A, $110F0F1E, $CBB0B07B, $FC5454A8, $D6BBBB6D, $3A16162C + ); + + LastForwardTable: array [0..255] of Cardinal = ( + $00000063, $0000007C, $00000077, $0000007B, $000000F2, $0000006B, $0000006F, $000000C5, + $00000030, $00000001, $00000067, $0000002B, $000000FE, $000000D7, $000000AB, $00000076, + $000000CA, $00000082, $000000C9, $0000007D, $000000FA, $00000059, $00000047, $000000F0, + $000000AD, $000000D4, $000000A2, $000000AF, $0000009C, $000000A4, $00000072, $000000C0, + $000000B7, $000000FD, $00000093, $00000026, $00000036, $0000003F, $000000F7, $000000CC, + $00000034, $000000A5, $000000E5, $000000F1, $00000071, $000000D8, $00000031, $00000015, + $00000004, $000000C7, $00000023, $000000C3, $00000018, $00000096, $00000005, $0000009A, + $00000007, $00000012, $00000080, $000000E2, $000000EB, $00000027, $000000B2, $00000075, + $00000009, $00000083, $0000002C, $0000001A, $0000001B, $0000006E, $0000005A, $000000A0, + $00000052, $0000003B, $000000D6, $000000B3, $00000029, $000000E3, $0000002F, $00000084, + $00000053, $000000D1, $00000000, $000000ED, $00000020, $000000FC, $000000B1, $0000005B, + $0000006A, $000000CB, $000000BE, $00000039, $0000004A, $0000004C, $00000058, $000000CF, + $000000D0, $000000EF, $000000AA, $000000FB, $00000043, $0000004D, $00000033, $00000085, + $00000045, $000000F9, $00000002, $0000007F, $00000050, $0000003C, $0000009F, $000000A8, + $00000051, $000000A3, $00000040, $0000008F, $00000092, $0000009D, $00000038, $000000F5, + $000000BC, $000000B6, $000000DA, $00000021, $00000010, $000000FF, $000000F3, $000000D2, + $000000CD, $0000000C, $00000013, $000000EC, $0000005F, $00000097, $00000044, $00000017, + $000000C4, $000000A7, $0000007E, $0000003D, $00000064, $0000005D, $00000019, $00000073, + $00000060, $00000081, $0000004F, $000000DC, $00000022, $0000002A, $00000090, $00000088, + $00000046, $000000EE, $000000B8, $00000014, $000000DE, $0000005E, $0000000B, $000000DB, + $000000E0, $00000032, $0000003A, $0000000A, $00000049, $00000006, $00000024, $0000005C, + $000000C2, $000000D3, $000000AC, $00000062, $00000091, $00000095, $000000E4, $00000079, + $000000E7, $000000C8, $00000037, $0000006D, $0000008D, $000000D5, $0000004E, $000000A9, + $0000006C, $00000056, $000000F4, $000000EA, $00000065, $0000007A, $000000AE, $00000008, + $000000BA, $00000078, $00000025, $0000002E, $0000001C, $000000A6, $000000B4, $000000C6, + $000000E8, $000000DD, $00000074, $0000001F, $0000004B, $000000BD, $0000008B, $0000008A, + $00000070, $0000003E, $000000B5, $00000066, $00000048, $00000003, $000000F6, $0000000E, + $00000061, $00000035, $00000057, $000000B9, $00000086, $000000C1, $0000001D, $0000009E, + $000000E1, $000000F8, $00000098, $00000011, $00000069, $000000D9, $0000008E, $00000094, + $0000009B, $0000001E, $00000087, $000000E9, $000000CE, $00000055, $00000028, $000000DF, + $0000008C, $000000A1, $00000089, $0000000D, $000000BF, $000000E6, $00000042, $00000068, + $00000041, $00000099, $0000002D, $0000000F, $000000B0, $00000054, $000000BB, $00000016 + ); + + InverseTable: array [0..255] of Cardinal = ( + $50A7F451, $5365417E, $C3A4171A, $965E273A, $CB6BAB3B, $F1459D1F, $AB58FAAC, $9303E34B, + $55FA3020, $F66D76AD, $9176CC88, $254C02F5, $FCD7E54F, $D7CB2AC5, $80443526, $8FA362B5, + $495AB1DE, $671BBA25, $980EEA45, $E1C0FE5D, $02752FC3, $12F04C81, $A397468D, $C6F9D36B, + $E75F8F03, $959C9215, $EB7A6DBF, $DA595295, $2D83BED4, $D3217458, $2969E049, $44C8C98E, + $6A89C275, $78798EF4, $6B3E5899, $DD71B927, $B64FE1BE, $17AD88F0, $66AC20C9, $B43ACE7D, + $184ADF63, $82311AE5, $60335197, $457F5362, $E07764B1, $84AE6BBB, $1CA081FE, $942B08F9, + $58684870, $19FD458F, $876CDE94, $B7F87B52, $23D373AB, $E2024B72, $578F1FE3, $2AAB5566, + $0728EBB2, $03C2B52F, $9A7BC586, $A50837D3, $F2872830, $B2A5BF23, $BA6A0302, $5C8216ED, + $2B1CCF8A, $92B479A7, $F0F207F3, $A1E2694E, $CDF4DA65, $D5BE0506, $1F6234D1, $8AFEA6C4, + $9D532E34, $A055F3A2, $32E18A05, $75EBF6A4, $39EC830B, $AAEF6040, $069F715E, $51106EBD, + $F98A213E, $3D06DD96, $AE053EDD, $46BDE64D, $B58D5491, $055DC471, $6FD40604, $FF155060, + $24FB9819, $97E9BDD6, $CC434089, $779ED967, $BD42E8B0, $888B8907, $385B19E7, $DBEEC879, + $470A7CA1, $E90F427C, $C91E84F8, $00000000, $83868009, $48ED2B32, $AC70111E, $4E725A6C, + $FBFF0EFD, $5638850F, $1ED5AE3D, $27392D36, $64D90F0A, $21A65C68, $D1545B9B, $3A2E3624, + $B1670A0C, $0FE75793, $D296EEB4, $9E919B1B, $4FC5C080, $A220DC61, $694B775A, $161A121C, + $0ABA93E2, $E52AA0C0, $43E0223C, $1D171B12, $0B0D090E, $ADC78BF2, $B9A8B62D, $C8A91E14, + $8519F157, $4C0775AF, $BBDD99EE, $FD607FA3, $9F2601F7, $BCF5725C, $C53B6644, $347EFB5B, + $7629438B, $DCC623CB, $68FCEDB6, $63F1E4B8, $CADC31D7, $10856342, $40229713, $2011C684, + $7D244A85, $F83DBBD2, $1132F9AE, $6DA129C7, $4B2F9E1D, $F330B2DC, $EC52860D, $D0E3C177, + $6C16B32B, $99B970A9, $FA489411, $2264E947, $C48CFCA8, $1A3FF0A0, $D82C7D56, $EF903322, + $C74E4987, $C1D138D9, $FEA2CA8C, $360BD498, $CF81F5A6, $28DE7AA5, $268EB7DA, $A4BFAD3F, + $E49D3A2C, $0D927850, $9BCC5F6A, $62467E54, $C2138DF6, $E8B8D890, $5EF7392E, $F5AFC382, + $BE805D9F, $7C93D069, $A92DD56F, $B31225CF, $3B99ACC8, $A77D1810, $6E639CE8, $7BBB3BDB, + $097826CD, $F418596E, $01B79AEC, $A89A4F83, $656E95E6, $7EE6FFAA, $08CFBC21, $E6E815EF, + $D99BE7BA, $CE366F4A, $D4099FEA, $D67CB029, $AFB2A431, $31233F2A, $3094A5C6, $C066A235, + $37BC4E74, $A6CA82FC, $B0D090E0, $15D8A733, $4A9804F1, $F7DAEC41, $0E50CD7F, $2FF69117, + $8DD64D76, $4DB0EF43, $544DAACC, $DF0496E4, $E3B5D19E, $1B886A4C, $B81F2CC1, $7F516546, + $04EA5E9D, $5D358C01, $737487FA, $2E410BFB, $5A1D67B3, $52D2DB92, $335610E9, $1347D66D, + $8C61D79A, $7A0CA137, $8E14F859, $893C13EB, $EE27A9CE, $35C961B7, $EDE51CE1, $3CB1477A, + $59DFD29C, $3F73F255, $79CE1418, $BF37C773, $EACDF753, $5BAAFD5F, $146F3DDF, $86DB4478, + $81F3AFCA, $3EC468B9, $2C342438, $5F40A3C2, $72C31D16, $0C25E2BC, $8B493C28, $41950DFF, + $7101A839, $DEB30C08, $9CE4B4D8, $90C15664, $6184CB7B, $70B632D5, $745C6C48, $4257B8D0 + ); + + LastInverseTable: array [0..255] of Cardinal = ( + $00000052, $00000009, $0000006A, $000000D5, $00000030, $00000036, $000000A5, $00000038, + $000000BF, $00000040, $000000A3, $0000009E, $00000081, $000000F3, $000000D7, $000000FB, + $0000007C, $000000E3, $00000039, $00000082, $0000009B, $0000002F, $000000FF, $00000087, + $00000034, $0000008E, $00000043, $00000044, $000000C4, $000000DE, $000000E9, $000000CB, + $00000054, $0000007B, $00000094, $00000032, $000000A6, $000000C2, $00000023, $0000003D, + $000000EE, $0000004C, $00000095, $0000000B, $00000042, $000000FA, $000000C3, $0000004E, + $00000008, $0000002E, $000000A1, $00000066, $00000028, $000000D9, $00000024, $000000B2, + $00000076, $0000005B, $000000A2, $00000049, $0000006D, $0000008B, $000000D1, $00000025, + $00000072, $000000F8, $000000F6, $00000064, $00000086, $00000068, $00000098, $00000016, + $000000D4, $000000A4, $0000005C, $000000CC, $0000005D, $00000065, $000000B6, $00000092, + $0000006C, $00000070, $00000048, $00000050, $000000FD, $000000ED, $000000B9, $000000DA, + $0000005E, $00000015, $00000046, $00000057, $000000A7, $0000008D, $0000009D, $00000084, + $00000090, $000000D8, $000000AB, $00000000, $0000008C, $000000BC, $000000D3, $0000000A, + $000000F7, $000000E4, $00000058, $00000005, $000000B8, $000000B3, $00000045, $00000006, + $000000D0, $0000002C, $0000001E, $0000008F, $000000CA, $0000003F, $0000000F, $00000002, + $000000C1, $000000AF, $000000BD, $00000003, $00000001, $00000013, $0000008A, $0000006B, + $0000003A, $00000091, $00000011, $00000041, $0000004F, $00000067, $000000DC, $000000EA, + $00000097, $000000F2, $000000CF, $000000CE, $000000F0, $000000B4, $000000E6, $00000073, + $00000096, $000000AC, $00000074, $00000022, $000000E7, $000000AD, $00000035, $00000085, + $000000E2, $000000F9, $00000037, $000000E8, $0000001C, $00000075, $000000DF, $0000006E, + $00000047, $000000F1, $0000001A, $00000071, $0000001D, $00000029, $000000C5, $00000089, + $0000006F, $000000B7, $00000062, $0000000E, $000000AA, $00000018, $000000BE, $0000001B, + $000000FC, $00000056, $0000003E, $0000004B, $000000C6, $000000D2, $00000079, $00000020, + $0000009A, $000000DB, $000000C0, $000000FE, $00000078, $000000CD, $0000005A, $000000F4, + $0000001F, $000000DD, $000000A8, $00000033, $00000088, $00000007, $000000C7, $00000031, + $000000B1, $00000012, $00000010, $00000059, $00000027, $00000080, $000000EC, $0000005F, + $00000060, $00000051, $0000007F, $000000A9, $00000019, $000000B5, $0000004A, $0000000D, + $0000002D, $000000E5, $0000007A, $0000009F, $00000093, $000000C9, $0000009C, $000000EF, + $000000A0, $000000E0, $0000003B, $0000004D, $000000AE, $0000002A, $000000F5, $000000B0, + $000000C8, $000000EB, $000000BB, $0000003C, $00000083, $00000053, $00000099, $00000061, + $00000017, $0000002B, $00000004, $0000007E, $000000BA, $00000077, $000000D6, $00000026, + $000000E1, $00000069, $00000014, $00000063, $00000055, $00000021, $0000000C, $0000007D + ); + +procedure ExpandAESKeyForEncryption128(const Key: TCnAESKey128; var ExpandedKey: + TCnAESExpandedKey128); +var + I, J: Integer; + T: Cardinal; + W0, W1, W2, W3: Cardinal; +begin + ExpandedKey[0] := PCardinal(@Key[0])^; + ExpandedKey[1] := PCardinal(@Key[4])^; + ExpandedKey[2] := PCardinal(@Key[8])^; + ExpandedKey[3] := PCardinal(@Key[12])^; + I := 0; J := 1; + repeat + T := (ExpandedKey[I + 3] shl 24) or (ExpandedKey[I + 3] shr 8); + W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)]; + W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)]; + ExpandedKey[I + 4] := ExpandedKey[I] xor + (W0 xor ((W1 shl 8) or (W1 shr 24)) xor + ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J]; + Inc(J); + ExpandedKey[I + 5] := ExpandedKey[I + 1] xor ExpandedKey[I + 4]; + ExpandedKey[I + 6] := ExpandedKey[I + 2] xor ExpandedKey[I + 5]; + ExpandedKey[I + 7] := ExpandedKey[I + 3] xor ExpandedKey[I + 6]; + Inc(I, 4); + until I >= 40; +end; + +procedure ExpandAESKeyForEncryption192(const Key: TCnAESKey192; var ExpandedKey: + TCnAESExpandedKey192); +var + I, J: Integer; + T: Cardinal; + W0, W1, W2, W3: Cardinal; +begin + ExpandedKey[0] := PCardinal(@Key[0])^; + ExpandedKey[1] := PCardinal(@Key[4])^; + ExpandedKey[2] := PCardinal(@Key[8])^; + ExpandedKey[3] := PCardinal(@Key[12])^; + ExpandedKey[4] := PCardinal(@Key[16])^; + ExpandedKey[5] := PCardinal(@Key[20])^; + I := 0; J := 1; + repeat + T := (ExpandedKey[I + 5] shl 24) or (ExpandedKey[I + 5] shr 8); + W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)]; + W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)]; + ExpandedKey[I + 6] := ExpandedKey[I] xor + (W0 xor ((W1 shl 8) or (W1 shr 24)) xor + ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J]; + Inc(J); + ExpandedKey[I + 7] := ExpandedKey[I + 1] xor ExpandedKey[I + 6]; + ExpandedKey[I + 8] := ExpandedKey[I + 2] xor ExpandedKey[I + 7]; + ExpandedKey[I + 9] := ExpandedKey[I + 3] xor ExpandedKey[I + 8]; + ExpandedKey[I + 10] := ExpandedKey[I + 4] xor ExpandedKey[I + 9]; + ExpandedKey[I + 11] := ExpandedKey[I + 5] xor ExpandedKey[I + 10]; + Inc(I, 6); + until I >= 46; +end; + +procedure ExpandAESKeyForEncryption256(const Key: TCnAESKey256; var ExpandedKey: + TCnAESExpandedKey256); +var + I, J: Integer; + T: Cardinal; + W0, W1, W2, W3: Cardinal; +begin + ExpandedKey[0] := PCardinal(@Key[0])^; + ExpandedKey[1] := PCardinal(@Key[4])^; + ExpandedKey[2] := PCardinal(@Key[8])^; + ExpandedKey[3] := PCardinal(@Key[12])^; + ExpandedKey[4] := PCardinal(@Key[16])^; + ExpandedKey[5] := PCardinal(@Key[20])^; + ExpandedKey[6] := PCardinal(@Key[24])^; + ExpandedKey[7] := PCardinal(@Key[28])^; + I := 0; J := 1; + repeat + T := (ExpandedKey[I + 7] shl 24) or (ExpandedKey[I + 7] shr 8); + W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)]; + W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)]; + ExpandedKey[I + 8] := ExpandedKey[I] xor + (W0 xor ((W1 shl 8) or (W1 shr 24)) xor + ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J]; + Inc(J); + ExpandedKey[I + 9] := ExpandedKey[I + 1] xor ExpandedKey[I + 8]; + ExpandedKey[I + 10] := ExpandedKey[I + 2] xor ExpandedKey[I + 9]; + ExpandedKey[I + 11] := ExpandedKey[I + 3] xor ExpandedKey[I + 10]; + W0 := LastForwardTable[Byte(ExpandedKey[I + 11])]; + W1 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 8)]; + W2 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 16)]; + W3 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 24)]; + ExpandedKey[I + 12] := ExpandedKey[I + 4] xor + (W0 xor ((W1 shl 8) or (W1 shr 24)) xor + ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))); + ExpandedKey[I + 13] := ExpandedKey[I + 5] xor ExpandedKey[I + 12]; + ExpandedKey[I + 14] := ExpandedKey[I + 6] xor ExpandedKey[I + 13]; + ExpandedKey[I + 15] := ExpandedKey[I + 7] xor ExpandedKey[I + 14]; + Inc(I, 8); + until I >= 52; +end; + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +begin + EncryptAES128(InBuf, Key, OutBuf); +end; + +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +begin + EncryptAES192(InBuf, Key, OutBuf); +end; + +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +begin + EncryptAES256(InBuf, Key, OutBuf); +end; + +{$ENDIF} + +procedure EncryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[0]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[1]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[2]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[3]; + + // performing transformation 9 times + // round 1 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // round 2 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 3 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 4 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 5 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 6 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 7 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 8 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 9 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // last round of transformations + W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)]; + W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)]; + W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)]; + W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)]; + W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +procedure EncryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[0]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[1]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[2]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[3]; + + // performing transformation 11 times + // round 1 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // round 2 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 3 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 4 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 5 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 6 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 7 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 8 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 9 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 10 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + // round 11 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; + // last round of transformations + W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)]; + W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[48]; + W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)]; + W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[49]; + W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)]; + W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[50]; + W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)]; + W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[51]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +procedure EncryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[0]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[1]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[2]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[3]; + + // performing transformation 13 times + // round 1 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // round 2 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 3 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 4 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 5 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 6 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 7 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 8 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 9 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 10 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + // round 11 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; + // round 12 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[48]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[49]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[50]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[51]; + // round 13 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[52]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[53]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[54]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[55]; + // last round of transformations + W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)]; + W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[56]; + W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)]; + W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[57]; + W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)]; + W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[58]; + W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)]; + W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[59]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey128); +begin + ExpandAESKeyForDecryption128(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey128; + var ExpandedKey: TCnAESExpandedKey128); +begin + ExpandAESKeyForDecryption128Expanded(Key, ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey192); +begin + ExpandAESKeyForDecryption192(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey192; + var ExpandedKey: TCnAESExpandedKey192); +begin + ExpandAESKeyForDecryption192Expanded(Key, ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey256); +begin + ExpandAESKeyForDecryption256(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey256; + var ExpandedKey: TCnAESExpandedKey256); +begin + ExpandAESKeyForDecryption256Expanded(Key, ExpandedKey); +end; + +{$ENDIF} + +procedure ExpandAESKeyForDecryption128(var ExpandedKey: TCnAESExpandedKey128); +var + I: Integer; + U, F2, F4, F8, F9: Cardinal; +begin + for I := 1 to 9 do + begin + F9 := ExpandedKey[I * 4]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 1]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 2]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 3]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + end; +end; + +procedure ExpandAESKeyForDecryption128Expanded(const Key: TCnAESKey128; var ExpandedKey: + TCnAESExpandedKey128); +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + ExpandAESKeyForDecryption128(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption192(var ExpandedKey: TCnAESExpandedKey192); +var + I: Integer; + U, F2, F4, F8, F9: Cardinal; +begin + for I := 1 to 11 do + begin + F9 := ExpandedKey[I * 4]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 1]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 2]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 3]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + end; +end; + +procedure ExpandAESKeyForDecryption192Expanded(const Key: TCnAESKey192; var ExpandedKey: + TCnAESExpandedKey192); +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + ExpandAESKeyForDecryption192(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption256(var ExpandedKey: TCnAESExpandedKey256); +var + I: Integer; + U, F2, F4, F8, F9: Cardinal; +begin + for I := 1 to 13 do + begin + F9 := ExpandedKey[I * 4]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 1]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 2]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 3]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + end; +end; + +procedure ExpandAESKeyForDecryption256Expanded(const Key: TCnAESKey256; var ExpandedKey: + TCnAESExpandedKey256); +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + ExpandAESKeyForDecryption256(ExpandedKey); +end; + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +begin + DecryptAES128(InBuf, Key, OutBuf); +end; + +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +begin + DecryptAES192(InBuf, Key, OutBuf); +end; + +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +begin + DecryptAES256(InBuf, Key, OutBuf); +end; + +{$ENDIF} + +procedure DecryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[40]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[41]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[42]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[43]; + + // performing transformations 9 times + // round 1 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 2 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 3 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 4 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 5 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 6 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 7 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 8 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 9 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // last round of transformations + W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)]; + W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[0]; + W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)]; + W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[1]; + W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)]; + W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[2]; + W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)]; + W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[3]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +procedure DecryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[48]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[49]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[50]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[51]; + + // performing transformations 11 times + // round 1 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; + // round 2 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + // round 3 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 4 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 5 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 6 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 7 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 8 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 9 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 10 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 11 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // last round of transformations + W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)]; + W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[0]; + W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)]; + W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[1]; + W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)]; + W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[2]; + W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)]; + W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[3]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +procedure DecryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[56]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[57]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[58]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[59]; + + // performing transformations 13 times + // round 1 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[52]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[53]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[54]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[55]; + // round 2 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[48]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[49]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[50]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[51]; + // round 3 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; + // round 4 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + // round 5 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 6 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 7 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 8 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 9 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 10 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 11 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 12 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 13 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // last round of transformations + W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)]; + W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[0]; + W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)]; + W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[1]; + W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)]; + W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[2]; + W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)]; + W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[3]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +// Stream Encryption Routines (ECB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +begin + EncryptAES128StreamECB(Source, Count, Key, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +begin + EncryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +begin + EncryptAES192StreamECB(Source, Count, Key, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +begin + EncryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +begin + EncryptAES256StreamECB(Source, Count, Key, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +begin + EncryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAES192StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAES256StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + EncryptAES128(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + EncryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + EncryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (ECB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +begin + DecryptAES128StreamECB(Source, Count, Key, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +begin + DecryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +begin + DecryptAES192StreamECB(Source, Count, Key, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +begin + DecryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +begin + DecryptAES256StreamECB(Source, Count, Key, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +begin + DecryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForDecryption128Expanded(Key, ExpandedKey); + DecryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + DecryptAES128(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +procedure DecryptAES192StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForDecryption192Expanded(Key, ExpandedKey); + DecryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + DecryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +procedure DecryptAES256StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForDecryption256Expanded(Key, ExpandedKey); + DecryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + DecryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +// Stream Encryption Routines (CBC mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES128StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES192StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES256StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); // Ҫÿһ鶼 + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; // ԭʼ IV + EncryptAES128(TempIn, ExpandedKey, TempOut); // ټ + Done := Dest.Write(TempOut, SizeOf(TempOut)); // д + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; // ݴԭʼ IV һʹ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES128(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (CBC mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES128StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES192StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES256StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForDecryption128Expanded(Key, ExpandedKey); + DecryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector1, Vector2: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + Vector1 := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + Vector2 := TempIn; + DecryptAES128(TempIn, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@Vector1[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@Vector1[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector1 := Vector2; + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +procedure DecryptAES192StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForDecryption192Expanded(Key, ExpandedKey); + DecryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector1, Vector2: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + Vector1 := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + Vector2 := TempIn; + DecryptAES192(TempIn, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@Vector1[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@Vector1[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector1 := Vector2; + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +procedure DecryptAES256StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForDecryption256Expanded(Key, ExpandedKey); + DecryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector1, Vector2: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); // CBC Ϊ AES ֿܲģԱ + Vector1 := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + Vector2 := TempIn; + DecryptAES256(TempIn, ExpandedKey, TempOut); // Ƚ + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; // ܺݺ Iv õ + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@Vector1[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@Vector1[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); // дȥ + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector1 := Vector2; // ȡ Iv Ϊһκͽ + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +// Stream Encryption Routines (CFB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES128StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES192StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES256StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); // Key ȼ Iv + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); // ĽдĽ + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; // Ľȡ Iv һּ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (CFB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES128StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES192StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES256StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + DecryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + // CFB Ϊ AES ֿܲĶ򣨳Ŀɶ + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); // + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); // Iv ȼܡעǼܣǽܣ + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); // дȥ + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempIn; // ȡ Iv Ϊһμ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then // һ鲻Ϊ + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, Count); // дȥ + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +procedure DecryptAES192StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + DecryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempIn; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, Count); + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +procedure DecryptAES256StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + DecryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempIn; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, Count); + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +// Stream Encryption Routines (OFB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES128StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES192StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES256StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); // Key ȼ Iv + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; // ܽȡ Iv һּܣעⲻ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (OFB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES128StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES192StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES256StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + DecryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + // OFB Ϊ AES ֿܲĶ򣨳Ŀɶ + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); // + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); // Iv ȼܡעǼܣǽܣ + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // дȥ + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempOut; // ȡ Iv Ϊһǰ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then // һ鲻Ϊ + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, Count); // дȥ + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +procedure DecryptAES192StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + DecryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +procedure DecryptAES256StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + DecryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +// Stream Encryption Routines (CTR mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES128StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES192StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES256StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done, Cnt, T: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Cnt := 1; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES128(Vector, ExpandedKey, TempOut); // Key ȼƴ Iv + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + + Inc(Cnt); // һ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done, Cnt, T: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Cnt := 1; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES192(Vector, ExpandedKey, TempOut); // Key ȼƴ Iv + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + + Inc(Cnt); // һ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done, Cnt, T: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Cnt := 1; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES256(Vector, ExpandedKey, TempOut); // Key ȼƴ Iv + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + + Inc(Cnt); // һ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (CTR mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES128StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES192StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES256StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + DecryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES192StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + DecryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES256StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + DecryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +// AES ECB ַתʮ +function AESEncryptEcbStrToHex(Value: AnsiString; Key: AnsiString; + KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamECB(SS, 0, AESKey128, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamECB(SS, 0, AESKey192, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamECB(SS, 0, AESKey256, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES ECB ʮַ +function AESDecryptEcbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamECB(SS, SS.Size - SS.Position, AESKey128, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamECB(SS, SS.Size - SS.Position, AESKey192, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamECB(SS, SS.Size - SS.Position, AESKey256, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CBC ַתʮ +function AESEncryptCbcStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCBC(SS, 0, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCBC(SS, 0, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCBC(SS, 0, AESKey256, Iv, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CBC ʮַ +function AESDecryptCbcStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCBC(SS, SS.Size - SS.Position, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCBC(SS, SS.Size - SS.Position, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCBC(SS, SS.Size - SS.Position, AESKey256, Iv, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CFB ģʽַתʮ +function AESEncryptCfbStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCFB(SS, 0, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCFB(SS, 0, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCFB(SS, 0, AESKey256, Iv, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CFB ʮַ +function AESDecryptCfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCFB(SS, SS.Size - SS.Position, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCFB(SS, SS.Size - SS.Position, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCFB(SS, SS.Size - SS.Position, AESKey256, Iv, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES OFB ģʽַתʮ +function AESEncryptOfbStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamOFB(SS, 0, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamOFB(SS, 0, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamOFB(SS, 0, AESKey256, Iv, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES OFB ʮַ +function AESDecryptOfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamOFB(SS, SS.Size - SS.Position, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamOFB(SS, SS.Size - SS.Position, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamOFB(SS, SS.Size - SS.Position, AESKey256, Iv, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CTR ģʽַתʮ +function AESEncryptCtrStrToHex(Value: AnsiString; Key: AnsiString; + const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCTR(SS, 0, AESKey128, Nonce, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCTR(SS, 0, AESKey192, Nonce, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCTR(SS, 0, AESKey256, Nonce, Iv, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CTR ʮַ +function AESDecryptCtrStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCTR(SS, SS.Size - SS.Position, AESKey128, Nonce, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCTR(SS, SS.Size - SS.Position, AESKey192, Nonce, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCTR(SS, SS.Size - SS.Position, AESKey256, Nonce, Iv, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES ECB ģʽֽ +function AESEncryptEcbBytes(Value, Key: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamECB(SS, 0, AESKey128, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamECB(SS, 0, AESKey192, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamECB(SS, 0, AESKey256, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES ECB ģʽֽ +function AESDecryptEcbBytes(Value, Key: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamECB(SS, SS.Size - SS.Position, AESKey128, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamECB(SS, SS.Size - SS.Position, AESKey192, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamECB(SS, SS.Size - SS.Position, AESKey256, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CBC ģʽֽ +function AESEncryptCbcBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCBC(SS, 0, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCBC(SS, 0, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCBC(SS, 0, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CBC ģʽֽ +function AESDecryptCbcBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCBC(SS, SS.Size - SS.Position, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCBC(SS, SS.Size - SS.Position, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCBC(SS, SS.Size - SS.Position, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CFB ģʽֽ +function AESEncryptCfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCFB(SS, 0, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCFB(SS, 0, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCFB(SS, 0, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CFB ģʽֽ +function AESDecryptCfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCFB(SS, SS.Size - SS.Position, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCFB(SS, SS.Size - SS.Position, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCFB(SS, SS.Size - SS.Position, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES OFB ģʽֽ +function AESEncryptOfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamOFB(SS, 0, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamOFB(SS, 0, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamOFB(SS, 0, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES OFB ģʽֽ +function AESDecryptOfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamOFB(SS, SS.Size - SS.Position, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamOFB(SS, SS.Size - SS.Position, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamOFB(SS, SS.Size - SS.Position, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CTR ģʽֽ +function AESEncryptCtrBytes(Value, Key, Nonce, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESCTRIv; + AESNonce: TCnAESCTRNonce; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + + FillChar(AESNonce, SizeOF(AESNonce), 0); + Move(PAnsiChar(Nonce)^, AESNonce, Min(SizeOf(AESNonce), Length(Nonce))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCTR(SS, 0, AESKey128, AESNonce, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCTR(SS, 0, AESKey192, AESNonce, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCTR(SS, 0, AESKey256, AESNonce, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CTR ģʽֽ +function AESDecryptCtrBytes(Value, Key, Nonce, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESCTRIv; + AESNonce: TCnAESCTRNonce; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + + FillChar(AESNonce, SizeOF(AESNonce), 0); + Move(PAnsiChar(Nonce)^, AESNonce, Min(SizeOf(AESNonce), Length(Nonce))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCTR(SS, SS.Size - SS.Position, AESKey128, AESNonce, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCTR(SS, SS.Size - SS.Position, AESKey192, AESNonce, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCTR(SS, SS.Size - SS.Position, AESKey256, AESNonce, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES ECB ģʽֽ鲢תʮ +function AESEncryptEcbBytesToHex(Value, Key: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptEcbBytes(Value, Key, KeyBit))); +end; + +// AES ECB ʮַֽ +function AESDecryptEcbBytesFromHex(const HexStr: AnsiString; Key: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptEcbBytes(HexToBytes(string(HexStr)), Key, KeyBit); +end; + +// AES CBC ģʽֽ鲢תʮ +function AESEncryptCbcBytesToHex(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptCbcBytes(Value, Key, Iv, KeyBit))); +end; + +// AES CBC ʮַֽ +function AESDecryptCbcBytesFromHex(const HexStr: AnsiString; Key, Iv: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptCbcBytes(HexToBytes(string(HexStr)), Key, Iv, KeyBit); +end; + +// AES CFB ģʽֽ鲢תʮ +function AESEncryptCfbBytesToHex(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptCfbBytes(Value, Key, Iv, KeyBit))); +end; + +// AES CFB ʮַֽ +function AESDecryptCfbBytesFromHex(const HexStr: AnsiString; Key, Iv: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptCfbBytes(HexToBytes(string(HexStr)), Key, Iv, KeyBit); +end; + +// AES OFB ģʽֽ鲢תʮ +function AESEncryptOfbBytesToHex(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptOfbBytes(Value, Key, Iv, KeyBit))); +end; + +// AES OFB ʮַֽ +function AESDecryptOfbBytesFromHex(const HexStr: AnsiString; Key, Iv: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptOfbBytes(HexToBytes(string(HexStr)), Key, Iv, KeyBit); +end; + +// AES CTR ģʽֽ鲢תʮ +function AESEncryptCtrBytesToHex(Value, Key, Nonce, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptCtrBytes(Value, Key, Nonce, Iv, KeyBit))); +end; + +// AES CTR ʮַֽ +function AESDecryptCtrBytesFromHex(const HexStr: AnsiString; Key, Nonce, Iv: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptCtrBytes(HexToBytes(string(HexStr)), Key, Nonce, Iv, KeyBit); +end; + +end. + diff --git a/CnPack/Crypto/CnBase64.pas b/CnPack/Crypto/CnBase64.pas index cfe7dc1..a8e3130 100644 --- a/CnPack/Crypto/CnBase64.pas +++ b/CnPack/Crypto/CnBase64.pas @@ -1,547 +1,547 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -{ -----------------------------------------------------------------------------} -{ uTBase64 v1.0 - Simple Base64 encoding/decoding class } -{ Base64 described in RFC2045, Page 24, (w) 1996 Freed & Borenstein } -{ Delphi implementation (w) 1999 Dennis D. Spreen (dennis@spreendigital.de) } -{ This unit is freeware. Just drop me a line if this unit is useful for you. } -{ -----------------------------------------------------------------------------} - -unit CnBase64; -{* |
-================================================================================
-* ƣ
-* ԪƣBase64 㷨ʵֵԪ
-* ԪߣղSolin solin@21cn.com; http://www.ilovezhuzhu.net
-*           wr960204
-*           CnPack  (master@cnpack.org)
-*           ݻ Dennis D. Spreen  UTBASE64.pas дԭаȨϢ
-*     עԪʵ˱׼ Base64  Base64URL ı빦ܡ
-*           Base64URL ڱ׼ Base64ѷ + / 滻 - _  URL 
-*           Ѻãɾβ =
-*
-* ƽ̨PWin2003Std + Delphi 6.0
-* ݲԣδ
-*   õԪ豾ػ
-* ޸ļ¼2023.10.04 V1.6
-*               ɾʵ֡Base64Encode  Base64Decode ֧ Base64URL ı
-*           2019.12.12 V1.5
-*               ֧ TBytes
-*           2019.04.15 V1.4
-*               ֧ Win32/Win64/MacOS
-*           2018.06.22 V1.3
-*               ԭʼݿܰ #0 ԭʼβ #0 Ƴ
-*           2016.05.03 V1.2
-*               ַа #0 ʱܻᱻضϵ
-*           2006.10.25 V1.1
-*                wr960204 Ż汾
-*           2003.10.14 V1.0
-*               Ԫ
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - SysUtils, Classes, CnNative, CnConsts; - -const - ECN_BASE64_OK = ECN_OK; // תɹ - {* Base64 ϵд룺޴ֵΪ 0} - ECN_BASE64_ERROR_BASE = ECN_CUSTOM_ERROR_BASE + $500; - {* Base64 ϵдĻ׼ʼֵΪ ECN_CUSTOM_ERROR_BASE $500} - - ECN_BASE64_LENGTH = ECN_BASE64_ERROR_BASE + 1; - {* Base64 ֮ݳȷǷ} - -function Base64Encode(InputData: TStream; var OutputData: string; - URL: Boolean = False): Integer; overload; -{* Base64 Base64URL 룬ɹ ECN_BASE64_OK - - - InputData: TStream - - var OutputData: string - ַ - URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 - - ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK -} - -function Base64Encode(const InputData: AnsiString; var OutputData: string; - URL: Boolean = False): Integer; overload; -{* ַ Base64 Base64URL 룬ɹ ECN_BASE64_OK - - - const InputData: AnsiString - ַ - var OutputData: string - ַ - URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 - - ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK -} - -function Base64Encode(InputData: Pointer; DataByteLen: Integer; var OutputData: string; - URL: Boolean = False): Integer; overload; -{* ݿ Base64 Base64URL 룬ɹ ECN_BASE64_OK - - - InputData: Pointer - ݿַ - DataByteLen: Integer - ݿֽڳ - var OutputData: string - ַ - URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 - - ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK -} - -function Base64Encode(InputData: TBytes; var OutputData: string; - URL: Boolean = False): Integer; overload; -{* ֽ Base64 Base64URL 룬ɹ ECN_BASE64_OK - - - InputData: TBytes - ֽ - var OutputData: string - ַ - URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 - - ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK -} - -function Base64Decode(const InputData: string; OutputData: TStream; - FixZero: Boolean = True): Integer; overload; -{* ַ Base64 루 Base64URL 룩дɹ ECN_BASE64_OK - - - const InputData: string - ַ - OutputData: TStream - - FixZero: Boolean - Ƿȥβ #0 - - ֵInteger - ؽǷɹɹ򷵻 ECN_BASE64_OK -} - -function Base64Decode(const InputData: string; var OutputData: AnsiString; - FixZero: Boolean = True): Integer; overload; -{* ַ Base64 루 Base64URL 룩дַɹ ECN_BASE64_OK - - - const InputData: string - ַ - var OutputData: AnsiString - ַ - FixZero: Boolean - Ƿȥβ #0 - - ֵInteger - ؽǷɹɹ򷵻 ECN_BASE64_OK -} - -function Base64Decode(const InputData: string; OutputData: Pointer; - DataByteLen: Integer; FixZero: Boolean = True): Integer; overload; -{* ַ Base64 루 Base64URL 룩дڴɹ ECN_BASE64_OK - - - const InputData: string - ַ - OutputData: Pointer - ڴַ - DataByteLen: Integer - ڴֽڳȣӦΪ 1 + (Length(InputData) * 3 / 4) - FixZero: Boolean - Ƿȥβ #0 - - ֵInteger - OutputData nilĽֽڳȡؽǷɹɹ򷵻 ECN_BASE64_OK -} - -function Base64Decode(const InputData: string; out OutputData: TBytes; - FixZero: Boolean = True): Integer; overload; -{* ַ Base64 루 Base64URL 룩дֽ顣ɹ ECN_BASE64_OK - - - const InputData: string - ַ - out OutputData: TBytes - ֽ - FixZero: Boolean - Ƿȥβ #0 - - ֵInteger - ؽǷɹɹ򷵻 ECN_BASE64_OK -} - -implementation - -var - FilterDecodeInput: Boolean = True; - -//------------------------------------------------------------------------------ -// IJο -//------------------------------------------------------------------------------ - - EnCodeTab: array[0..64] of AnsiChar = - ( - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/', - '='); - - EnCodeTabURL: array[0..64] of AnsiChar = - ( - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '-', '_', - '='); - -//------------------------------------------------------------------------------ -// IJο -//------------------------------------------------------------------------------ - - { Base64 ֱַӸ㣬Ҳȡ} - DecodeTable: array[#0..#127] of Byte = - ( - Byte('='), 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, - 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, - 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 62, 00, 62, 00, 63, // ĵһ 62 63 + / - 62 - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 00, 00, 00, 00, 00, 00, - 00, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 00, 00, 00, 00, 63, // _ 63 - 00, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 00, 00, 00, 00, 00 - ); - -function Base64Encode(InputData: TStream; var OutputData: string; URL: Boolean): Integer; -var - Mem: TMemoryStream; -begin - Mem := TMemoryStream.Create; - try - Mem.CopyFrom(InputData, InputData.Size); - Result := Base64Encode(Mem.Memory, Mem.Size, OutputData, URL); - finally - Mem.Free; - end; -end; - -// Ϊ wr960204 ĽĿ Base64 㷨 -function Base64Encode(InputData: Pointer; DataByteLen: Integer; var OutputData: string; - URL: Boolean): Integer; -var - Times, I: Integer; - X1, X2, X3, X4: AnsiChar; - XT: Byte; -begin - if (InputData = nil) or (DataByteLen <= 0) then - begin - Result := ECN_BASE64_LENGTH; - Exit; - end; - - if DataByteLen mod 3 = 0 then - Times := DataByteLen div 3 - else - Times := DataByteLen div 3 + 1; - SetLength(OutputData, Times * 4); // һηڴ,һδַ,һδͷŷڴ - FillChar(OutputData[1], Length(OutputData) * SizeOf(Char), 0); - - if URL then - begin - for I := 0 to Times - 1 do - begin - if DataByteLen >= (3 + I * 3) then - begin - X1 := EnCodeTabURL[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; - XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; - XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); - X2 := EnCodeTabURL[XT]; - XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; - XT := XT or (Ord(PAnsiChar(InputData)[2 + I * 3]) shr 6); - X3 := EnCodeTabURL[XT]; - XT := (Ord(PAnsiChar(InputData)[2 + I * 3]) and 63); - X4 := EnCodeTabURL[XT]; - end - else if DataByteLen >= (2 + I * 3) then - begin - X1 := EnCodeTabURL[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; - XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; - XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); - X2 := EnCodeTabURL[XT]; - XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; - X3 := EnCodeTabURL[XT ]; - X4 := '='; - end - else - begin - X1 := EnCodeTabURL[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; - XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; - X2 := EnCodeTabURL[XT]; - X3 := '='; - X4 := '='; - end; - OutputData[I shl 2 + 1] := Char(X1); - OutputData[I shl 2 + 2] := Char(X2); - OutputData[I shl 2 + 3] := Char(X3); - OutputData[I shl 2 + 4] := Char(X4); - end; - end - else - begin - for I := 0 to Times - 1 do - begin - if DataByteLen >= (3 + I * 3) then - begin - X1 := EnCodeTab[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; - XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; - XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); - X2 := EnCodeTab[XT]; - XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; - XT := XT or (Ord(PAnsiChar(InputData)[2 + I * 3]) shr 6); - X3 := EnCodeTab[XT]; - XT := (Ord(PAnsiChar(InputData)[2 + I * 3]) and 63); - X4 := EnCodeTab[XT]; - end - else if DataByteLen >= (2 + I * 3) then - begin - X1 := EnCodeTab[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; - XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; - XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); - X2 := EnCodeTab[XT]; - XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; - X3 := EnCodeTab[XT ]; - X4 := '='; - end - else - begin - X1 := EnCodeTab[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; - XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; - X2 := EnCodeTab[XT]; - X3 := '='; - X4 := '='; - end; - OutputData[I shl 2 + 1] := Char(X1); - OutputData[I shl 2 + 2] := Char(X2); - OutputData[I shl 2 + 3] := Char(X3); - OutputData[I shl 2 + 4] := Char(X4); - end; - end; - - OutputData := Trim(OutputData); - if URL then - begin - // ɾ OutputData β = ַ - if (Length(OutputData) > 0) and (OutputData[Length(OutputData)] = '=') then - begin - Delete(OutputData, Length(OutputData), 1); - if (Length(OutputData) > 0) and (OutputData[Length(OutputData)] = '=') then - begin - Delete(OutputData, Length(OutputData), 1); - if (Length(OutputData) > 0) and (OutputData[Length(OutputData)] = '=') then - Delete(OutputData, Length(OutputData), 1); - end; - end; - end; - Result := ECN_BASE64_OK; -end; - -function Base64Encode(const InputData: AnsiString; var OutputData: string; URL: Boolean): Integer; -begin - if InputData <> '' then - Result := Base64Encode(@InputData[1], Length(InputData), OutputData, URL) - else - Result := ECN_BASE64_LENGTH; -end; - -function Base64Encode(InputData: TBytes; var OutputData: string; URL: Boolean): Integer; -begin - if Length(InputData) > 0 then - Result := Base64Encode(@InputData[0], Length(InputData), OutputData, URL) - else - Result := ECN_BASE64_LENGTH; -end; - -function Base64Decode(const InputData: string; OutputData: TStream; FixZero: Boolean): Integer; -var - Data: TBytes; -begin - Result := Base64Decode(InputData, Data, FixZero); - if (Result = ECN_BASE64_OK) and (Length(Data) > 0) then - begin - OutputData.Size := Length(Data); - OutputData.Position := 0; - OutputData.Write(Data[0], Length(Data)); - end; -end; - -function Base64Decode(const InputData: string; out OutputData: TBytes; - FixZero: Boolean): Integer; -var - SrcLen, DstLen, Times, I: Integer; - X1, X2, X3, X4, XT: Byte; - C, ToDec: Integer; - Data: AnsiString; - - function FilterLine(const Source: AnsiString): AnsiString; - var - P, PP: PAnsiChar; - I, FL: Integer; - begin - FL := Length(Source); - if FL > 0 then - begin - GetMem(P, FL); // һηڴ,һδַ,һδͷŷڴ - PP := P; - FillChar(P^, FL, 0); - for I := 1 to FL do - begin - if Source[I] in ['0'..'9', 'A'..'Z', 'a'..'z', '+', '/', '=', '-', '_'] then - begin - PP^ := Source[I]; - Inc(PP); - end; - end; - SetString(Result, P, PP - P); // ȡЧ - FreeMem(P); - end; - end; - -begin - if InputData = '' then - begin - Result := ECN_BASE64_OK; - Exit; - end; - OutPutData := nil; - - // D5 ²֪ôIJ AnsiString(InputData)ܻڴֿ - if FilterDecodeInput then - begin -{$IFDEF UNICODE} - Data := FilterLine(AnsiString(InputData)); -{$ELSE} - Data := FilterLine(InputData); -{$ENDIF} - end - else - begin -{$IFDEF UNICODE} - Data := AnsiString(InputData); -{$ELSE} - Data := InputData; -{$ENDIF} - end; - - // Base64URL Ľȥβ =ҪݳǷ 4 ı - if (Length(Data) and $03) <> 0 then - Data := Data + StringOfChar(AnsiChar('='), 4 - (Length(Data) and $03)); - - SrcLen := Length(Data); - DstLen := SrcLen * 3 div 4; - ToDec := 0; - - // βһȺζԭʼݲ˸ #0ȺζŲ #0ҪȥҲ̳ - // עⲻͬԭʼݵβ #0 ȥ - if Data[SrcLen] = '=' then - begin - Inc(ToDec); - if (SrcLen > 1) and (Data[SrcLen - 1] = '=') then - Inc(ToDec); - end; - - SetLength(OutputData, DstLen); // һηڴ,һδַ,һδͷŷڴ - Times := SrcLen div 4; - C := 0; - - for I := 0 to Times - 1 do - begin - X1 := DecodeTable[Data[1 + I shl 2]]; - X2 := DecodeTable[Data[2 + I shl 2]]; - X3 := DecodeTable[Data[3 + I shl 2]]; - X4 := DecodeTable[Data[4 + I shl 2]]; - X1 := X1 shl 2; - XT := X2 shr 4; - X1 := X1 or XT; - X2 := X2 shl 4; - OutputData[C] := X1; - Inc(C); - if X3 = 64 then - Break; - XT := X3 shr 2; - X2 := X2 or XT; - X3 := X3 shl 6; - OutputData[C] := X2; - Inc(C); - if X4 = 64 then - Break; - X3 := X3 or X4; - OutputData[C] := X3; - Inc(C); - end; - - // ݲĵȺĿǷɾβ #0 - while (ToDec > 0) and (OutputData[DstLen - 1] = 0) do - begin - Dec(ToDec); - Dec(DstLen); - end; - SetLength(OutputData, DstLen); - - // ٸⲿҪɾβ #0ʵ̫ʵ - if FixZero then - begin - while (DstLen > 0) and (OutputData[DstLen - 1] = 0) do - Dec(DstLen); - SetLength(OutputData, DstLen); - end; - - Result := ECN_BASE64_OK; -end; - -function Base64Decode(const InputData: string; var OutputData: AnsiString; FixZero: Boolean): Integer; -var - Data: TBytes; -begin - Result := Base64Decode(InputData, Data, FixZero); - if (Result = ECN_BASE64_OK) and (Length(Data) > 0) then - begin - SetLength(OutputData, Length(Data)); - Move(Data[0], OutputData[1], Length(Data)); - end; -end; - -function Base64Decode(const InputData: string; OutputData: Pointer; - DataByteLen: Integer; FixZero: Boolean): Integer; -var - Data: TBytes; -begin - Result := Base64Decode(InputData, Data, FixZero); - if (Result = ECN_BASE64_OK) and (Length(Data) > 0) then - begin - if OutputData = nil then - begin - Result := Length(Data); - Exit; - end; - - if DataByteLen < Length(Data) then - begin - Result := ECN_BASE64_LENGTH; - Exit; - end; - - Move(Data[0], OutPutData^, Length(Data)); - end; -end; - -end. +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +{ -----------------------------------------------------------------------------} +{ uTBase64 v1.0 - Simple Base64 encoding/decoding class } +{ Base64 described in RFC2045, Page 24, (w) 1996 Freed & Borenstein } +{ Delphi implementation (w) 1999 Dennis D. Spreen (dennis@spreendigital.de) } +{ This unit is freeware. Just drop me a line if this unit is useful for you. } +{ -----------------------------------------------------------------------------} + +unit CnBase64; +{* |
+================================================================================
+* ƣ
+* ԪƣBase64 㷨ʵֵԪ
+* ԪߣղSolin solin@21cn.com; http://www.ilovezhuzhu.net
+*           wr960204
+*           CnPack  (master@cnpack.org)
+*           ݻ Dennis D. Spreen  UTBASE64.pas дԭаȨϢ
+*     עԪʵ˱׼ Base64  Base64URL ı빦ܡ
+*           Base64URL ڱ׼ Base64ѷ + / 滻 - _  URL 
+*           Ѻãɾβ =
+*
+* ƽ̨PWin2003Std + Delphi 6.0
+* ݲԣδ
+*   õԪ豾ػ
+* ޸ļ¼2023.10.04 V1.6
+*               ɾʵ֡Base64Encode  Base64Decode ֧ Base64URL ı
+*           2019.12.12 V1.5
+*               ֧ TBytes
+*           2019.04.15 V1.4
+*               ֧ Win32/Win64/MacOS
+*           2018.06.22 V1.3
+*               ԭʼݿܰ #0 ԭʼβ #0 Ƴ
+*           2016.05.03 V1.2
+*               ַа #0 ʱܻᱻضϵ
+*           2006.10.25 V1.1
+*                wr960204 Ż汾
+*           2003.10.14 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, CnNative, CnConsts; + +const + ECN_BASE64_OK = ECN_OK; // תɹ + {* Base64 ϵд룺޴ֵΪ 0} + ECN_BASE64_ERROR_BASE = ECN_CUSTOM_ERROR_BASE + $500; + {* Base64 ϵдĻ׼ʼֵΪ ECN_CUSTOM_ERROR_BASE $500} + + ECN_BASE64_LENGTH = ECN_BASE64_ERROR_BASE + 1; + {* Base64 ֮ݳȷǷ} + +function Base64Encode(InputData: TStream; var OutputData: string; + URL: Boolean = False): Integer; overload; +{* Base64 Base64URL 룬ɹ ECN_BASE64_OK + + + InputData: TStream - + var OutputData: string - ַ + URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 + + ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Encode(const InputData: AnsiString; var OutputData: string; + URL: Boolean = False): Integer; overload; +{* ַ Base64 Base64URL 룬ɹ ECN_BASE64_OK + + + const InputData: AnsiString - ַ + var OutputData: string - ַ + URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 + + ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Encode(InputData: Pointer; DataByteLen: Integer; var OutputData: string; + URL: Boolean = False): Integer; overload; +{* ݿ Base64 Base64URL 룬ɹ ECN_BASE64_OK + + + InputData: Pointer - ݿַ + DataByteLen: Integer - ݿֽڳ + var OutputData: string - ַ + URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 + + ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Encode(InputData: TBytes; var OutputData: string; + URL: Boolean = False): Integer; overload; +{* ֽ Base64 Base64URL 룬ɹ ECN_BASE64_OK + + + InputData: TBytes - ֽ + var OutputData: string - ַ + URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 + + ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Decode(const InputData: string; OutputData: TStream; + FixZero: Boolean = True): Integer; overload; +{* ַ Base64 루 Base64URL 룩дɹ ECN_BASE64_OK + + + const InputData: string - ַ + OutputData: TStream - + FixZero: Boolean - Ƿȥβ #0 + + ֵInteger - ؽǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Decode(const InputData: string; var OutputData: AnsiString; + FixZero: Boolean = True): Integer; overload; +{* ַ Base64 루 Base64URL 룩дַɹ ECN_BASE64_OK + + + const InputData: string - ַ + var OutputData: AnsiString - ַ + FixZero: Boolean - Ƿȥβ #0 + + ֵInteger - ؽǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Decode(const InputData: string; OutputData: Pointer; + DataByteLen: Integer; FixZero: Boolean = True): Integer; overload; +{* ַ Base64 루 Base64URL 룩дڴɹ ECN_BASE64_OK + + + const InputData: string - ַ + OutputData: Pointer - ڴַ + DataByteLen: Integer - ڴֽڳȣӦΪ 1 + (Length(InputData) * 3 / 4) + FixZero: Boolean - Ƿȥβ #0 + + ֵInteger - OutputData nilĽֽڳȡؽǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Decode(const InputData: string; out OutputData: TBytes; + FixZero: Boolean = True): Integer; overload; +{* ַ Base64 루 Base64URL 룩дֽ顣ɹ ECN_BASE64_OK + + + const InputData: string - ַ + out OutputData: TBytes - ֽ + FixZero: Boolean - Ƿȥβ #0 + + ֵInteger - ؽǷɹɹ򷵻 ECN_BASE64_OK +} + +implementation + +var + FilterDecodeInput: Boolean = True; + +//------------------------------------------------------------------------------ +// IJο +//------------------------------------------------------------------------------ + + EnCodeTab: array[0..64] of AnsiChar = + ( + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/', + '='); + + EnCodeTabURL: array[0..64] of AnsiChar = + ( + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '-', '_', + '='); + +//------------------------------------------------------------------------------ +// IJο +//------------------------------------------------------------------------------ + + { Base64 ֱַӸ㣬Ҳȡ} + DecodeTable: array[#0..#127] of Byte = + ( + Byte('='), 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, + 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, + 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 62, 00, 62, 00, 63, // ĵһ 62 63 + / - 62 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 00, 00, 00, 00, 00, 00, + 00, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 00, 00, 00, 00, 63, // _ 63 + 00, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 00, 00, 00, 00, 00 + ); + +function Base64Encode(InputData: TStream; var OutputData: string; URL: Boolean): Integer; +var + Mem: TMemoryStream; +begin + Mem := TMemoryStream.Create; + try + Mem.CopyFrom(InputData, InputData.Size); + Result := Base64Encode(Mem.Memory, Mem.Size, OutputData, URL); + finally + Mem.Free; + end; +end; + +// Ϊ wr960204 ĽĿ Base64 㷨 +function Base64Encode(InputData: Pointer; DataByteLen: Integer; var OutputData: string; + URL: Boolean): Integer; +var + Times, I: Integer; + X1, X2, X3, X4: AnsiChar; + XT: Byte; +begin + if (InputData = nil) or (DataByteLen <= 0) then + begin + Result := ECN_BASE64_LENGTH; + Exit; + end; + + if DataByteLen mod 3 = 0 then + Times := DataByteLen div 3 + else + Times := DataByteLen div 3 + 1; + SetLength(OutputData, Times * 4); // һηڴ,һδַ,һδͷŷڴ + FillChar(OutputData[1], Length(OutputData) * SizeOf(Char), 0); + + if URL then + begin + for I := 0 to Times - 1 do + begin + if DataByteLen >= (3 + I * 3) then + begin + X1 := EnCodeTabURL[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); + X2 := EnCodeTabURL[XT]; + XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; + XT := XT or (Ord(PAnsiChar(InputData)[2 + I * 3]) shr 6); + X3 := EnCodeTabURL[XT]; + XT := (Ord(PAnsiChar(InputData)[2 + I * 3]) and 63); + X4 := EnCodeTabURL[XT]; + end + else if DataByteLen >= (2 + I * 3) then + begin + X1 := EnCodeTabURL[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); + X2 := EnCodeTabURL[XT]; + XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; + X3 := EnCodeTabURL[XT ]; + X4 := '='; + end + else + begin + X1 := EnCodeTabURL[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + X2 := EnCodeTabURL[XT]; + X3 := '='; + X4 := '='; + end; + OutputData[I shl 2 + 1] := Char(X1); + OutputData[I shl 2 + 2] := Char(X2); + OutputData[I shl 2 + 3] := Char(X3); + OutputData[I shl 2 + 4] := Char(X4); + end; + end + else + begin + for I := 0 to Times - 1 do + begin + if DataByteLen >= (3 + I * 3) then + begin + X1 := EnCodeTab[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); + X2 := EnCodeTab[XT]; + XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; + XT := XT or (Ord(PAnsiChar(InputData)[2 + I * 3]) shr 6); + X3 := EnCodeTab[XT]; + XT := (Ord(PAnsiChar(InputData)[2 + I * 3]) and 63); + X4 := EnCodeTab[XT]; + end + else if DataByteLen >= (2 + I * 3) then + begin + X1 := EnCodeTab[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); + X2 := EnCodeTab[XT]; + XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; + X3 := EnCodeTab[XT ]; + X4 := '='; + end + else + begin + X1 := EnCodeTab[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + X2 := EnCodeTab[XT]; + X3 := '='; + X4 := '='; + end; + OutputData[I shl 2 + 1] := Char(X1); + OutputData[I shl 2 + 2] := Char(X2); + OutputData[I shl 2 + 3] := Char(X3); + OutputData[I shl 2 + 4] := Char(X4); + end; + end; + + OutputData := Trim(OutputData); + if URL then + begin + // ɾ OutputData β = ַ + if (Length(OutputData) > 0) and (OutputData[Length(OutputData)] = '=') then + begin + Delete(OutputData, Length(OutputData), 1); + if (Length(OutputData) > 0) and (OutputData[Length(OutputData)] = '=') then + begin + Delete(OutputData, Length(OutputData), 1); + if (Length(OutputData) > 0) and (OutputData[Length(OutputData)] = '=') then + Delete(OutputData, Length(OutputData), 1); + end; + end; + end; + Result := ECN_BASE64_OK; +end; + +function Base64Encode(const InputData: AnsiString; var OutputData: string; URL: Boolean): Integer; +begin + if InputData <> '' then + Result := Base64Encode(@InputData[1], Length(InputData), OutputData, URL) + else + Result := ECN_BASE64_LENGTH; +end; + +function Base64Encode(InputData: TBytes; var OutputData: string; URL: Boolean): Integer; +begin + if Length(InputData) > 0 then + Result := Base64Encode(@InputData[0], Length(InputData), OutputData, URL) + else + Result := ECN_BASE64_LENGTH; +end; + +function Base64Decode(const InputData: string; OutputData: TStream; FixZero: Boolean): Integer; +var + Data: TBytes; +begin + Result := Base64Decode(InputData, Data, FixZero); + if (Result = ECN_BASE64_OK) and (Length(Data) > 0) then + begin + OutputData.Size := Length(Data); + OutputData.Position := 0; + OutputData.Write(Data[0], Length(Data)); + end; +end; + +function Base64Decode(const InputData: string; out OutputData: TBytes; + FixZero: Boolean): Integer; +var + SrcLen, DstLen, Times, I: Integer; + X1, X2, X3, X4, XT: Byte; + C, ToDec: Integer; + Data: AnsiString; + + function FilterLine(const Source: AnsiString): AnsiString; + var + P, PP: PAnsiChar; + I, FL: Integer; + begin + FL := Length(Source); + if FL > 0 then + begin + GetMem(P, FL); // һηڴ,һδַ,һδͷŷڴ + PP := P; + FillChar(P^, FL, 0); + for I := 1 to FL do + begin + if Source[I] in ['0'..'9', 'A'..'Z', 'a'..'z', '+', '/', '=', '-', '_'] then + begin + PP^ := Source[I]; + Inc(PP); + end; + end; + SetString(Result, P, PP - P); // ȡЧ + FreeMem(P); + end; + end; + +begin + if InputData = '' then + begin + Result := ECN_BASE64_OK; + Exit; + end; + OutPutData := nil; + + // D5 ²֪ôIJ AnsiString(InputData)ܻڴֿ + if FilterDecodeInput then + begin +{$IFDEF UNICODE} + Data := FilterLine(AnsiString(InputData)); +{$ELSE} + Data := FilterLine(InputData); +{$ENDIF} + end + else + begin +{$IFDEF UNICODE} + Data := AnsiString(InputData); +{$ELSE} + Data := InputData; +{$ENDIF} + end; + + // Base64URL Ľȥβ =ҪݳǷ 4 ı + if (Length(Data) and $03) <> 0 then + Data := Data + StringOfChar(AnsiChar('='), 4 - (Length(Data) and $03)); + + SrcLen := Length(Data); + DstLen := SrcLen * 3 div 4; + ToDec := 0; + + // βһȺζԭʼݲ˸ #0ȺζŲ #0ҪȥҲ̳ + // עⲻͬԭʼݵβ #0 ȥ + if Data[SrcLen] = '=' then + begin + Inc(ToDec); + if (SrcLen > 1) and (Data[SrcLen - 1] = '=') then + Inc(ToDec); + end; + + SetLength(OutputData, DstLen); // һηڴ,һδַ,һδͷŷڴ + Times := SrcLen div 4; + C := 0; + + for I := 0 to Times - 1 do + begin + X1 := DecodeTable[Data[1 + I shl 2]]; + X2 := DecodeTable[Data[2 + I shl 2]]; + X3 := DecodeTable[Data[3 + I shl 2]]; + X4 := DecodeTable[Data[4 + I shl 2]]; + X1 := X1 shl 2; + XT := X2 shr 4; + X1 := X1 or XT; + X2 := X2 shl 4; + OutputData[C] := X1; + Inc(C); + if X3 = 64 then + Break; + XT := X3 shr 2; + X2 := X2 or XT; + X3 := X3 shl 6; + OutputData[C] := X2; + Inc(C); + if X4 = 64 then + Break; + X3 := X3 or X4; + OutputData[C] := X3; + Inc(C); + end; + + // ݲĵȺĿǷɾβ #0 + while (ToDec > 0) and (OutputData[DstLen - 1] = 0) do + begin + Dec(ToDec); + Dec(DstLen); + end; + SetLength(OutputData, DstLen); + + // ٸⲿҪɾβ #0ʵ̫ʵ + if FixZero then + begin + while (DstLen > 0) and (OutputData[DstLen - 1] = 0) do + Dec(DstLen); + SetLength(OutputData, DstLen); + end; + + Result := ECN_BASE64_OK; +end; + +function Base64Decode(const InputData: string; var OutputData: AnsiString; FixZero: Boolean): Integer; +var + Data: TBytes; +begin + Result := Base64Decode(InputData, Data, FixZero); + if (Result = ECN_BASE64_OK) and (Length(Data) > 0) then + begin + SetLength(OutputData, Length(Data)); + Move(Data[0], OutputData[1], Length(Data)); + end; +end; + +function Base64Decode(const InputData: string; OutputData: Pointer; + DataByteLen: Integer; FixZero: Boolean): Integer; +var + Data: TBytes; +begin + Result := Base64Decode(InputData, Data, FixZero); + if (Result = ECN_BASE64_OK) and (Length(Data) > 0) then + begin + if OutputData = nil then + begin + Result := Length(Data); + Exit; + end; + + if DataByteLen < Length(Data) then + begin + Result := ECN_BASE64_LENGTH; + Exit; + end; + + Move(Data[0], OutPutData^, Length(Data)); + end; +end; + +end. diff --git a/CnPack/Crypto/CnConsts.pas b/CnPack/Crypto/CnConsts.pas index f4f50aa..efb2e95 100644 --- a/CnPack/Crypto/CnConsts.pas +++ b/CnPack/Crypto/CnConsts.pas @@ -1,250 +1,250 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -unit CnConsts; -{* |
-================================================================================
-* ƣ
-* ԪƣԴַ嵥Ԫ
-* ԪߣCnPack 
-*     ע
-* ƽ̨PWin98SE + Delphi 5.0
-* ݲԣPWin9X/2000/XP + Delphi 5/6
-*   õԪеַϱػʽ
-* ޸ļ¼2005.12.24 V1.0
-*                ԪֲӢַ
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -const - ECN_OK = 0; // OK޴ - - ECN_FILE_NOT_FOUND = $10; // ļ - - ECN_CUSTOM_ERROR_BASE = $1000; // 趨Ĵʼֵ - -//============================================================================== -// Strings DO NOT Localize: -//============================================================================== - -resourcestring - - // CnPack Reg Path - SCnPackRegPath = '\Software\CnPack'; - - // Tools Reg Path - SCnPackToolRegPath = 'CnTools'; - -//============================================================================== -// Strings to be Localized: -//============================================================================== - - -var - // Common Information - SCnInformation: string = 'Information'; - SCnWarning: string = 'Warning'; - SCnError: string = 'Error'; - SCnEnabled: string = 'Enabled'; - SCnDisabled: string = 'Disabled'; - SCnMsgDlgOK: string = '&OK'; - SCnMsgDlgCancel: string = '&Cancel'; - SCnMsgDlgYes: string = '&Yes'; - SCnMsgDlgNo: string = '&No'; - SCnMsgDlgYesToAll: string = 'Yes to &All'; - SCnMsgDlgNoToAll: string = 'No to A&ll'; - SCnVersion: string = 'Version'; - SCnNeedAdmin: string = 'Maybe Need Administrator.'; - -const - // CnPack Information - SCnPackAbout = 'CnPack'; - SCnPackVer = 'Ver 0.1.5.2'; - SCnPackStr = SCnPackAbout + ' ' + SCnPackVer; - SCnPackUrl = 'https://www.cnpack.org'; - SCnPackBbsUrl = 'https://bbs.cnpack.org'; - SCnPackNewsUrl = 'news://news.cnpack.org'; - SCnPackSourceUrl = 'https://github.com/cnpack'; - SCnPackEmail = 'master@cnpack.org'; - SCnPackBugEmail = 'bugs@cnpack.org'; - SCnPackSuggestionsEmail = 'suggestions@cnpack.org'; - - SCnPackDonationUrl = 'https://www.cnpack.org/foundation.php'; - SCnPackDonationUrlSF = 'http://sourceforge.net/donate/index.php?group_id=110999'; - SCnPackGroup = 'CnPack Team'; - SCnPackCopyright = '(C)Copyright 2001-2025 ' + SCnPackGroup; - - // CnPropEditors - SCopyrightFmtStr = - SCnPackStr + #13#10#13#10 + - 'Component Name: %s' + #13#10 + - 'Author: %s(%s)' + #13#10 + - 'Comment: %s' + #13#10 + - 'HomePage: ' + SCnPackUrl + #13#10 + - 'Email: ' + SCnPackEmail + #13#10#13#10 + - SCnPackCopyright; - -resourcestring - - // Component Palette Name - SCnNonVisualPalette = 'CnPack Tools'; - SCnGraphicPalette = 'CnPack VCL'; - SCnNetPalette = 'CnPack Net'; - SCnDatabasePalette = 'CnPack DB'; - SCnReportPalette = 'CnPack Report'; - - // CnPack Developers Added from Last. -var - SCnPack_Team: string = 'CnPack Team'; - SCnPack_Zjy: string = 'Zhou JingYu'; - SCnPack_Shenloqi: string = 'Chinbo'; - SCnPack_xiaolv: string = 'xiaolv'; - SCnPack_Flier: string = 'Flier Lu'; - SCnPack_LiuXiao: string = 'Liu Xiao'; - SCnPack_PanYing: string = 'Pan Ying'; - SCnPack_Hubdog: string = 'Hubdog'; - SCnPack_Wyb_star: string = 'wyb_star'; - SCnPack_Licwing: string = 'Licwing zue'; - SCnPack_Alan: string = 'Alan'; - SCnPack_GuYueChunQiu: string = 'GuYueChunQiu'; - SCnPack_Aimingoo: string = 'Aimingoo'; - SCnPack_QSoft: string = 'QSoft'; - SCnPack_Hospitality: string = 'ZhangJiongXuan (Hospitality)'; - SCnPack_SQuall: string = 'SQUALL'; - SCnPack_Hhha: string = 'Hhha'; - SCnPack_Beta: string = 'beta'; - SCnPack_Leeon: string = 'Leeon'; - SCnPack_SuperYoyoNc: string = 'SuperYoyoNC'; - SCnPack_JohnsonZhong: string = 'Johnson Zhong'; - SCnPack_DragonPC: string = 'Dragon P.C.'; - SCnPack_Kendling: string = 'Kending'; - SCnPack_ccrun: string = 'ccrun'; - SCnPack_Dingbaosheng: string = 'dingbaosheng'; - SCnPack_LuXiaoban: string = 'Zhou Yibo(Lu Xiaoban)'; - SCnPack_Savetime: string = 'savetime'; - SCnPack_solokey: string = 'solokey'; - SCnPack_Bahamut: string = 'Bahamut'; - SCnPack_Sesame: string = 'Sesame'; - SCnPack_BuDeXian: string = 'BuDeXian'; - SCnPack_XiaoXia: string = 'Summer'; - SCnPack_ZiMin: string = 'ZiMin'; - SCnPack_rarnu: string = 'rarnu'; - SCnPack_dejoy: string = 'dejoy'; - SCnPack_Rain: string = 'Rain'; - SCnPack_cnwinds: string = 'cnwinds'; - - // CnCommon - SUnknowError: string = 'Unknow error'; - SErrorCode: string = 'Error code:'; - -const - SCnPack_TeamEmail = 'master@cnpack.org'; - SCnPack_ZjyEmail = 'zjy@cnpack.org'; - SCnPack_ShenloqiEmail = 'Shenloqi@hotmail.com'; - SCnPack_xiaolvEmail = 'xiaolv888@etang.com'; - SCnPack_FlierEmail = 'flier_lu@sina.com'; - SCnPack_LiuXiaoEmail = 'liuxiao@cnpack.org'; - SCnPack_PanYingEmail = 'panying@sina.com'; - SCnPack_HubdogEmail = 'hubdog@263.net'; - SCnPack_Wyb_starMail = 'wyb_star@sina.com'; - SCnPack_LicwingEmail = 'licwing@chinasystemsn.com'; - SCnPack_AlanEmail = 'BeyondStudio@163.com'; - SCnPack_GuYueChunQiuEmail = 'guyuechunqiu@cnpack.org'; - SCnPack_AimingooEmail = 'aim@263.net'; - SCnPack_QSoftEmail = 'hq.com@263.net'; - SCnPack_HospitalityEmail = 'Hospitality_ZJX@msn.com'; - SCnPack_SQuallEmail = 'squall_sa@163.com'; - SCnPack_HhhaEmail = 'Hhha@eyou.com'; - SCnPack_BetaEmail = 'beta@01cn.net'; - SCnPack_LeeonEmail = 'real-like@163.com'; - SCnPack_SuperYoyoNcEmail = 'superyoyonc@sohu.com'; - SCnPack_JohnsonZhongEmail = 'zhongs@tom.com'; - SCnPack_DragonPCEmail = 'dragonpc@21cn.com'; - SCnPack_KendlingEmail = 'kendling@21cn.com'; - SCnPack_ccRunEmail = 'info@ccrun.com'; - SCnPack_DingbaoshengEmail = 'yzdbs@msn.com'; - SCnPack_LuXiaobanEmail = 'zhouyibo2000@sina.com'; - SCnPack_SavetimeEmail = 'savetime2k@hotmail.com'; - SCnPack_solokeyEmail = 'crh611@163.com'; - SCnPack_BahamutEmail = 'fantasyfinal@126.com'; - SCnPack_SesameEmail = 'sesamehch@163.com'; - SCnPack_BuDeXianEmail = 'appleak46@yahoo.com.cn'; - SCnPack_XiaoXiaEmail = 'summercore@163.com'; - SCnPack_ZiMinEmail = '441414288@qq.com'; - SCnPack_rarnuEmail = 'rarnu@cnpack.org'; - SCnPack_dejoyEmail = 'dejoybbs@163.com'; - SCnPack_RainEmail = SCnPack_TeamEmail; // Emailÿ - SCnPack_cnwindsEmail = SCnPack_TeamEmail; - - // CnMemProf - SCnPackMemMgr = 'CnMemProf'; - SMemLeakDlgReport = 'Found %d memory leaks. [There are %d allocated before replace memory manager.]'; - SMemMgrODSReport = 'Get = %d Free = %d Realloc = %d'; - SMemMgrOverflow = 'Memory Manager''s list capability overflow, Please enlarge it!'; - SMemMgrRunTime = '%d hour(s) %d minute(s) %d second(s)'; - SOldAllocMemCount = 'There are %d allocated before replace memory manager.'; - SAppRunTime = 'Application total run time: '; - SMemSpaceCanUse = 'HeapStatus.TotalAddrSpace: %d KB'; - SUncommittedSpace = 'HeapStatus.TotalUncommitted: %d KB'; - SCommittedSpace = 'HeapStatus.TotalCommitted: %d KB'; - SFreeSpace = 'HeapStatus.TotalFree: %d KB'; - SAllocatedSpace = 'HeapStatus.TotalAllocated: %d KB'; - SAllocatedSpacePercent = 'TotalAllocated div TotalAddrSpace: %d%%'; - SFreeSmallSpace = 'HeapStatus.FreeSmall: %d KB'; - SFreeBigSpace = 'HeapStatus.FreeBig: %d KB'; - SUnusedSpace = 'HeapStatus.Unused: %d KB'; - SOverheadSpace = 'HeapStatus.Overhead: %d KB'; - SObjectCountInMemory = 'Objects count in memory: '; - SNoMemLeak = ' No memory leak.'; - SNoName = '(no name)'; - SNotAnObject = ' Not an object'; - SByte = 'Byte'; - SCommaString = ','; - SPeriodString = '.'; - -resourcestring - SCnErrorMapViewOfFile = 'MapViewOfFile Failed. '; - SCnErrorCreateFileMapping = 'CreateFileMapping Failed. '; - -function CnGetLastError: Integer; - -procedure _CnSetLastError(Err: Integer); - -implementation - -threadvar - CnErrorCode: Integer; - -function CnGetLastError: Integer; -begin - Result := CnErrorCode; -end; - -procedure _CnSetLastError(Err: Integer); -begin - CnErrorCode := Err; -end; - -end. - +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnConsts; +{* |
+================================================================================
+* ƣ
+* ԪƣԴַ嵥Ԫ
+* ԪߣCnPack 
+*     ע
+* ƽ̨PWin98SE + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2005.12.24 V1.0
+*                ԪֲӢַ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +const + ECN_OK = 0; // OK޴ + + ECN_FILE_NOT_FOUND = $10; // ļ + + ECN_CUSTOM_ERROR_BASE = $1000; // 趨Ĵʼֵ + +//============================================================================== +// Strings DO NOT Localize: +//============================================================================== + +resourcestring + + // CnPack Reg Path + SCnPackRegPath = '\Software\CnPack'; + + // Tools Reg Path + SCnPackToolRegPath = 'CnTools'; + +//============================================================================== +// Strings to be Localized: +//============================================================================== + + +var + // Common Information + SCnInformation: string = 'Information'; + SCnWarning: string = 'Warning'; + SCnError: string = 'Error'; + SCnEnabled: string = 'Enabled'; + SCnDisabled: string = 'Disabled'; + SCnMsgDlgOK: string = '&OK'; + SCnMsgDlgCancel: string = '&Cancel'; + SCnMsgDlgYes: string = '&Yes'; + SCnMsgDlgNo: string = '&No'; + SCnMsgDlgYesToAll: string = 'Yes to &All'; + SCnMsgDlgNoToAll: string = 'No to A&ll'; + SCnVersion: string = 'Version'; + SCnNeedAdmin: string = 'Maybe Need Administrator.'; + +const + // CnPack Information + SCnPackAbout = 'CnPack'; + SCnPackVer = 'Ver 0.1.5.2'; + SCnPackStr = SCnPackAbout + ' ' + SCnPackVer; + SCnPackUrl = 'https://www.cnpack.org'; + SCnPackBbsUrl = 'https://bbs.cnpack.org'; + SCnPackNewsUrl = 'news://news.cnpack.org'; + SCnPackSourceUrl = 'https://github.com/cnpack'; + SCnPackEmail = 'master@cnpack.org'; + SCnPackBugEmail = 'bugs@cnpack.org'; + SCnPackSuggestionsEmail = 'suggestions@cnpack.org'; + + SCnPackDonationUrl = 'https://www.cnpack.org/foundation.php'; + SCnPackDonationUrlSF = 'http://sourceforge.net/donate/index.php?group_id=110999'; + SCnPackGroup = 'CnPack Team'; + SCnPackCopyright = '(C)Copyright 2001-2025 ' + SCnPackGroup; + + // CnPropEditors + SCopyrightFmtStr = + SCnPackStr + #13#10#13#10 + + 'Component Name: %s' + #13#10 + + 'Author: %s(%s)' + #13#10 + + 'Comment: %s' + #13#10 + + 'HomePage: ' + SCnPackUrl + #13#10 + + 'Email: ' + SCnPackEmail + #13#10#13#10 + + SCnPackCopyright; + +resourcestring + + // Component Palette Name + SCnNonVisualPalette = 'CnPack Tools'; + SCnGraphicPalette = 'CnPack VCL'; + SCnNetPalette = 'CnPack Net'; + SCnDatabasePalette = 'CnPack DB'; + SCnReportPalette = 'CnPack Report'; + + // CnPack Developers Added from Last. +var + SCnPack_Team: string = 'CnPack Team'; + SCnPack_Zjy: string = 'Zhou JingYu'; + SCnPack_Shenloqi: string = 'Chinbo'; + SCnPack_xiaolv: string = 'xiaolv'; + SCnPack_Flier: string = 'Flier Lu'; + SCnPack_LiuXiao: string = 'Liu Xiao'; + SCnPack_PanYing: string = 'Pan Ying'; + SCnPack_Hubdog: string = 'Hubdog'; + SCnPack_Wyb_star: string = 'wyb_star'; + SCnPack_Licwing: string = 'Licwing zue'; + SCnPack_Alan: string = 'Alan'; + SCnPack_GuYueChunQiu: string = 'GuYueChunQiu'; + SCnPack_Aimingoo: string = 'Aimingoo'; + SCnPack_QSoft: string = 'QSoft'; + SCnPack_Hospitality: string = 'ZhangJiongXuan (Hospitality)'; + SCnPack_SQuall: string = 'SQUALL'; + SCnPack_Hhha: string = 'Hhha'; + SCnPack_Beta: string = 'beta'; + SCnPack_Leeon: string = 'Leeon'; + SCnPack_SuperYoyoNc: string = 'SuperYoyoNC'; + SCnPack_JohnsonZhong: string = 'Johnson Zhong'; + SCnPack_DragonPC: string = 'Dragon P.C.'; + SCnPack_Kendling: string = 'Kending'; + SCnPack_ccrun: string = 'ccrun'; + SCnPack_Dingbaosheng: string = 'dingbaosheng'; + SCnPack_LuXiaoban: string = 'Zhou Yibo(Lu Xiaoban)'; + SCnPack_Savetime: string = 'savetime'; + SCnPack_solokey: string = 'solokey'; + SCnPack_Bahamut: string = 'Bahamut'; + SCnPack_Sesame: string = 'Sesame'; + SCnPack_BuDeXian: string = 'BuDeXian'; + SCnPack_XiaoXia: string = 'Summer'; + SCnPack_ZiMin: string = 'ZiMin'; + SCnPack_rarnu: string = 'rarnu'; + SCnPack_dejoy: string = 'dejoy'; + SCnPack_Rain: string = 'Rain'; + SCnPack_cnwinds: string = 'cnwinds'; + + // CnCommon + SUnknowError: string = 'Unknow error'; + SErrorCode: string = 'Error code:'; + +const + SCnPack_TeamEmail = 'master@cnpack.org'; + SCnPack_ZjyEmail = 'zjy@cnpack.org'; + SCnPack_ShenloqiEmail = 'Shenloqi@hotmail.com'; + SCnPack_xiaolvEmail = 'xiaolv888@etang.com'; + SCnPack_FlierEmail = 'flier_lu@sina.com'; + SCnPack_LiuXiaoEmail = 'liuxiao@cnpack.org'; + SCnPack_PanYingEmail = 'panying@sina.com'; + SCnPack_HubdogEmail = 'hubdog@263.net'; + SCnPack_Wyb_starMail = 'wyb_star@sina.com'; + SCnPack_LicwingEmail = 'licwing@chinasystemsn.com'; + SCnPack_AlanEmail = 'BeyondStudio@163.com'; + SCnPack_GuYueChunQiuEmail = 'guyuechunqiu@cnpack.org'; + SCnPack_AimingooEmail = 'aim@263.net'; + SCnPack_QSoftEmail = 'hq.com@263.net'; + SCnPack_HospitalityEmail = 'Hospitality_ZJX@msn.com'; + SCnPack_SQuallEmail = 'squall_sa@163.com'; + SCnPack_HhhaEmail = 'Hhha@eyou.com'; + SCnPack_BetaEmail = 'beta@01cn.net'; + SCnPack_LeeonEmail = 'real-like@163.com'; + SCnPack_SuperYoyoNcEmail = 'superyoyonc@sohu.com'; + SCnPack_JohnsonZhongEmail = 'zhongs@tom.com'; + SCnPack_DragonPCEmail = 'dragonpc@21cn.com'; + SCnPack_KendlingEmail = 'kendling@21cn.com'; + SCnPack_ccRunEmail = 'info@ccrun.com'; + SCnPack_DingbaoshengEmail = 'yzdbs@msn.com'; + SCnPack_LuXiaobanEmail = 'zhouyibo2000@sina.com'; + SCnPack_SavetimeEmail = 'savetime2k@hotmail.com'; + SCnPack_solokeyEmail = 'crh611@163.com'; + SCnPack_BahamutEmail = 'fantasyfinal@126.com'; + SCnPack_SesameEmail = 'sesamehch@163.com'; + SCnPack_BuDeXianEmail = 'appleak46@yahoo.com.cn'; + SCnPack_XiaoXiaEmail = 'summercore@163.com'; + SCnPack_ZiMinEmail = '441414288@qq.com'; + SCnPack_rarnuEmail = 'rarnu@cnpack.org'; + SCnPack_dejoyEmail = 'dejoybbs@163.com'; + SCnPack_RainEmail = SCnPack_TeamEmail; // Emailÿ + SCnPack_cnwindsEmail = SCnPack_TeamEmail; + + // CnMemProf + SCnPackMemMgr = 'CnMemProf'; + SMemLeakDlgReport = 'Found %d memory leaks. [There are %d allocated before replace memory manager.]'; + SMemMgrODSReport = 'Get = %d Free = %d Realloc = %d'; + SMemMgrOverflow = 'Memory Manager''s list capability overflow, Please enlarge it!'; + SMemMgrRunTime = '%d hour(s) %d minute(s) %d second(s)'; + SOldAllocMemCount = 'There are %d allocated before replace memory manager.'; + SAppRunTime = 'Application total run time: '; + SMemSpaceCanUse = 'HeapStatus.TotalAddrSpace: %d KB'; + SUncommittedSpace = 'HeapStatus.TotalUncommitted: %d KB'; + SCommittedSpace = 'HeapStatus.TotalCommitted: %d KB'; + SFreeSpace = 'HeapStatus.TotalFree: %d KB'; + SAllocatedSpace = 'HeapStatus.TotalAllocated: %d KB'; + SAllocatedSpacePercent = 'TotalAllocated div TotalAddrSpace: %d%%'; + SFreeSmallSpace = 'HeapStatus.FreeSmall: %d KB'; + SFreeBigSpace = 'HeapStatus.FreeBig: %d KB'; + SUnusedSpace = 'HeapStatus.Unused: %d KB'; + SOverheadSpace = 'HeapStatus.Overhead: %d KB'; + SObjectCountInMemory = 'Objects count in memory: '; + SNoMemLeak = ' No memory leak.'; + SNoName = '(no name)'; + SNotAnObject = ' Not an object'; + SByte = 'Byte'; + SCommaString = ','; + SPeriodString = '.'; + +resourcestring + SCnErrorMapViewOfFile = 'MapViewOfFile Failed. '; + SCnErrorCreateFileMapping = 'CreateFileMapping Failed. '; + +function CnGetLastError: Integer; + +procedure _CnSetLastError(Err: Integer); + +implementation + +threadvar + CnErrorCode: Integer; + +function CnGetLastError: Integer; +begin + Result := CnErrorCode; +end; + +procedure _CnSetLastError(Err: Integer); +begin + CnErrorCode := Err; +end; + +end. + diff --git a/CnPack/Crypto/CnDES.pas b/CnPack/Crypto/CnDES.pas index c255235..5757122 100644 --- a/CnPack/Crypto/CnDES.pas +++ b/CnPack/Crypto/CnDES.pas @@ -1,1973 +1,1973 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -unit CnDES; -{* |
-================================================================================
-* ƣ
-* ԪƣDES ԳƼӽ㷨ʵֵԪ
-* ԪߣCnPack  (master@cnpack.org)
-*           /ֲ䲿ֹܡ
-*     עԪʵ DES/3DES ԳƼӽ㷨ֿС 8 ֽڣʵ
-*           ECB/CBC ģʽ֧ģʽ
-*
-* ƽ̨PWin2000Pro + Delphi 5.0
-* ݲԣPWin9X/2000/XP + Delphi 5/6
-*   õԪеַϱػʽ
-* ޸ļ¼2024.11.30 V1.7
-*               ɾ淶 DESEncryptStrToHex  DESDecryptStrToHex
-*               ɾ淶 TripleDESEncryptStrToHex  TripleDESDecryptStrToHex
-*                ECB 汾
-*               Ż PAnsiChar ʽ Iv Ĵ
-*           2024.10.12 V1.6
-*                3DES ²Խ⣬Ż Key  Iv Ķ봦
-*           2022.08.13 V1.5
-*               Կݼܷؿ
-*           2021.02.07 V1.4
-*               Ӷ TBytes ֧
-*           2020.03.25 V1.3
-*                3DES ֧
-*           2020.03.24 V1.2
-*                ECB/CBC ַӽܺɾԭеַܺ
-*           2019.04.15 V1.1
-*               ֧ Win32/Win64/MacOS
-*           2008.05.30 V1.0
-*               Ԫ
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - SysUtils, Classes, CnNative; - -const - CN_DES_KEYSIZE = 8; - {* DES Կȣ8 ֽ} - - CN_DES_BLOCKSIZE = 8; - {* DES ļܿ鳤ȣ8 ֽ} - - CN_TRIPLE_DES_KEYSIZE = CN_DES_KEYSIZE * 3; - {* 3DES Կȣ DES 24 ֽ} - - CN_TRIPLE_DES_BLOCKSIZE = CN_DES_BLOCKSIZE; - {* 3DES ļܿ鳤ȣ 8 ֽ} - -type - ECnDESException = class(Exception); - {* DES 쳣} - - TCnDESKey = array[0..CN_DES_KEYSIZE - 1] of Byte; - {* DES ļ Key8 ֽ} - - TCnDESBuffer = array[0..CN_DES_BLOCKSIZE - 1] of Byte; - {* DES ļܿ飬8 ֽ} - - TCnDESIv = array[0..CN_DES_BLOCKSIZE - 1] of Byte; - {* DES CBC ijʼ8 ֽ} - - TCn3DESKey = array[0..CN_TRIPLE_DES_KEYSIZE - 1] of Byte; - {* 3DES Կȣ DES 24 ֽ} - - TCn3DESBuffer = TCnDESBuffer; - {* 3DES ļܿ飬 DES ļܿ飬8 ֽ} - - TCn3DESIv = TCnDESIv; - {* 3DES CBC ijʼ DES CBC ijʼ8 ֽ} - -// ================================= DES ======================================= - -function DESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; -{* ֽڳȼ DES ȡǿ - - - InputByteLength: Integer - ֽڳ - - ֵInteger - DES ij -} - -procedure DESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); -{* AnsiString DES ܣʹ ECB ģʽ - - - Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 - const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı - Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 - - ֵޣ -} - -procedure DESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); -{* AnsiString DES ܣʹ ECB ģʽ - - - Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 - const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı - Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 - - ֵޣ -} - -procedure DESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; const Input: AnsiString; - Output: PAnsiChar); -{* AnsiString DES ܣʹ CBC ģʽ - - - Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 - Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ - const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı - Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 - - ֵޣ -} - -procedure DESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; const Input: AnsiString; - Output: PAnsiChar); -{* AnsiString DES ܣʹ CBC ģʽ - - - Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 - Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ - const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı - Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 - - ֵޣ -} - -function DESEncryptEcbStrToHex(const Str: AnsiString; const Key: AnsiString): AnsiString; -{* KeyDES ܷתʮƵģʹ ECB ģʽĩβܲ #0 - - - const Str: AnsiString - ַܵ - const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 - - ֵAnsiString - ؼܺʮַ -} - -function DESDecryptEcbStrFromHex(const HexStr: AnsiString; const Key: AnsiString): AnsiString; -{* ʮƵ KeyDES ܷģʹ ECB ģʽ - - - const HexStr: AnsiString - ܵʮַ - const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 - - ֵAnsiString - ؽַܺ -} - -function DESEncryptCbcStrToHex(const Str: AnsiString; const Key: AnsiString; const Iv: AnsiString): AnsiString; -{* Key IvDES ܷתʮƵģʹ CBC ģʽĩβܲ #0 - - - const Str: AnsiString - ַܵ - const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 - const Iv: AnsiString - 8 ֽڳʼ - - ֵAnsiString - ؼܺʮַ -} - -function DESDecryptCbcStrFromHex(const HexStr: AnsiString; const Key: AnsiString; - const Iv: AnsiString): AnsiString; -{* ʮƵ Key IvDES ܷģʹ ECB ģʽ - - - const HexStr: AnsiString - ܵʮַ - const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 - const Iv: AnsiString - 8 ֽڳʼ - - ֵAnsiString - ؽַܺ -} - -function DESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; -{* ֽ DES ܣʹ ECB ģʽ - - - Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 - Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı - - ֵTBytes - ؼֽܺ -} - -function DESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; -{* ֽ DES ܣʹ ECB ģʽ - - - Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 - Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı - - ֵTBytes - ؽֽܺ -} - -function DESEncryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; -{* ֽ DES ܣʹ CBC ģʽ - - - Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 - Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 - Input: TBytes - ֽܵ - - ֵTBytes - ؼֽܺ -} - -function DESDecryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; -{* ֽ DES ܣʹ CBC ģʽ - - - Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 - Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 - Input: TBytes - ֽܵ - - ֵTBytes - ؽֽܺ -} - -procedure DESEncryptStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnDESKey; Dest: TStream); overload; -{* DES ܣʹ ECB ģʽ - Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnDESKey - 8 ֽ DES Կ - Dest: TStream - - - ֵޣ -} - -procedure DESDecryptStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnDESKey; Dest: TStream); overload; -{* DES ܣʹ ECB ģʽ - Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnDESKey - 8 ֽ DES Կ - Dest: TStream - - - ֵޣ -} - -procedure DESEncryptStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; -{* DES ܣʹ CBC ģʽ - Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnDESKey - 8 ֽ DES Կ - const InitVector: TCnDESIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure DESDecryptStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; -{* DES ܣʹ CBC ģʽ - Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnDESKey - 8 ֽ DES Կ - const InitVector: TCnDESIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -// =========================== 3-DES (Triple DES) ============================== - -function TripleDESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; -{* ֽڳȼȡǿ - - - InputByteLength: Integer - ֽڳ - - ֵInteger - 3DES ֽڳ -} - -procedure TripleDESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); -{* AnsiString 3DES ܣʹ ECB ģʽ - - - Key: AnsiString - 24ֽ 3DES Կ̫ضϣ #0 - const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı - Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 - - ֵޣ -} - -procedure TripleDESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); -{* AnsiString 3DES ܣʹ ECB ģʽ - - - Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 - const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı - Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 - - ֵޣ -} - -procedure TripleDESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; - const Input: AnsiString; Output: PAnsiChar); -{* AnsiString 3DES ܣʹ CBC ģʽ - - - Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 - Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ - const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı - Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 - - ֵޣ -} - -procedure TripleDESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; - const Input: AnsiString; Output: PAnsiChar); -{* AnsiString 3DES ܣʹ CBC ģʽ - - - Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 - Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ - const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı - Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 - - ֵޣ -} - -function TripleDESEncryptEcbStrToHex(const Str: AnsiString; const Key: AnsiString): AnsiString; -{* Key3DES ܷתʮƵģʹ ECB ģʽĩβܲ #0 - - - const Str: AnsiString - ַܵ - const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 - - ֵAnsiString - ؼܺʮַ -} - -function TripleDESDecryptEcbStrFromHex(const HexStr: AnsiString; const Key: AnsiString): AnsiString; -{* ʮƵ Key3DES ܷģʹ ECB ģʽ - - - const HexStr: AnsiString - ܵʮַ - const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 - - ֵAnsiString - ؽַܺ -} - -function TripleDESEncryptCbcStrToHex(const Str: AnsiString; const Key: AnsiString; - const Iv: AnsiString): AnsiString; -{* Key Iv3DES ܷתʮƵģʹ CBC ģʽĩβܲ #0 - - - const Str: AnsiString - ַܵ - const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 - const Iv: AnsiString - 8 ֽڳʼ - - ֵAnsiString - ؼܺʮַ -} - -function TripleDESDecryptCbcStrFromHex(const HexStr: AnsiString; - const Key: AnsiString; const Iv: AnsiString): AnsiString; -{* ʮƵ Key Iv3DES ܷģʹ CBC ģʽ - - - const HexStr: AnsiString - ܵʮַ - const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 - const Iv: AnsiString - 8 ֽڳʼ - - ֵAnsiString - ؽַܺ -} - -function TripleDESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; -{* ֽ 3DES ܣʹ ECB ģʽ - - - Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 - Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı - - ֵTBytes - ؼֽܺ -} - -function TripleDESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; -{* ֽ 3DES ܣʹ ECB ģʽ - - - Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 - Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı - - ֵTBytes - ؽֽܺ -} - -function TripleDESEncryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; -{* ֽ 3DES ܣʹ CBC ģʽ - - - Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 - Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 - Input: TBytes - ֽܵ - - ֵTBytes - ؼֽܺ -} - -function TripleDESDecryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; -{* ֽ 3DES ܣʹ CBC ģʽ - - - Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 - Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 - Input: TBytes - ֽܵ - - ֵTBytes - ؽֽܺ -} - -procedure TripleDESEncryptStreamECB(Source: TStream; Count: Cardinal; - const Key: TCn3DESKey; Dest: TStream); overload; -{* 3DES ܣʹ ECB ģʽ - Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnDESKey - 24 ֽ 3DES Կ - Dest: TStream - - - ֵޣ -} - -procedure TripleDESDecryptStreamECB(Source: TStream; Count: Cardinal; - const Key: TCn3DESKey; Dest: TStream); overload; -{* 3DES ܣʹ ECB ģʽ - Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCnDESKey - 24 ֽ 3DES Կ - Dest: TStream - - - ֵޣ -} - -procedure TripleDESEncryptStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; -{* 3DES ܣʹ CBC ģʽ - Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCn3DESKey - 24 ֽ 3DES Կ - const InitVector: TCnDESIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -procedure TripleDESDecryptStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; -{* 3DES ܣʹ CBC ģʽ - Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ - - - Source: TStream - ܵ - Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ - const Key: TCn3DESKey - 24 ֽ 3DES Կ - const InitVector: TCnDESIv - 8 ֽڳʼ - Dest: TStream - - - ֵޣ -} - -implementation - -resourcestring - SCnErrorDESInvalidInBufSize = 'Invalid Buffer Size for Decryption'; - SCnErrorDESReadError = 'Stream Read Error'; - SCnErrorDESWriteError = 'Stream Write Error'; - -type - TKeyByte = array[0..5] of Byte; - TDesMode = (dmEncry, dmDecry); - TSubKey = array[0..15] of TKeyByte; - -const - BitIP: array[0..63] of Byte = - (57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7, - 56, 48, 40, 32, 24, 16, 8, 0, - 58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6); - - BitCP: array[0..63] of Byte = - (39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25, - 32, 0, 40, 8, 48, 16, 56, 24); - - BitExp: array[0..47] of Integer = - (31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, - 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, - 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0); - - BitPM: array[0..31] of Byte = - (15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, - 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24); - - sBox: array[0..7] of array[0..63] of Byte = - ((14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, - 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, - 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, - 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13), - - (15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, - 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, - 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, - 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9), - - (10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, - 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, - 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, - 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12), - - (7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, - 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, - 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, - 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14), - - (2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, - 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, - 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, - 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3), - - (12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, - 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, - 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, - 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13), - - (4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, - 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, - 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, - 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12), - - (13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, - 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, - 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, - 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11)); - - BitPMC1: array[0..55] of Byte = - (56, 48, 40, 32, 24, 16, 8, - 0, 57, 49, 41, 33, 25, 17, - 9, 1, 58, 50, 42, 34, 26, - 18, 10, 2, 59, 51, 43, 35, - 62, 54, 46, 38, 30, 22, 14, - 6, 61, 53, 45, 37, 29, 21, - 13, 5, 60, 52, 44, 36, 28, - 20, 12, 4, 27, 19, 11, 3); - - BitPMC2: array[0..47] of Byte = - (13, 16, 10, 23, 0, 4, - 2, 27, 14, 5, 20, 9, - 22, 18, 11, 3, 25, 7, - 15, 6, 26, 19, 12, 1, - 40, 51, 30, 36, 46, 54, - 29, 39, 50, 44, 32, 47, - 43, 48, 38, 55, 33, 52, - 45, 41, 49, 35, 28, 31); - -function Min(A, B: Integer): Integer; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - if A < B then - Result := A - else - Result := B; -end; - -procedure InitPermutation(var InData: array of Byte); -var - NewData: array[0..7] of Byte; - I: Integer; -begin - FillChar(NewData, 8, 0); - for I := 0 to 63 do - if (InData[BitIP[I] shr 3] and (1 shl (7 - (BitIP[I] and $07)))) <> 0 then - NewData[I shr 3] := NewData[I shr 3] or (1 shl (7 - (I and $07))); - for I := 0 to 7 do InData[I] := NewData[I]; -end; - -procedure ConversePermutation(var InData: array of Byte); -var - NewData: array[0..7] of Byte; - I: Integer; -begin - FillChar(NewData, 8, 0); - for I := 0 to 63 do - if (InData[BitCP[I] shr 3] and (1 shl (7 - (BitCP[I] and $07)))) <> 0 then - NewData[I shr 3] := NewData[I shr 3] or (1 shl (7 - (I and $07))); - for I := 0 to 7 do InData[I] := NewData[I]; -end; - -procedure Expand(const InData: array of Byte; var OutData: array of Byte); -var - I: Integer; -begin - FillChar(OutData, 6, 0); - for I := 0 to 47 do - if (InData[BitExp[I] shr 3] and (1 shl (7 - (BitExp[I] and $07)))) <> 0 then - OutData[I shr 3] := OutData[I shr 3] or (1 shl (7 - (I and $07))); -end; - -procedure Permutation(var InData: array of Byte); -var - NewData: array[0..3] of Byte; - I: Integer; -begin - FillChar(NewData, 4, 0); - for I := 0 to 31 do - if (InData[BitPM[I] shr 3] and (1 shl (7 - (BitPM[I] and $07)))) <> 0 then - NewData[I shr 3] := NewData[I shr 3] or (1 shl (7 - (I and $07))); - for I := 0 to 3 do InData[I] := NewData[I]; -end; - -function Si(S, InByte: Byte): Byte; -var - c: Byte; -begin - c := (InByte and $20) or ((InByte and $1E) shr 1) or - ((InByte and $01) shl 4); - Result := (sBox[S][c] and $0F); -end; - -procedure PermutationChoose1(const InData: array of Byte; var OutData: array of Byte); -var - I: Integer; -begin - FillChar(OutData, 7, 0); - for I := 0 to 55 do - if (InData[BitPMC1[I] shr 3] and (1 shl (7 - (BitPMC1[I] and $07)))) <> 0 then - OutData[I shr 3] := OutData[I shr 3] or (1 shl (7 - (I and $07))); -end; - -procedure PermutationChoose2(const InData: array of Byte; var OutData: array of Byte); -var - I: Integer; -begin - FillChar(OutData, 6, 0); - for I := 0 to 47 do - if (InData[BitPMC2[I] shr 3] and (1 shl (7 - (BitPMC2[I] and $07)))) <> 0 then - OutData[I shr 3] := OutData[I shr 3] or (1 shl (7 - (I and $07))); -end; - -procedure CycleMove(var InData: array of Byte; bitMove: Byte); -var - I: Integer; -begin - for I := 0 to bitMove - 1 do - begin - InData[0] := (InData[0] shl 1) or (InData[1] shr 7); - InData[1] := (InData[1] shl 1) or (InData[2] shr 7); - InData[2] := (InData[2] shl 1) or (InData[3] shr 7); - InData[3] := (InData[3] shl 1) or ((InData[0] and $10) shr 4); - InData[0] := (InData[0] and $0F); - end; -end; - -procedure MakeKey(const InKey: array of Byte; var OutKey: array of TKeyByte); -const - bitDisplace: array[0..15] of Byte = - (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1); -var - OutData56: array[0..6] of Byte; - Key28l: array[0..3] of Byte; - Key28r: array[0..3] of Byte; - Key56o: array[0..6] of Byte; - I: Integer; -begin - PermutationChoose1(InKey, OutData56); - Key28l[0] := OutData56[0] shr 4; - Key28l[1] := (OutData56[0] shl 4) or (OutData56[1] shr 4); - Key28l[2] := (OutData56[1] shl 4) or (OutData56[2] shr 4); - Key28l[3] := (OutData56[2] shl 4) or (OutData56[3] shr 4); - Key28r[0] := OutData56[3] and $0F; - Key28r[1] := OutData56[4]; - Key28r[2] := OutData56[5]; - Key28r[3] := OutData56[6]; - for I := 0 to 15 do - begin - CycleMove(Key28l, bitDisplace[I]); - CycleMove(Key28r, bitDisplace[I]); - Key56o[0] := (Key28l[0] shl 4) or (Key28l[1] shr 4); - Key56o[1] := (Key28l[1] shl 4) or (Key28l[2] shr 4); - Key56o[2] := (Key28l[2] shl 4) or (Key28l[3] shr 4); - Key56o[3] := (Key28l[3] shl 4) or (Key28r[0]); - Key56o[4] := Key28r[1]; - Key56o[5] := Key28r[2]; - Key56o[6] := Key28r[3]; - PermutationChoose2(Key56o, OutKey[I]); - end; -end; - -procedure Encry(const InData, ASubKey: array of Byte; var OutData: array of Byte); -var - OutBuf: array[0..5] of Byte; - Buf: array[0..7] of Byte; - I: Integer; -begin - Expand(InData, OutBuf); - for I := 0 to 5 do OutBuf[I] := OutBuf[I] xor ASubKey[I]; - Buf[0] := OutBuf[0] shr 2; - Buf[1] := ((OutBuf[0] and $03) shl 4) or (OutBuf[1] shr 4); - Buf[2] := ((OutBuf[1] and $0F) shl 2) or (OutBuf[2] shr 6); - Buf[3] := OutBuf[2] and $3F; - Buf[4] := OutBuf[3] shr 2; - Buf[5] := ((OutBuf[3] and $03) shl 4) or (OutBuf[4] shr 4); - Buf[6] := ((OutBuf[4] and $0F) shl 2) or (OutBuf[5] shr 6); - Buf[7] := OutBuf[5] and $3F; - for I := 0 to 7 do Buf[I] := si(I, Buf[I]); - for I := 0 to 3 do OutBuf[I] := (Buf[I * 2] shl 4) or Buf[I * 2 + 1]; - Permutation(OutBuf); - for I := 0 to 3 do OutData[I] := OutBuf[I]; -end; - -// InData OutData Ҫ 8 ֽ -procedure DesData(DesMode: TDesMode; SubKey: TSubKey; const InData: array of Byte; - var OutData: array of Byte); -var - I, J: Integer; - Temp, Buf: array[0..3] of Byte; -begin - for I := 0 to 7 do OutData[I] := InData[I]; - InitPermutation(OutData); - if DesMode = dmEncry then - begin - for I := 0 to 15 do - begin - for J := 0 to 3 do Temp[J] := OutData[J]; - for J := 0 to 3 do OutData[J] := OutData[J + 4]; - Encry(OutData, SubKey[I], Buf); - for J := 0 to 3 do OutData[J + 4] := Temp[J] xor Buf[J]; - end; - for J := 0 to 3 do Temp[J] := OutData[J + 4]; - for J := 0 to 3 do OutData[J + 4] := OutData[J]; - for J := 0 to 3 do OutData[J] := Temp[J]; - end - else if DesMode = dmDecry then - begin - for I := 15 downto 0 do - begin - for J := 0 to 3 do Temp[J] := OutData[J]; - for J := 0 to 3 do OutData[J] := OutData[J + 4]; - Encry(OutData, SubKey[I], Buf); - for J := 0 to 3 do OutData[J + 4] := Temp[J] xor Buf[J]; - end; - for J := 0 to 3 do Temp[J] := OutData[J + 4]; - for J := 0 to 3 do OutData[J + 4] := OutData[J]; - for J := 0 to 3 do OutData[J] := Temp[J]; - end; - ConversePermutation(OutData); -end; - -// Key #0 ճ 8 ֽ -procedure MakeKeyAlign(var Key: AnsiString); -begin - if Length(Key) < CN_DES_KEYSIZE then - while Length(Key) < CN_DES_KEYSIZE do - Key := Key + Chr(0); -end; - -// ַ #0 ճ 8 ıעմ -procedure MakeInputAlign(var Str: AnsiString); -begin - while Length(Str) mod CN_DES_KEYSIZE <> 0 do - Str := Str + Chr(0); -end; - -// ֽ鲹 0 ճ 8 ıע鲻 -procedure MakeInputBytesAlign(var Input: TBytes); -var - I, Len, NL: Integer; -begin - Len := Length(Input); - if Len mod CN_DES_BLOCKSIZE <> 0 then - begin - NL := ((Len div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE; - SetLength(Input, NL); - for I := Len to NL - 1 do - Input[I] := 0; - end; -end; - -function DESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; -begin - Result := (((InputByteLength - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE; -end; - -procedure DESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); -var - StrByte, OutByte: TCnDESBuffer; - KeyByte: TCnDESKey; - Str: AnsiString; - I: Integer; - SubKey: TSubKey; -begin - MakeKeyAlign(Key); - - Str := Input; - MakeInputAlign(Str); // Str 8 ı - - if Str = '' then // մֱӷؿ - begin - if Output <> nil then - Output[0] := #0; - Exit; - end; - - Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); - MakeKey(KeyByte, SubKey); - - for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); - DesData(dmEncry, SubKey, StrByte, OutByte); - Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - end; -end; - -procedure DESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); -var - StrByte, OutByte: TCnDESBuffer; - KeyByte: TCnDESKey; - I: Integer; - SubKey: TSubKey; -begin - MakeKeyAlign(Key); - Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); - MakeKey(KeyByte, SubKey); - - for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); - DesData(dmDecry, SubKey, StrByte, OutByte); - Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - end; - - // ĩβ 0 ⲿжɾ -end; - -procedure DESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; - const Input: AnsiString; Output: PAnsiChar); -var - StrByte, OutByte: TCnDESBuffer; - KeyByte: TCnDESKey; - Vector: TCnDESIv; - Str: AnsiString; - I: Integer; - SubKey: TSubKey; -begin - MakeKeyAlign(Key); - - Str := Input; - MakeInputAlign(Str); - - if Str = '' then // մֱӷؿ - begin - if Output <> nil then - Output[0] := #0; - Exit; - end; - - Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); - MakeKey(KeyByte, SubKey); - Move(Iv^, Vector[0], SizeOf(TCnDESIv)); - - for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); - - // CBC ݿֵȸ Iv - PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; - - // ټ - DesData(dmEncry, SubKey, StrByte, OutByte); - Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - - // ܽµ Iv - Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); - end; -end; - -procedure DESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; - const Input: AnsiString; Output: PAnsiChar); -var - StrByte, OutByte: TCnDESBuffer; - KeyByte: TCnDESKey; - Vector, TV: TCnDESIv; - I: Integer; - SubKey: TSubKey; -begin - MakeKeyAlign(Key); - Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); - - MakeKey(KeyByte, SubKey); - Move(Iv^, Vector[0], SizeOf(TCnDESIv)); - - for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); - Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ - - // Ƚ - DesData(dmDecry, SubKey, StrByte, OutByte); - - // CBC ݿֵܺٸ Iv - PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; - - Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - - // ĸµ Iv - Move(TV[0], Vector[0], SizeOf(TCnDESIv)); - end; - - // ĩβ 0 ⲿжɾ -end; - -procedure SetResultLengthUsingInput(const Str: AnsiString; var Res: AnsiString); -var - Len: Integer; -begin - Len := Length(Str); - if Len < CN_DES_BLOCKSIZE then - Len := CN_DES_BLOCKSIZE - else - Len := (((Len - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE; - SetLength(Res, Len); -end; - -function DESEncryptEcbStrToHex(const Str, Key: AnsiString): AnsiString; -var - TempResult: AnsiString; -begin - Result := ''; - if Str = '' then - Exit; - - SetResultLengthUsingInput(Str, TempResult); - DESEncryptEcbStr(Key, Str, @TempResult[1]); - Result := AnsiStrToHex(TempResult); -end; - -function DESDecryptEcbStrFromHex(const HexStr, Key: AnsiString): AnsiString; -var - Str: AnsiString; -begin - Str := HexToAnsiStr(HexStr); - SetResultLengthUsingInput(Str, Result); - DESDecryptEcbStr(Key, Str, @(Result[1])); -end; - -function DESEncryptCbcStrToHex(const Str, Key, Iv: AnsiString): AnsiString; -var - TempResult: AnsiString; -begin - Result := ''; - if Str = '' then - Exit; - - SetResultLengthUsingInput(Str, TempResult); - DESEncryptCbcStr(Key, PAnsiChar(Iv), Str, @TempResult[1]); - Result := AnsiStrToHex(TempResult); -end; - -function DESDecryptCbcStrFromHex(const HexStr, Key, Iv: AnsiString): AnsiString; -var - Str: AnsiString; -begin - Str := HexToAnsiStr(HexStr); - SetResultLengthUsingInput(Str, Result); - DESDecryptCbcStr(Key, PAnsiChar(Iv), Str, @(Result[1])); -end; - -function DESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; -var - StrByte, OutByte: TCnDESBuffer; - KeyByte: TCnDESKey; - I: Integer; - SubKey: TSubKey; -begin - if Length(Input) <= 0 then - begin - Result := nil; - Exit; - end; - - MakeInputBytesAlign(Input); - - FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); - MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); - MakeKey(KeyByte, SubKey); - - SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); - for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); - DesData(dmEncry, SubKey, StrByte, OutByte); - Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - end; -end; - -function DESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; -var - StrByte, OutByte: TCnDESBuffer; - KeyByte: TCnDESKey; - I: Integer; - SubKey: TSubKey; -begin - if Length(Input) <= 0 then - begin - Result := nil; - Exit; - end; - - FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); - MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); - MakeKey(KeyByte, SubKey); - - SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); - for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); - DesData(dmDecry, SubKey, StrByte, OutByte); - Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - end; -end; - -function DESEncryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; -var - StrByte, OutByte: TCnDESBuffer; - KeyByte: TCnDESKey; - Vector: TCnDESIv; - I: Integer; - SubKey: TSubKey; -begin - if Length(Input) <= 0 then - begin - Result := nil; - Exit; - end; - - MakeInputBytesAlign(Input); - - FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); - MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); - MakeKey(KeyByte, SubKey); - - FillChar(Vector[0], SizeOf(TCnDESIv), 0); - MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); - - SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); - for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); - - // CBC ݿֵȸ Iv - PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; - - // ټ - DesData(dmEncry, SubKey, StrByte, OutByte); - Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - - // ܽµ Iv - Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); - end; -end; - -function DESDecryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; -var - StrByte, OutByte: TCnDESBuffer; - KeyByte: TCnDESKey; - Vector, TV: TCnDESIv; - I: Integer; - SubKey: TSubKey; -begin - if Length(Input) <= 0 then - begin - Result := nil; - Exit; - end; - - FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); - MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); - MakeKey(KeyByte, SubKey); - - FillChar(Vector[0], SizeOf(TCnDESIv), 0); - MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); - - SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); - for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); - Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ - - // Ƚ - DesData(dmDecry, SubKey, StrByte, OutByte); - - // CBC ݿֵܺٸ Iv - PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; - - Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - - // ĸµ Iv - Move(TV[0], Vector[0], SizeOf(TCnDESIv)); - end; -end; - -procedure DESEncryptStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnDESKey; Dest: TStream); overload; -var - TempIn, TempOut: TCnDESBuffer; - Done: Cardinal; - SubKey: TSubKey; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else - Count := Min(Count, Source.Size - Source.Position); - - if Count = 0 then - Exit; - - MakeKey(Key, SubKey); - while Count >= SizeOf(TCnDESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorDESReadError); - - DesData(dmEncry, SubKey, TempIn, TempOut); - - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorDESWriteError); - - Dec(Count, SizeOf(TCnDESBuffer)); - end; - - if Count > 0 then // β 0 - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorDESReadError); - FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); - - DesData(dmEncry, SubKey, TempIn, TempOut); - - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorDESWriteError); - end; -end; - -procedure DESDecryptStreamECB(Source: TStream; Count: Cardinal; - const Key: TCnDESKey; Dest: TStream); overload; -var - TempIn, TempOut: TCnDESBuffer; - Done: Cardinal; - SubKey: TSubKey; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else - Count := Min(Count, Source.Size - Source.Position); - - if Count = 0 then - Exit; - if (Count mod SizeOf(TCnDESBuffer)) > 0 then - raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); - - MakeKey(Key, SubKey); - while Count >= SizeOf(TCnDESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorDESReadError); - - DesData(dmDecry, SubKey, TempIn, TempOut); - - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorDESWriteError); - - Dec(Count, SizeOf(TCnDESBuffer)); - end; -end; - -procedure DESEncryptStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; -var - TempIn, TempOut: TCnDESBuffer; - Vector: TCnDESIv; - Done: Cardinal; - SubKey: TSubKey; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else - Count := Min(Count, Source.Size - Source.Position); - - if Count = 0 then - Exit; - - Vector := InitVector; - MakeKey(Key, SubKey); - - while Count >= SizeOf(TCnDESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorDESReadError); - - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; - - DesData(dmEncry, SubKey, TempIn, TempOut); - - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorDESWriteError); - - Move(TempOut[0], Vector[0], SizeOf(TCnDESIv)); - Dec(Count, SizeOf(TCnDESBuffer)); - end; - - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorDESReadError); - FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); - - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; - - DesData(dmEncry, SubKey, TempIn, TempOut); - - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorDESWriteError); - end; -end; - -procedure DESDecryptStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; -var - TempIn, TempOut: TCnDESBuffer; - Vector1, Vector2: TCnDESIv; - Done: Cardinal; - SubKey: TSubKey; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else - Count := Min(Count, Source.Size - Source.Position); - - if Count = 0 then - Exit; - if (Count mod SizeOf(TCnDESBuffer)) > 0 then - raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); - - Vector1 := InitVector; - MakeKey(Key, SubKey); - - while Count >= SizeOf(TCnDESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorDESReadError); - - Move(TempIn[0], Vector2[0], SizeOf(TCnDESIv)); - DesData(dmDecry, SubKey, TempIn, TempOut); - - PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; - - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError(SCnErrorDESWriteError); - - Vector1 := Vector2; - Dec(Count, SizeOf(TCnDESBuffer)); - end; -end; - -procedure Make3DESKeys(Keys: AnsiString; var K1, K2, K3: TCnDESKey); overload; -var - I: Integer; -begin - if Length(Keys) < CN_TRIPLE_DES_KEYSIZE then - while Length(Keys) < CN_TRIPLE_DES_KEYSIZE do - Keys := Keys + Chr(0); - - for I := 0 to CN_DES_KEYSIZE - 1 do - begin - K1[I] := Ord(Keys[I + 1]); - K2[I] := Ord(Keys[I + 1 + CN_DES_KEYSIZE]); - K3[I] := Ord(Keys[I + 1 + CN_DES_KEYSIZE * 2]); - end; -end; - -procedure Make3DESKeys(Keys: TCn3DESKey; var K1, K2, K3: TCnDESKey); overload; -var - I: Integer; -begin - for I := 0 to CN_DES_KEYSIZE - 1 do - begin - K1[I] := Keys[I]; - K2[I] := Keys[I + CN_DES_KEYSIZE]; - K3[I] := Keys[I + CN_DES_KEYSIZE * 2]; - end; -end; - -procedure Make3DESKeys(Keys: TBytes; var K1, K2, K3: TCnDESKey); overload; -var - I, Len: Integer; -begin - Len := Length(Keys); - if Len < CN_TRIPLE_DES_KEYSIZE then - begin - SetLength(Keys, CN_TRIPLE_DES_KEYSIZE); - for I := Len to CN_TRIPLE_DES_KEYSIZE - 1 do - Keys[I] := 0; - end; - - for I := 0 to CN_DES_KEYSIZE - 1 do - begin - K1[I] := Ord(Keys[I]); - K2[I] := Ord(Keys[I + CN_DES_KEYSIZE]); - K3[I] := Ord(Keys[I + CN_DES_KEYSIZE * 2]); - end; -end; - -function TripleDESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; -begin - Result := (((InputByteLength - 1) div CN_TRIPLE_DES_BLOCKSIZE) + 1) * CN_TRIPLE_DES_BLOCKSIZE; -end; - -procedure TripleDESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); -var - StrByte, OutByte: TCnDESBuffer; - K1, K2, K3: TCnDESKey; - Str: AnsiString; - I: Integer; - SubKey1, SubKey2, SubKey3: TSubKey; -begin - Make3DESKeys(Key, K1, K2, K3); - MakeKey(K1, SubKey1); - MakeKey(K2, SubKey2); - MakeKey(K3, SubKey3); - - Str := Input; - MakeInputAlign(Str); - - if Str = '' then // մֱӷؿ - begin - if Output <> nil then - Output[0] := #0; - Exit; - end; - - for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); - - DesData(dmEncry, SubKey1, StrByte, OutByte); - DesData(dmDecry, SubKey2, OutByte, StrByte); - DesData(dmEncry, SubKey3, StrByte, OutByte); - - Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - end; -end; - -procedure TripleDESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); -var - StrByte, OutByte: TCnDESBuffer; - K1, K2, K3: TCnDESKey; - I: Integer; - SubKey1, SubKey2, SubKey3: TSubKey; -begin - Make3DESKeys(Key, K1, K2, K3); - MakeKey(K1, SubKey1); - MakeKey(K2, SubKey2); - MakeKey(K3, SubKey3); - - for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); - - DesData(dmDecry, SubKey3, StrByte, OutByte); - DesData(dmEncry, SubKey2, OutByte, StrByte); - DesData(dmDecry, SubKey1, StrByte, OutByte); - - Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - end; - - // ĩβ 0 ⲿжɾ -end; - -procedure TripleDESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; - const Input: AnsiString; Output: PAnsiChar); -var - StrByte, OutByte: TCnDESBuffer; - K1, K2, K3: TCnDESKey; - Vector: TCnDESIv; - Str: AnsiString; - I: Integer; - SubKey1, SubKey2, SubKey3: TSubKey; -begin - Make3DESKeys(Key, K1, K2, K3); - MakeKey(K1, SubKey1); - MakeKey(K2, SubKey2); - MakeKey(K3, SubKey3); - - Str := Input; - MakeInputAlign(Str); - - if Str = '' then // մֱӷؿ - begin - if Output <> nil then - Output[0] := #0; - Exit; - end; - - Move(Iv^, Vector[0], SizeOf(TCnDESIv)); - - for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); - - // CBC ݿֵȸ Iv - PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; - - // ټ - DesData(dmEncry, SubKey1, StrByte, OutByte); - DesData(dmDecry, SubKey2, OutByte, StrByte); - DesData(dmEncry, SubKey3, StrByte, OutByte); - - Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - - // ܽµ Iv - Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); - end; -end; - -procedure TripleDESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; - const Input: AnsiString; Output: PAnsiChar); -var - StrByte, OutByte: TCnDESBuffer; - K1, K2, K3: TCnDESKey; - Vector, TV: TCnDESIv; - I: Integer; - SubKey1, SubKey2, SubKey3: TSubKey; -begin - Make3DESKeys(Key, K1, K2, K3); - MakeKey(K1, SubKey1); - MakeKey(K2, SubKey2); - MakeKey(K3, SubKey3); - - Move(Iv^, Vector[0], SizeOf(TCnDESIv)); - - for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); - Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ - - // Ƚ - DesData(dmDecry, SubKey3, StrByte, OutByte); - DesData(dmEncry, SubKey2, OutByte, StrByte); - DesData(dmDecry, SubKey1, StrByte, OutByte); - - // CBC ݿֵܺٸ Iv - PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; - - Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - - // ĸµ Iv - Move(TV[0], Vector[0], SizeOf(TCnDESIv)); - end; - - // ĩβ 0 ⲿжɾ -end; - -function TripleDESEncryptEcbStrToHex(const Str, Key: AnsiString): AnsiString; -var - TempResult, Temp: AnsiString; - I: Integer; -begin - SetResultLengthUsingInput(Str, TempResult); - TripleDESEncryptEcbStr(Key, Str, @TempResult[1]); - - Result := ''; - for I := 0 to Length(TempResult) - 1 do - begin - Temp := AnsiString(Format('%x', [Ord(TempResult[I + 1])])); - if Length(Temp) = 1 then - Temp := '0' + Temp; - Result := Result + Temp; - end; -end; - -function TripleDESDecryptEcbStrFromHex(const HexStr, Key: AnsiString): AnsiString; -var - Str: AnsiString; -begin - Str := HexToAnsiStr(HexStr); - SetResultLengthUsingInput(Str, Result); - TripleDESDecryptEcbStr(Key, Str, @(Result[1])); -end; - -function TripleDESEncryptCbcStrToHex(const Str, Key, Iv: AnsiString): AnsiString; -var - TempResult, Temp: AnsiString; - I: Integer; -begin - SetResultLengthUsingInput(Str, TempResult); - TripleDESEncryptCbcStr(Key, PAnsiChar(Iv), Str, @TempResult[1]); - - Result := ''; - for I := 0 to Length(TempResult) - 1 do - begin - Temp := AnsiString(Format('%x', [Ord(TempResult[I + 1])])); - if Length(Temp) = 1 then - Temp := '0' + Temp; - Result := Result + Temp; - end; -end; - -function TripleDESDecryptCbcStrFromHex(const HexStr, Key, Iv: AnsiString): AnsiString; -var - Str: AnsiString; -begin - Str := HexToAnsiStr(HexStr); - SetResultLengthUsingInput(Str, Result); - TripleDESDecryptCbcStr(Key, PAnsiChar(Iv), Str, @(Result[1])); -end; - -function TripleDESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; -var - StrByte, OutByte: TCnDESBuffer; - K1, K2, K3: TCnDESKey; - I: Integer; - SubKey1, SubKey2, SubKey3: TSubKey; -begin - if Length(Input) <= 0 then - begin - Result := nil; - Exit; - end; - - Make3DESKeys(Key, K1, K2, K3); - MakeKey(K1, SubKey1); - MakeKey(K2, SubKey2); - MakeKey(K3, SubKey3); - - MakeInputBytesAlign(Input); - - SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); - for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); - - DesData(dmEncry, SubKey1, StrByte, OutByte); - DesData(dmDecry, SubKey2, OutByte, StrByte); - DesData(dmEncry, SubKey3, StrByte, OutByte); - - Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - end; -end; - -function TripleDESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; -var - StrByte, OutByte: TCnDESBuffer; - K1, K2, K3: TCnDESKey; - I: Integer; - SubKey1, SubKey2, SubKey3: TSubKey; -begin - if Length(Input) <= 0 then - begin - Result := nil; - Exit; - end; - - Make3DESKeys(Key, K1, K2, K3); - MakeKey(K1, SubKey1); - MakeKey(K2, SubKey2); - MakeKey(K3, SubKey3); - - SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); - for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); - - DesData(dmDecry, SubKey3, StrByte, OutByte); - DesData(dmEncry, SubKey2, OutByte, StrByte); - DesData(dmDecry, SubKey1, StrByte, OutByte); - - Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - end; -end; - -function TripleDESEncryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; -var - StrByte, OutByte: TCnDESBuffer; - K1, K2, K3: TCnDESKey; - Vector: TCnDESIv; - I: Integer; - SubKey1, SubKey2, SubKey3: TSubKey; -begin - if Length(Input) <= 0 then - begin - Result := nil; - Exit; - end; - - Make3DESKeys(Key, K1, K2, K3); - MakeKey(K1, SubKey1); - MakeKey(K2, SubKey2); - MakeKey(K3, SubKey3); - - MakeInputBytesAlign(Input); - FillChar(Vector[0], SizeOf(TCnDESIv), 0); - MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); - - SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); - for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); - - // CBC ݿֵȸ Iv - PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; - - // ټ - DesData(dmEncry, SubKey1, StrByte, OutByte); - DesData(dmDecry, SubKey2, OutByte, StrByte); - DesData(dmEncry, SubKey3, StrByte, OutByte); - - Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - - // ܽµ Iv - Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); - end; -end; - -function TripleDESDecryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; -var - StrByte, OutByte: TCnDESBuffer; - K1, K2, K3: TCnDESKey; - Vector, TV: TCnDESIv; - I: Integer; - SubKey1, SubKey2, SubKey3: TSubKey; -begin - if Length(Input) <= 0 then - begin - Result := nil; - Exit; - end; - - Make3DESKeys(Key, K1, K2, K3); - MakeKey(K1, SubKey1); - MakeKey(K2, SubKey2); - MakeKey(K3, SubKey3); - - FillChar(Vector[0], SizeOf(TCnDESIv), 0); - MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); - - SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); - for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do - begin - Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); - Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ - - // Ƚ - DesData(dmDecry, SubKey3, StrByte, OutByte); - DesData(dmEncry, SubKey2, OutByte, StrByte); - DesData(dmDecry, SubKey1, StrByte, OutByte); - - // CBC ݿֵܺٸ Iv - PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; - - Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); - - // ĸµ Iv - Move(TV[0], Vector[0], SizeOf(TCnDESIv)); - end; -end; - -procedure TripleDESEncryptStreamECB(Source: TStream; Count: Cardinal; - const Key: TCn3DESKey; Dest: TStream); overload; -var - K1, K2, K3: TCnDESKey; - TempIn, TempOut: TCnDESBuffer; - Done: Cardinal; - SubKey1, SubKey2, SubKey3: TSubKey; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else - Count := Min(Count, Source.Size - Source.Position); - - if Count = 0 then - Exit; - - Make3DESKeys(Key, K1, K2, K3); - MakeKey(K1, SubKey1); - MakeKey(K2, SubKey2); - MakeKey(K3, SubKey3); - - while Count >= SizeOf(TCnDESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorDESReadError); - - DesData(dmEncry, SubKey1, TempIn, TempOut); - DesData(dmDecry, SubKey2, TempOut, TempIn); - DesData(dmEncry, SubKey3, TempIn, TempOut); - - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorDESWriteError); - - Dec(Count, SizeOf(TCnDESBuffer)); - end; - - if Count > 0 then // β 0 - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorDESReadError); - FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); - - DesData(dmEncry, SubKey1, TempIn, TempOut); - DesData(dmDecry, SubKey2, TempOut, TempIn); - DesData(dmEncry, SubKey3, TempIn, TempOut); - - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorDESWriteError); - end; -end; - -procedure TripleDESDecryptStreamECB(Source: TStream; Count: Cardinal; - const Key: TCn3DESKey; Dest: TStream); overload; -var - K1, K2, K3: TCnDESKey; - TempIn, TempOut: TCnDESBuffer; - Done: Cardinal; - SubKey1, SubKey2, SubKey3: TSubKey; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else - Count := Min(Count, Source.Size - Source.Position); - - if Count = 0 then - Exit; - if (Count mod SizeOf(TCnDESBuffer)) > 0 then - raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); - - Make3DESKeys(Key, K1, K2, K3); - MakeKey(K1, SubKey1); - MakeKey(K2, SubKey2); - MakeKey(K3, SubKey3); - - while Count >= SizeOf(TCnDESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorDESReadError); - - DesData(dmDecry, SubKey3, TempIn, TempOut); - DesData(dmEncry, SubKey2, TempOut, TempIn); - DesData(dmDecry, SubKey1, TempIn, TempOut); - - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorDESWriteError); - - Dec(Count, SizeOf(TCnDESBuffer)); - end; -end; - -procedure TripleDESEncryptStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; -var - K1, K2, K3: TCnDESKey; - TempIn, TempOut: TCnDESBuffer; - Vector: TCnDESIv; - Done: Cardinal; - SubKey1, SubKey2, SubKey3: TSubKey; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else - Count := Min(Count, Source.Size - Source.Position); - - if Count = 0 then - Exit; - - Vector := InitVector; - Make3DESKeys(Key, K1, K2, K3); - MakeKey(K1, SubKey1); - MakeKey(K2, SubKey2); - MakeKey(K3, SubKey3); - - while Count >= SizeOf(TCnDESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError.Create(SCnErrorDESReadError); - - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; - - DesData(dmEncry, SubKey1, TempIn, TempOut); - DesData(dmDecry, SubKey2, TempOut, TempIn); - DesData(dmEncry, SubKey3, TempIn, TempOut); - - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorDESWriteError); - - Move(TempOut[0], Vector[0], SizeOf(TCnDESIv)); - Dec(Count, SizeOf(TCnDESBuffer)); - end; - - if Count > 0 then - begin - Done := Source.Read(TempIn, Count); - if Done < Count then - raise EStreamError.Create(SCnErrorDESReadError); - FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); - - PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; - PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; - - DesData(dmEncry, SubKey1, TempIn, TempOut); - DesData(dmDecry, SubKey2, TempOut, TempIn); - DesData(dmEncry, SubKey3, TempIn, TempOut); - - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError.Create(SCnErrorDESWriteError); - end; -end; - -procedure TripleDESDecryptStreamCBC(Source: TStream; Count: Cardinal; - const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; -var - K1, K2, K3: TCnDESKey; - TempIn, TempOut: TCnDESBuffer; - Vector1, Vector2: TCnDESIv; - Done: Cardinal; - SubKey1, SubKey2, SubKey3: TSubKey; -begin - if Count = 0 then - begin - Source.Position := 0; - Count := Source.Size; - end - else - Count := Min(Count, Source.Size - Source.Position); - - if Count = 0 then - Exit; - if (Count mod SizeOf(TCnDESBuffer)) > 0 then - raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); - - Vector1 := InitVector; - Make3DESKeys(Key, K1, K2, K3); - MakeKey(K1, SubKey1); - MakeKey(K2, SubKey2); - MakeKey(K3, SubKey3); - - while Count >= SizeOf(TCnDESBuffer) do - begin - Done := Source.Read(TempIn, SizeOf(TempIn)); - if Done < SizeOf(TempIn) then - raise EStreamError(SCnErrorDESReadError); - - Move(TempIn[0], Vector2[0], SizeOf(TCnDESIv)); - - DesData(dmDecry, SubKey3, TempIn, TempOut); - DesData(dmEncry, SubKey2, TempOut, TempIn); - DesData(dmDecry, SubKey1, TempIn, TempOut); - - PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; - PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; - - Done := Dest.Write(TempOut, SizeOf(TempOut)); - if Done < SizeOf(TempOut) then - raise EStreamError(SCnErrorDESWriteError); - - Vector1 := Vector2; - Dec(Count, SizeOf(TCnDESBuffer)); - end; -end; - -end. +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnDES; +{* |
+================================================================================
+* ƣ
+* ԪƣDES ԳƼӽ㷨ʵֵԪ
+* ԪߣCnPack  (master@cnpack.org)
+*           /ֲ䲿ֹܡ
+*     עԪʵ DES/3DES ԳƼӽ㷨ֿС 8 ֽڣʵ
+*           ECB/CBC ģʽ֧ģʽ
+*
+* ƽ̨PWin2000Pro + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2024.11.30 V1.7
+*               ɾ淶 DESEncryptStrToHex  DESDecryptStrToHex
+*               ɾ淶 TripleDESEncryptStrToHex  TripleDESDecryptStrToHex
+*                ECB 汾
+*               Ż PAnsiChar ʽ Iv Ĵ
+*           2024.10.12 V1.6
+*                3DES ²Խ⣬Ż Key  Iv Ķ봦
+*           2022.08.13 V1.5
+*               Կݼܷؿ
+*           2021.02.07 V1.4
+*               Ӷ TBytes ֧
+*           2020.03.25 V1.3
+*                3DES ֧
+*           2020.03.24 V1.2
+*                ECB/CBC ַӽܺɾԭеַܺ
+*           2019.04.15 V1.1
+*               ֧ Win32/Win64/MacOS
+*           2008.05.30 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, CnNative; + +const + CN_DES_KEYSIZE = 8; + {* DES Կȣ8 ֽ} + + CN_DES_BLOCKSIZE = 8; + {* DES ļܿ鳤ȣ8 ֽ} + + CN_TRIPLE_DES_KEYSIZE = CN_DES_KEYSIZE * 3; + {* 3DES Կȣ DES 24 ֽ} + + CN_TRIPLE_DES_BLOCKSIZE = CN_DES_BLOCKSIZE; + {* 3DES ļܿ鳤ȣ 8 ֽ} + +type + ECnDESException = class(Exception); + {* DES 쳣} + + TCnDESKey = array[0..CN_DES_KEYSIZE - 1] of Byte; + {* DES ļ Key8 ֽ} + + TCnDESBuffer = array[0..CN_DES_BLOCKSIZE - 1] of Byte; + {* DES ļܿ飬8 ֽ} + + TCnDESIv = array[0..CN_DES_BLOCKSIZE - 1] of Byte; + {* DES CBC ijʼ8 ֽ} + + TCn3DESKey = array[0..CN_TRIPLE_DES_KEYSIZE - 1] of Byte; + {* 3DES Կȣ DES 24 ֽ} + + TCn3DESBuffer = TCnDESBuffer; + {* 3DES ļܿ飬 DES ļܿ飬8 ֽ} + + TCn3DESIv = TCnDESIv; + {* 3DES CBC ijʼ DES CBC ijʼ8 ֽ} + +// ================================= DES ======================================= + +function DESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; +{* ֽڳȼ DES ȡǿ + + + InputByteLength: Integer - ֽڳ + + ֵInteger - DES ij +} + +procedure DESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +{* AnsiString DES ܣʹ ECB ģʽ + + + Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure DESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +{* AnsiString DES ܣʹ ECB ģʽ + + + Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure DESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; const Input: AnsiString; + Output: PAnsiChar); +{* AnsiString DES ܣʹ CBC ģʽ + + + Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure DESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; const Input: AnsiString; + Output: PAnsiChar); +{* AnsiString DES ܣʹ CBC ģʽ + + + Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +function DESEncryptEcbStrToHex(const Str: AnsiString; const Key: AnsiString): AnsiString; +{* KeyDES ܷתʮƵģʹ ECB ģʽĩβܲ #0 + + + const Str: AnsiString - ַܵ + const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + + ֵAnsiString - ؼܺʮַ +} + +function DESDecryptEcbStrFromHex(const HexStr: AnsiString; const Key: AnsiString): AnsiString; +{* ʮƵ KeyDES ܷģʹ ECB ģʽ + + + const HexStr: AnsiString - ܵʮַ + const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + + ֵAnsiString - ؽַܺ +} + +function DESEncryptCbcStrToHex(const Str: AnsiString; const Key: AnsiString; const Iv: AnsiString): AnsiString; +{* Key IvDES ܷתʮƵģʹ CBC ģʽĩβܲ #0 + + + const Str: AnsiString - ַܵ + const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + const Iv: AnsiString - 8 ֽڳʼ + + ֵAnsiString - ؼܺʮַ +} + +function DESDecryptCbcStrFromHex(const HexStr: AnsiString; const Key: AnsiString; + const Iv: AnsiString): AnsiString; +{* ʮƵ Key IvDES ܷģʹ ECB ģʽ + + + const HexStr: AnsiString - ܵʮַ + const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + const Iv: AnsiString - 8 ֽڳʼ + + ֵAnsiString - ؽַܺ +} + +function DESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +{* ֽ DES ܣʹ ECB ģʽ + + + Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 + Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı + + ֵTBytes - ؼֽܺ +} + +function DESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +{* ֽ DES ܣʹ ECB ģʽ + + + Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 + Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı + + ֵTBytes - ؽֽܺ +} + +function DESEncryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; +{* ֽ DES ܣʹ CBC ģʽ + + + Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 + Input: TBytes - ֽܵ + + ֵTBytes - ؼֽܺ +} + +function DESDecryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; +{* ֽ DES ܣʹ CBC ģʽ + + + Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 + Input: TBytes - ֽܵ + + ֵTBytes - ؽֽܺ +} + +procedure DESEncryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; Dest: TStream); overload; +{* DES ܣʹ ECB ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 8 ֽ DES Կ + Dest: TStream - + + ֵޣ +} + +procedure DESDecryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; Dest: TStream); overload; +{* DES ܣʹ ECB ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 8 ֽ DES Կ + Dest: TStream - + + ֵޣ +} + +procedure DESEncryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +{* DES ܣʹ CBC ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 8 ֽ DES Կ + const InitVector: TCnDESIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DESDecryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +{* DES ܣʹ CBC ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 8 ֽ DES Կ + const InitVector: TCnDESIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// =========================== 3-DES (Triple DES) ============================== + +function TripleDESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; +{* ֽڳȼȡǿ + + + InputByteLength: Integer - ֽڳ + + ֵInteger - 3DES ֽڳ +} + +procedure TripleDESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +{* AnsiString 3DES ܣʹ ECB ģʽ + + + Key: AnsiString - 24ֽ 3DES Կ̫ضϣ #0 + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure TripleDESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +{* AnsiString 3DES ܣʹ ECB ģʽ + + + Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure TripleDESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +{* AnsiString 3DES ܣʹ CBC ģʽ + + + Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure TripleDESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +{* AnsiString 3DES ܣʹ CBC ģʽ + + + Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +function TripleDESEncryptEcbStrToHex(const Str: AnsiString; const Key: AnsiString): AnsiString; +{* Key3DES ܷתʮƵģʹ ECB ģʽĩβܲ #0 + + + const Str: AnsiString - ַܵ + const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + + ֵAnsiString - ؼܺʮַ +} + +function TripleDESDecryptEcbStrFromHex(const HexStr: AnsiString; const Key: AnsiString): AnsiString; +{* ʮƵ Key3DES ܷģʹ ECB ģʽ + + + const HexStr: AnsiString - ܵʮַ + const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + + ֵAnsiString - ؽַܺ +} + +function TripleDESEncryptCbcStrToHex(const Str: AnsiString; const Key: AnsiString; + const Iv: AnsiString): AnsiString; +{* Key Iv3DES ܷתʮƵģʹ CBC ģʽĩβܲ #0 + + + const Str: AnsiString - ַܵ + const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + const Iv: AnsiString - 8 ֽڳʼ + + ֵAnsiString - ؼܺʮַ +} + +function TripleDESDecryptCbcStrFromHex(const HexStr: AnsiString; + const Key: AnsiString; const Iv: AnsiString): AnsiString; +{* ʮƵ Key Iv3DES ܷģʹ CBC ģʽ + + + const HexStr: AnsiString - ܵʮַ + const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + const Iv: AnsiString - 8 ֽڳʼ + + ֵAnsiString - ؽַܺ +} + +function TripleDESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +{* ֽ 3DES ܣʹ ECB ģʽ + + + Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 + Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı + + ֵTBytes - ؼֽܺ +} + +function TripleDESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +{* ֽ 3DES ܣʹ ECB ģʽ + + + Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 + Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı + + ֵTBytes - ؽֽܺ +} + +function TripleDESEncryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; +{* ֽ 3DES ܣʹ CBC ģʽ + + + Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 + Input: TBytes - ֽܵ + + ֵTBytes - ؼֽܺ +} + +function TripleDESDecryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; +{* ֽ 3DES ܣʹ CBC ģʽ + + + Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 + Input: TBytes - ֽܵ + + ֵTBytes - ؽֽܺ +} + +procedure TripleDESEncryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; Dest: TStream); overload; +{* 3DES ܣʹ ECB ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 24 ֽ 3DES Կ + Dest: TStream - + + ֵޣ +} + +procedure TripleDESDecryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; Dest: TStream); overload; +{* 3DES ܣʹ ECB ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 24 ֽ 3DES Կ + Dest: TStream - + + ֵޣ +} + +procedure TripleDESEncryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +{* 3DES ܣʹ CBC ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCn3DESKey - 24 ֽ 3DES Կ + const InitVector: TCnDESIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure TripleDESDecryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +{* 3DES ܣʹ CBC ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCn3DESKey - 24 ֽ 3DES Կ + const InitVector: TCnDESIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +implementation + +resourcestring + SCnErrorDESInvalidInBufSize = 'Invalid Buffer Size for Decryption'; + SCnErrorDESReadError = 'Stream Read Error'; + SCnErrorDESWriteError = 'Stream Write Error'; + +type + TKeyByte = array[0..5] of Byte; + TDesMode = (dmEncry, dmDecry); + TSubKey = array[0..15] of TKeyByte; + +const + BitIP: array[0..63] of Byte = + (57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7, + 56, 48, 40, 32, 24, 16, 8, 0, + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6); + + BitCP: array[0..63] of Byte = + (39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25, + 32, 0, 40, 8, 48, 16, 56, 24); + + BitExp: array[0..47] of Integer = + (31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, + 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, + 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0); + + BitPM: array[0..31] of Byte = + (15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, + 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24); + + sBox: array[0..7] of array[0..63] of Byte = + ((14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13), + + (15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9), + + (10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12), + + (7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14), + + (2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3), + + (12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13), + + (4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12), + + (13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11)); + + BitPMC1: array[0..55] of Byte = + (56, 48, 40, 32, 24, 16, 8, + 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, + 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, + 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, + 20, 12, 4, 27, 19, 11, 3); + + BitPMC2: array[0..47] of Byte = + (13, 16, 10, 23, 0, 4, + 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, + 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, + 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, + 45, 41, 49, 35, 28, 31); + +function Min(A, B: Integer): Integer; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + if A < B then + Result := A + else + Result := B; +end; + +procedure InitPermutation(var InData: array of Byte); +var + NewData: array[0..7] of Byte; + I: Integer; +begin + FillChar(NewData, 8, 0); + for I := 0 to 63 do + if (InData[BitIP[I] shr 3] and (1 shl (7 - (BitIP[I] and $07)))) <> 0 then + NewData[I shr 3] := NewData[I shr 3] or (1 shl (7 - (I and $07))); + for I := 0 to 7 do InData[I] := NewData[I]; +end; + +procedure ConversePermutation(var InData: array of Byte); +var + NewData: array[0..7] of Byte; + I: Integer; +begin + FillChar(NewData, 8, 0); + for I := 0 to 63 do + if (InData[BitCP[I] shr 3] and (1 shl (7 - (BitCP[I] and $07)))) <> 0 then + NewData[I shr 3] := NewData[I shr 3] or (1 shl (7 - (I and $07))); + for I := 0 to 7 do InData[I] := NewData[I]; +end; + +procedure Expand(const InData: array of Byte; var OutData: array of Byte); +var + I: Integer; +begin + FillChar(OutData, 6, 0); + for I := 0 to 47 do + if (InData[BitExp[I] shr 3] and (1 shl (7 - (BitExp[I] and $07)))) <> 0 then + OutData[I shr 3] := OutData[I shr 3] or (1 shl (7 - (I and $07))); +end; + +procedure Permutation(var InData: array of Byte); +var + NewData: array[0..3] of Byte; + I: Integer; +begin + FillChar(NewData, 4, 0); + for I := 0 to 31 do + if (InData[BitPM[I] shr 3] and (1 shl (7 - (BitPM[I] and $07)))) <> 0 then + NewData[I shr 3] := NewData[I shr 3] or (1 shl (7 - (I and $07))); + for I := 0 to 3 do InData[I] := NewData[I]; +end; + +function Si(S, InByte: Byte): Byte; +var + c: Byte; +begin + c := (InByte and $20) or ((InByte and $1E) shr 1) or + ((InByte and $01) shl 4); + Result := (sBox[S][c] and $0F); +end; + +procedure PermutationChoose1(const InData: array of Byte; var OutData: array of Byte); +var + I: Integer; +begin + FillChar(OutData, 7, 0); + for I := 0 to 55 do + if (InData[BitPMC1[I] shr 3] and (1 shl (7 - (BitPMC1[I] and $07)))) <> 0 then + OutData[I shr 3] := OutData[I shr 3] or (1 shl (7 - (I and $07))); +end; + +procedure PermutationChoose2(const InData: array of Byte; var OutData: array of Byte); +var + I: Integer; +begin + FillChar(OutData, 6, 0); + for I := 0 to 47 do + if (InData[BitPMC2[I] shr 3] and (1 shl (7 - (BitPMC2[I] and $07)))) <> 0 then + OutData[I shr 3] := OutData[I shr 3] or (1 shl (7 - (I and $07))); +end; + +procedure CycleMove(var InData: array of Byte; bitMove: Byte); +var + I: Integer; +begin + for I := 0 to bitMove - 1 do + begin + InData[0] := (InData[0] shl 1) or (InData[1] shr 7); + InData[1] := (InData[1] shl 1) or (InData[2] shr 7); + InData[2] := (InData[2] shl 1) or (InData[3] shr 7); + InData[3] := (InData[3] shl 1) or ((InData[0] and $10) shr 4); + InData[0] := (InData[0] and $0F); + end; +end; + +procedure MakeKey(const InKey: array of Byte; var OutKey: array of TKeyByte); +const + bitDisplace: array[0..15] of Byte = + (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1); +var + OutData56: array[0..6] of Byte; + Key28l: array[0..3] of Byte; + Key28r: array[0..3] of Byte; + Key56o: array[0..6] of Byte; + I: Integer; +begin + PermutationChoose1(InKey, OutData56); + Key28l[0] := OutData56[0] shr 4; + Key28l[1] := (OutData56[0] shl 4) or (OutData56[1] shr 4); + Key28l[2] := (OutData56[1] shl 4) or (OutData56[2] shr 4); + Key28l[3] := (OutData56[2] shl 4) or (OutData56[3] shr 4); + Key28r[0] := OutData56[3] and $0F; + Key28r[1] := OutData56[4]; + Key28r[2] := OutData56[5]; + Key28r[3] := OutData56[6]; + for I := 0 to 15 do + begin + CycleMove(Key28l, bitDisplace[I]); + CycleMove(Key28r, bitDisplace[I]); + Key56o[0] := (Key28l[0] shl 4) or (Key28l[1] shr 4); + Key56o[1] := (Key28l[1] shl 4) or (Key28l[2] shr 4); + Key56o[2] := (Key28l[2] shl 4) or (Key28l[3] shr 4); + Key56o[3] := (Key28l[3] shl 4) or (Key28r[0]); + Key56o[4] := Key28r[1]; + Key56o[5] := Key28r[2]; + Key56o[6] := Key28r[3]; + PermutationChoose2(Key56o, OutKey[I]); + end; +end; + +procedure Encry(const InData, ASubKey: array of Byte; var OutData: array of Byte); +var + OutBuf: array[0..5] of Byte; + Buf: array[0..7] of Byte; + I: Integer; +begin + Expand(InData, OutBuf); + for I := 0 to 5 do OutBuf[I] := OutBuf[I] xor ASubKey[I]; + Buf[0] := OutBuf[0] shr 2; + Buf[1] := ((OutBuf[0] and $03) shl 4) or (OutBuf[1] shr 4); + Buf[2] := ((OutBuf[1] and $0F) shl 2) or (OutBuf[2] shr 6); + Buf[3] := OutBuf[2] and $3F; + Buf[4] := OutBuf[3] shr 2; + Buf[5] := ((OutBuf[3] and $03) shl 4) or (OutBuf[4] shr 4); + Buf[6] := ((OutBuf[4] and $0F) shl 2) or (OutBuf[5] shr 6); + Buf[7] := OutBuf[5] and $3F; + for I := 0 to 7 do Buf[I] := si(I, Buf[I]); + for I := 0 to 3 do OutBuf[I] := (Buf[I * 2] shl 4) or Buf[I * 2 + 1]; + Permutation(OutBuf); + for I := 0 to 3 do OutData[I] := OutBuf[I]; +end; + +// InData OutData Ҫ 8 ֽ +procedure DesData(DesMode: TDesMode; SubKey: TSubKey; const InData: array of Byte; + var OutData: array of Byte); +var + I, J: Integer; + Temp, Buf: array[0..3] of Byte; +begin + for I := 0 to 7 do OutData[I] := InData[I]; + InitPermutation(OutData); + if DesMode = dmEncry then + begin + for I := 0 to 15 do + begin + for J := 0 to 3 do Temp[J] := OutData[J]; + for J := 0 to 3 do OutData[J] := OutData[J + 4]; + Encry(OutData, SubKey[I], Buf); + for J := 0 to 3 do OutData[J + 4] := Temp[J] xor Buf[J]; + end; + for J := 0 to 3 do Temp[J] := OutData[J + 4]; + for J := 0 to 3 do OutData[J + 4] := OutData[J]; + for J := 0 to 3 do OutData[J] := Temp[J]; + end + else if DesMode = dmDecry then + begin + for I := 15 downto 0 do + begin + for J := 0 to 3 do Temp[J] := OutData[J]; + for J := 0 to 3 do OutData[J] := OutData[J + 4]; + Encry(OutData, SubKey[I], Buf); + for J := 0 to 3 do OutData[J + 4] := Temp[J] xor Buf[J]; + end; + for J := 0 to 3 do Temp[J] := OutData[J + 4]; + for J := 0 to 3 do OutData[J + 4] := OutData[J]; + for J := 0 to 3 do OutData[J] := Temp[J]; + end; + ConversePermutation(OutData); +end; + +// Key #0 ճ 8 ֽ +procedure MakeKeyAlign(var Key: AnsiString); +begin + if Length(Key) < CN_DES_KEYSIZE then + while Length(Key) < CN_DES_KEYSIZE do + Key := Key + Chr(0); +end; + +// ַ #0 ճ 8 ıעմ +procedure MakeInputAlign(var Str: AnsiString); +begin + while Length(Str) mod CN_DES_KEYSIZE <> 0 do + Str := Str + Chr(0); +end; + +// ֽ鲹 0 ճ 8 ıע鲻 +procedure MakeInputBytesAlign(var Input: TBytes); +var + I, Len, NL: Integer; +begin + Len := Length(Input); + if Len mod CN_DES_BLOCKSIZE <> 0 then + begin + NL := ((Len div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE; + SetLength(Input, NL); + for I := Len to NL - 1 do + Input[I] := 0; + end; +end; + +function DESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; +begin + Result := (((InputByteLength - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE; +end; + +procedure DESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Str: AnsiString; + I: Integer; + SubKey: TSubKey; +begin + MakeKeyAlign(Key); + + Str := Input; + MakeInputAlign(Str); // Str 8 ı + + if Str = '' then // մֱӷؿ + begin + if Output <> nil then + Output[0] := #0; + Exit; + end; + + Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + DesData(dmEncry, SubKey, StrByte, OutByte); + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +procedure DESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + I: Integer; + SubKey: TSubKey; +begin + MakeKeyAlign(Key); + Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + DesData(dmDecry, SubKey, StrByte, OutByte); + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; + + // ĩβ 0 ⲿжɾ +end; + +procedure DESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Vector: TCnDESIv; + Str: AnsiString; + I: Integer; + SubKey: TSubKey; +begin + MakeKeyAlign(Key); + + Str := Input; + MakeInputAlign(Str); + + if Str = '' then // մֱӷؿ + begin + if Output <> nil then + Output[0] := #0; + Exit; + end; + + Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + Move(Iv^, Vector[0], SizeOf(TCnDESIv)); + + for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + + // CBC ݿֵȸ Iv + PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; + + // ټ + DesData(dmEncry, SubKey, StrByte, OutByte); + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ܽµ Iv + Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +procedure DESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Vector, TV: TCnDESIv; + I: Integer; + SubKey: TSubKey; +begin + MakeKeyAlign(Key); + Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); + + MakeKey(KeyByte, SubKey); + Move(Iv^, Vector[0], SizeOf(TCnDESIv)); + + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ + + // Ƚ + DesData(dmDecry, SubKey, StrByte, OutByte); + + // CBC ݿֵܺٸ Iv + PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ĸµ Iv + Move(TV[0], Vector[0], SizeOf(TCnDESIv)); + end; + + // ĩβ 0 ⲿжɾ +end; + +procedure SetResultLengthUsingInput(const Str: AnsiString; var Res: AnsiString); +var + Len: Integer; +begin + Len := Length(Str); + if Len < CN_DES_BLOCKSIZE then + Len := CN_DES_BLOCKSIZE + else + Len := (((Len - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE; + SetLength(Res, Len); +end; + +function DESEncryptEcbStrToHex(const Str, Key: AnsiString): AnsiString; +var + TempResult: AnsiString; +begin + Result := ''; + if Str = '' then + Exit; + + SetResultLengthUsingInput(Str, TempResult); + DESEncryptEcbStr(Key, Str, @TempResult[1]); + Result := AnsiStrToHex(TempResult); +end; + +function DESDecryptEcbStrFromHex(const HexStr, Key: AnsiString): AnsiString; +var + Str: AnsiString; +begin + Str := HexToAnsiStr(HexStr); + SetResultLengthUsingInput(Str, Result); + DESDecryptEcbStr(Key, Str, @(Result[1])); +end; + +function DESEncryptCbcStrToHex(const Str, Key, Iv: AnsiString): AnsiString; +var + TempResult: AnsiString; +begin + Result := ''; + if Str = '' then + Exit; + + SetResultLengthUsingInput(Str, TempResult); + DESEncryptCbcStr(Key, PAnsiChar(Iv), Str, @TempResult[1]); + Result := AnsiStrToHex(TempResult); +end; + +function DESDecryptCbcStrFromHex(const HexStr, Key, Iv: AnsiString): AnsiString; +var + Str: AnsiString; +begin + Str := HexToAnsiStr(HexStr); + SetResultLengthUsingInput(Str, Result); + DESDecryptCbcStr(Key, PAnsiChar(Iv), Str, @(Result[1])); +end; + +function DESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + I: Integer; + SubKey: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + MakeInputBytesAlign(Input); + + FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); + MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + DesData(dmEncry, SubKey, StrByte, OutByte); + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +function DESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + I: Integer; + SubKey: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); + MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + DesData(dmDecry, SubKey, StrByte, OutByte); + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +function DESEncryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Vector: TCnDESIv; + I: Integer; + SubKey: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + MakeInputBytesAlign(Input); + + FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); + MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + FillChar(Vector[0], SizeOf(TCnDESIv), 0); + MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + + // CBC ݿֵȸ Iv + PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; + + // ټ + DesData(dmEncry, SubKey, StrByte, OutByte); + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ܽµ Iv + Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +function DESDecryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Vector, TV: TCnDESIv; + I: Integer; + SubKey: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); + MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + FillChar(Vector[0], SizeOf(TCnDESIv), 0); + MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ + + // Ƚ + DesData(dmDecry, SubKey, StrByte, OutByte); + + // CBC ݿֵܺٸ Iv + PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ĸµ Iv + Move(TV[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +procedure DESEncryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; Dest: TStream); overload; +var + TempIn, TempOut: TCnDESBuffer; + Done: Cardinal; + SubKey: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + + MakeKey(Key, SubKey); + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + DesData(dmEncry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Dec(Count, SizeOf(TCnDESBuffer)); + end; + + if Count > 0 then // β 0 + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorDESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + + DesData(dmEncry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + end; +end; + +procedure DESDecryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; Dest: TStream); overload; +var + TempIn, TempOut: TCnDESBuffer; + Done: Cardinal; + SubKey: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + if (Count mod SizeOf(TCnDESBuffer)) > 0 then + raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); + + MakeKey(Key, SubKey); + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + DesData(dmDecry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Dec(Count, SizeOf(TCnDESBuffer)); + end; +end; + +procedure DESEncryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +var + TempIn, TempOut: TCnDESBuffer; + Vector: TCnDESIv; + Done: Cardinal; + SubKey: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + + Vector := InitVector; + MakeKey(Key, SubKey); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + + DesData(dmEncry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Move(TempOut[0], Vector[0], SizeOf(TCnDESIv)); + Dec(Count, SizeOf(TCnDESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorDESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + + DesData(dmEncry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + end; +end; + +procedure DESDecryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +var + TempIn, TempOut: TCnDESBuffer; + Vector1, Vector2: TCnDESIv; + Done: Cardinal; + SubKey: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + if (Count mod SizeOf(TCnDESBuffer)) > 0 then + raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); + + Vector1 := InitVector; + MakeKey(Key, SubKey); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorDESReadError); + + Move(TempIn[0], Vector2[0], SizeOf(TCnDESIv)); + DesData(dmDecry, SubKey, TempIn, TempOut); + + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorDESWriteError); + + Vector1 := Vector2; + Dec(Count, SizeOf(TCnDESBuffer)); + end; +end; + +procedure Make3DESKeys(Keys: AnsiString; var K1, K2, K3: TCnDESKey); overload; +var + I: Integer; +begin + if Length(Keys) < CN_TRIPLE_DES_KEYSIZE then + while Length(Keys) < CN_TRIPLE_DES_KEYSIZE do + Keys := Keys + Chr(0); + + for I := 0 to CN_DES_KEYSIZE - 1 do + begin + K1[I] := Ord(Keys[I + 1]); + K2[I] := Ord(Keys[I + 1 + CN_DES_KEYSIZE]); + K3[I] := Ord(Keys[I + 1 + CN_DES_KEYSIZE * 2]); + end; +end; + +procedure Make3DESKeys(Keys: TCn3DESKey; var K1, K2, K3: TCnDESKey); overload; +var + I: Integer; +begin + for I := 0 to CN_DES_KEYSIZE - 1 do + begin + K1[I] := Keys[I]; + K2[I] := Keys[I + CN_DES_KEYSIZE]; + K3[I] := Keys[I + CN_DES_KEYSIZE * 2]; + end; +end; + +procedure Make3DESKeys(Keys: TBytes; var K1, K2, K3: TCnDESKey); overload; +var + I, Len: Integer; +begin + Len := Length(Keys); + if Len < CN_TRIPLE_DES_KEYSIZE then + begin + SetLength(Keys, CN_TRIPLE_DES_KEYSIZE); + for I := Len to CN_TRIPLE_DES_KEYSIZE - 1 do + Keys[I] := 0; + end; + + for I := 0 to CN_DES_KEYSIZE - 1 do + begin + K1[I] := Ord(Keys[I]); + K2[I] := Ord(Keys[I + CN_DES_KEYSIZE]); + K3[I] := Ord(Keys[I + CN_DES_KEYSIZE * 2]); + end; +end; + +function TripleDESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; +begin + Result := (((InputByteLength - 1) div CN_TRIPLE_DES_BLOCKSIZE) + 1) * CN_TRIPLE_DES_BLOCKSIZE; +end; + +procedure TripleDESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Str: AnsiString; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + Str := Input; + MakeInputAlign(Str); + + if Str = '' then // մֱӷؿ + begin + if Output <> nil then + Output[0] := #0; + Exit; + end; + + for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + + DesData(dmEncry, SubKey1, StrByte, OutByte); + DesData(dmDecry, SubKey2, OutByte, StrByte); + DesData(dmEncry, SubKey3, StrByte, OutByte); + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +procedure TripleDESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + + DesData(dmDecry, SubKey3, StrByte, OutByte); + DesData(dmEncry, SubKey2, OutByte, StrByte); + DesData(dmDecry, SubKey1, StrByte, OutByte); + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; + + // ĩβ 0 ⲿжɾ +end; + +procedure TripleDESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Vector: TCnDESIv; + Str: AnsiString; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + Str := Input; + MakeInputAlign(Str); + + if Str = '' then // մֱӷؿ + begin + if Output <> nil then + Output[0] := #0; + Exit; + end; + + Move(Iv^, Vector[0], SizeOf(TCnDESIv)); + + for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + + // CBC ݿֵȸ Iv + PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; + + // ټ + DesData(dmEncry, SubKey1, StrByte, OutByte); + DesData(dmDecry, SubKey2, OutByte, StrByte); + DesData(dmEncry, SubKey3, StrByte, OutByte); + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ܽµ Iv + Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +procedure TripleDESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Vector, TV: TCnDESIv; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + Move(Iv^, Vector[0], SizeOf(TCnDESIv)); + + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ + + // Ƚ + DesData(dmDecry, SubKey3, StrByte, OutByte); + DesData(dmEncry, SubKey2, OutByte, StrByte); + DesData(dmDecry, SubKey1, StrByte, OutByte); + + // CBC ݿֵܺٸ Iv + PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ĸµ Iv + Move(TV[0], Vector[0], SizeOf(TCnDESIv)); + end; + + // ĩβ 0 ⲿжɾ +end; + +function TripleDESEncryptEcbStrToHex(const Str, Key: AnsiString): AnsiString; +var + TempResult, Temp: AnsiString; + I: Integer; +begin + SetResultLengthUsingInput(Str, TempResult); + TripleDESEncryptEcbStr(Key, Str, @TempResult[1]); + + Result := ''; + for I := 0 to Length(TempResult) - 1 do + begin + Temp := AnsiString(Format('%x', [Ord(TempResult[I + 1])])); + if Length(Temp) = 1 then + Temp := '0' + Temp; + Result := Result + Temp; + end; +end; + +function TripleDESDecryptEcbStrFromHex(const HexStr, Key: AnsiString): AnsiString; +var + Str: AnsiString; +begin + Str := HexToAnsiStr(HexStr); + SetResultLengthUsingInput(Str, Result); + TripleDESDecryptEcbStr(Key, Str, @(Result[1])); +end; + +function TripleDESEncryptCbcStrToHex(const Str, Key, Iv: AnsiString): AnsiString; +var + TempResult, Temp: AnsiString; + I: Integer; +begin + SetResultLengthUsingInput(Str, TempResult); + TripleDESEncryptCbcStr(Key, PAnsiChar(Iv), Str, @TempResult[1]); + + Result := ''; + for I := 0 to Length(TempResult) - 1 do + begin + Temp := AnsiString(Format('%x', [Ord(TempResult[I + 1])])); + if Length(Temp) = 1 then + Temp := '0' + Temp; + Result := Result + Temp; + end; +end; + +function TripleDESDecryptCbcStrFromHex(const HexStr, Key, Iv: AnsiString): AnsiString; +var + Str: AnsiString; +begin + Str := HexToAnsiStr(HexStr); + SetResultLengthUsingInput(Str, Result); + TripleDESDecryptCbcStr(Key, PAnsiChar(Iv), Str, @(Result[1])); +end; + +function TripleDESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + MakeInputBytesAlign(Input); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + + DesData(dmEncry, SubKey1, StrByte, OutByte); + DesData(dmDecry, SubKey2, OutByte, StrByte); + DesData(dmEncry, SubKey3, StrByte, OutByte); + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +function TripleDESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + + DesData(dmDecry, SubKey3, StrByte, OutByte); + DesData(dmEncry, SubKey2, OutByte, StrByte); + DesData(dmDecry, SubKey1, StrByte, OutByte); + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +function TripleDESEncryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Vector: TCnDESIv; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + MakeInputBytesAlign(Input); + FillChar(Vector[0], SizeOf(TCnDESIv), 0); + MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + + // CBC ݿֵȸ Iv + PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; + + // ټ + DesData(dmEncry, SubKey1, StrByte, OutByte); + DesData(dmDecry, SubKey2, OutByte, StrByte); + DesData(dmEncry, SubKey3, StrByte, OutByte); + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ܽµ Iv + Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +function TripleDESDecryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Vector, TV: TCnDESIv; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + FillChar(Vector[0], SizeOf(TCnDESIv), 0); + MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ + + // Ƚ + DesData(dmDecry, SubKey3, StrByte, OutByte); + DesData(dmEncry, SubKey2, OutByte, StrByte); + DesData(dmDecry, SubKey1, StrByte, OutByte); + + // CBC ݿֵܺٸ Iv + PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ĸµ Iv + Move(TV[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +procedure TripleDESEncryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; Dest: TStream); overload; +var + K1, K2, K3: TCnDESKey; + TempIn, TempOut: TCnDESBuffer; + Done: Cardinal; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + DesData(dmEncry, SubKey1, TempIn, TempOut); + DesData(dmDecry, SubKey2, TempOut, TempIn); + DesData(dmEncry, SubKey3, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Dec(Count, SizeOf(TCnDESBuffer)); + end; + + if Count > 0 then // β 0 + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorDESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + + DesData(dmEncry, SubKey1, TempIn, TempOut); + DesData(dmDecry, SubKey2, TempOut, TempIn); + DesData(dmEncry, SubKey3, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + end; +end; + +procedure TripleDESDecryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; Dest: TStream); overload; +var + K1, K2, K3: TCnDESKey; + TempIn, TempOut: TCnDESBuffer; + Done: Cardinal; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + if (Count mod SizeOf(TCnDESBuffer)) > 0 then + raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + DesData(dmDecry, SubKey3, TempIn, TempOut); + DesData(dmEncry, SubKey2, TempOut, TempIn); + DesData(dmDecry, SubKey1, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Dec(Count, SizeOf(TCnDESBuffer)); + end; +end; + +procedure TripleDESEncryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +var + K1, K2, K3: TCnDESKey; + TempIn, TempOut: TCnDESBuffer; + Vector: TCnDESIv; + Done: Cardinal; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + + Vector := InitVector; + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + + DesData(dmEncry, SubKey1, TempIn, TempOut); + DesData(dmDecry, SubKey2, TempOut, TempIn); + DesData(dmEncry, SubKey3, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Move(TempOut[0], Vector[0], SizeOf(TCnDESIv)); + Dec(Count, SizeOf(TCnDESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorDESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + + DesData(dmEncry, SubKey1, TempIn, TempOut); + DesData(dmDecry, SubKey2, TempOut, TempIn); + DesData(dmEncry, SubKey3, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + end; +end; + +procedure TripleDESDecryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +var + K1, K2, K3: TCnDESKey; + TempIn, TempOut: TCnDESBuffer; + Vector1, Vector2: TCnDESIv; + Done: Cardinal; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + if (Count mod SizeOf(TCnDESBuffer)) > 0 then + raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); + + Vector1 := InitVector; + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorDESReadError); + + Move(TempIn[0], Vector2[0], SizeOf(TCnDESIv)); + + DesData(dmDecry, SubKey3, TempIn, TempOut); + DesData(dmEncry, SubKey2, TempOut, TempIn); + DesData(dmDecry, SubKey1, TempIn, TempOut); + + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorDESWriteError); + + Vector1 := Vector2; + Dec(Count, SizeOf(TCnDESBuffer)); + end; +end; + +end. diff --git a/CnPack/Crypto/CnFloat.pas b/CnPack/Crypto/CnFloat.pas index a727541..eb5de61 100644 --- a/CnPack/Crypto/CnFloat.pas +++ b/CnPack/Crypto/CnFloat.pas @@ -1,1354 +1,1354 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -unit CnFloat; -{* |
-================================================================================
-* ƣ
-* Ԫƣת
-* ԪߣǬԪ(wqyfavor@163.com)
-*     עõԪʵ Extended תΪˡʮַĺ
-*           㷨Ƕȡ Extended ڴеĶݽת Extended ͵˵
-*           ԲοϡDouble  Single Ϊϵͳֵ֧ͨĸͣ Delphi е
-*           Extended ڴ洢ʽвͬ߾β񻯣 Double  Single β
-*           Ĭϵ 1βΪ 1.001 Double  Single д洢Ϊ 001ȥ
-*           Сǰ 1 Extended 洢Ϊ 1001
-*           NaN Ϊ "not a number"Ǹο Math.pas Ԫеij NaN
-*           Infinity Ϊ󣬶ο Math.pas Ԫеij Infinity  NegInfinity.
-*           һ DecimalExp  AlwaysUseExponent 
-*           ʮƸתʱָʽѧ㷨Щ
-*           Ҳָֻʽ 1E-1000ָʱ 0.0000000...0001תָ
-*           ҲӦӦƱʾʱʮƱʾָ֣ƴ
-*           1.001E101ֵΪ 100100ָʮƱһЩ 1.001D5ʾС
-*            5 λDecimalExp ָǷʮƱֵָġע⣬ʮ
-*           ʾָ޹涨﷨ʹ "D" ʾ"E" ΪӦƱʾ⣬
-*           ʮƱȽ⣬"D"  "E" ΪʮַʮƱʱʹ "^"
-*           ַ 3.BD^D(12)A.BD^E(ABCE)粻ϲָʽ޸ġ
-*           AlwaysUseExponent ָǷһÿѧ 100.111 λȽ٣
-*           ԶжϲҪʹÿѧ AlwaysUseExponent ΪʱһΪָ
-*           ʽ 1.00111E2
-*           const
-*             MaxBinDigits = 120;
-*             MaxHexDigits = 30;
-*             MaxOctDigits = 40;
-*           ָλʱһʹÿѧ
-*
-*           ⣬Extended ֻ Win32  10 ֽڣMacOS/Linux x64 ¾ 16 ֽڣWin64  ARM ƽ̨ 8 ֽ
-*           ңMacOS64 µ 16 ֽչȲ  IEEE 754-2008 й涨 Quadruple ʽǰ 10 ֽڽضϣ
-*           ڲṹͬ Win32 µչ 10 ֽ
-*
-* ƽ̨WinXP + Delphi 2009
-* ݲԣDelphi 2007 Extended ֻ֧Сģʽ
-*   õԪеַϱػʽ
-* ޸ļ¼2023.01.13
-*               ݴ Win64  Extended  8 ֽ Double  10 ֽչȵ
-*               ݴ MacOS64/Linux64 µ 16 ֽ Extendedֻضϴǰ 10 ֽڣ
-*           2022.02.17
-*                FPC ı֧֣
-*           2021.09.05
-*               תΪ UInt64֧ UInt64  Int64 棩ĺ
-*           2020.11.11
-*                UInt64֧ UInt64  Int64 棩תΪĺ
-*           2020.06.24
-*               ⿪ƴյĺ
-*           2009.1.12
-*               Ԫ
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - SysUtils, Classes, SysConst, {$IFDEF MSWINDOWS} Windows, {$ENDIF} CnNative; - -{ - IEEE 754 涨ָʽЧڵλ 0 - - Single 1 λ S8 λָ E23 λЧ M 4 ֽ 32 λ - ˫ Double 1 λ S11 λָ E52 λЧ M 8 ֽ 64 λ - չ˫ Extended 1 λ S15 λָ E64 λЧ M 10 ֽ 80 λ - - IEEE 754-2008 - ı Quadruple 1 λ S15 λָ E112 λЧ M 16 ֽ 128 λ - ˱ Octuple 1 λ S19 λָ E236 λЧ M 32 ֽ 256 λ - - Уλ S0 ʾ1 ʾE Ҫȥ 127/1023/16383/16383 ָ - M: 淶/˫ȵĶ M ĸλӸ 1. Чչӣ 1. - ֵЧ 1.xxxx ʽ 2 E ηעⲻ 10 E η - - ʽ ֽ 1 ֽ 2 ֽ 3 ֽ 4 ... ֽ nÿֽڵұߵλ 0 - 4 SXXXXXXX XMMMMMMM MMMMMMMM MMMMMMMM - ˫ 8 SXXXXXXX XXXXMMMM MMMMMMMM MMMMMMMM ... MMMMMMMM - չ˫ 10 SXXXXXXX XXXXXXXX 1MMMMMMM MMMMMMMM ... MMMMMMMM // עЧְ 1඼ʡ 1 - ı 16 SXXXXXXX XXXXXXXX MMMMMMMM MMMMMMMM ... MMMMMMMM - ˱ 32 SXXXXXXX XXXXXXXX XXXXMMMM MMMMMMMM ... MMMMMMMM - - ע⣺Little Endian ϣֽ 1 n 򡣱Ԫѵ - - 0ȫ 0 - -0ȫ 0 λΪ 1 - ָȫ 1Чȫ 0 0 1 -} - -type - TCnQuadruple = packed record - {* Delphi ıͣýṹָ} - Lo: TUInt64; - Hi0: Cardinal; - case Boolean of - True: (Hi1: Cardinal); - False: (W0, W1: Word); // С˻ϣźָ W1 - end; - PCnQuadruple = ^TCnQuadruple; - - TCnOctuple = packed record - {* Delphi ް˱ͣ Int64 ָ} - F0: Int64; - F1: Int64; - F2: Int64; - F3: Int64; - end; - PCnOctuple = ^TCnOctuple; - - ECnFloatSizeError = class(Exception); - -const - CN_EXTENDED_SIZE_8 = 8; // Win64 µ Extended ֻ 8 ֽ - CN_EXTENDED_SIZE_10 = 10; // Win32 µ Extended DZ׼ 10 ֽ - CN_EXTENDED_SIZE_16 = 16; // MACOS64/Linux64 16 ֽ - - CN_SIGN_SINGLE_MASK = $80000000; - CN_SIGN_DOUBLE_MASK = $8000000000000000; - CN_SIGN_EXTENDED_MASK = $8000; // ȥ 8 ֽЧ - CN_SIGN_QUADRUPLE_MASK = $80000000; // ֻǰֽڣȥ˺ - - CN_EXPONENT_SINGLE_MASK = $7F800000; // Ҫ 23 λ - CN_EXPONENT_DOUBLE_MASK = $7FF0000000000000; // Ҫ 52 λ - CN_EXPONENT_EXTENDED_MASK = $7FFF; // ȥ 8 ֽЧ - CN_EXPONENT_QUADRUPLE_MASK = $7FFF; // ȥ 14 ֽЧ - - CN_SIGNIFICAND_SINGLE_MASK = $007FFFFF; // 23 λ - CN_SIGNIFICAND_DOUBLE_MASK = $000FFFFFFFFFFFFF; // 52 λ - CN_SIGNIFICAND_EXTENDED_MASK = $FFFFFFFFFFFFFFFF; // 64 λʵȫ 8 ֽ - CN_SIGNIFICAND_QUADRUPLE_MASK = $FFFF; - - CN_SINGLE_SIGNIFICAND_BITLENGTH = 23; - CN_DOUBLE_SIGNIFICAND_BITLENGTH = 52; - CN_EXTENDED_SIGNIFICAND_BITLENGTH = 63; - - CN_EXPONENT_OFFSET_SINGLE = 127; // ʵֵָҪܴ浽ڴָ - CN_EXPONENT_OFFSET_DOUBLE = 1023; - CN_EXPONENT_OFFSET_EXTENDED = 16383; // 10 16 ֽչȸΪ - - CN_SINGLE_MIN_EXPONENT = -127; - CN_SINGLE_MAX_EXPONENT = 127; // Max ָȫ 1 Σ - CN_DOUBLE_MIN_EXPONENT = -1023; - CN_DOUBLE_MAX_EXPONENT = 1023; - CN_EXTENDED_MIN_EXPONENT = -16383; - CN_EXTENDED_MAX_EXPONENT = 16383; - -procedure ExtractFloatSingle(Value: Single; out SignNegative: Boolean; - out Exponent: Integer; out Mantissa: Cardinal); -{* ӵȸнλָЧ֡ - עָΪʵָЧΪ 24 λԭʼΪ 0~22 λ 23 λΪȥ 1 - - - Value: Single - ⿪ĵȸ - out SignNegative: Boolean - λTrue Ϊ - out Exponent: Integer - ָ - out Mantissa: Cardinal - Ч - - ֵޣ -} - -procedure ExtractFloatDouble(Value: Double; out SignNegative: Boolean; - out Exponent: Integer; out Mantissa: TUInt64); -{* ˫ȸнλָЧ֡ - עָΪʵָЧΪ 53 λԭʼΪ 0~51 λ 52 λΪȥ 1 - - - Value: Double - ⿪˫ȸ - out SignNegative: Boolean - λTrue Ϊ - out Exponent: Integer - ָ - out Mantissa: TUInt64 - Ч - - ֵޣ -} - -procedure ExtractFloatExtended(Value: Extended; out SignNegative: Boolean; - out Exponent: Integer; out Mantissa: TUInt64); -{* չȸнλָЧ֣֧ 10 ֽڡ - Լ 16 ֽڽضΪ 10 ֽڵ Extended ʽ - עָΪʵָЧΪȫ 64 λλ 63 λΪԴ 1 - - - Value: Extended - ⿪չȸ - out SignNegative: Boolean - λTrue Ϊ - out Exponent: Integer - ָ - out Mantissa: TUInt64 - Ч - - ֵޣ -} - -procedure ExtractFloatQuadruple(Value: Extended; out SignNegative: Boolean; - out Exponent: Integer; out MantissaLo: TUInt64; out MantissaHi: TUInt64); -{* ʮֽھȸнλָЧֻ֣ Extended Ϊ 16 ֽ - Ҹʽ IEEE 754-2008 ıȸʱЧĿǰ Delphi ָ֧øʽ - עָΪʵָЧ 112 λΪߵ֡ - - - Value: Extended - ⿪ʮֽھȸ - out SignNegative: Boolean - λTrue Ϊ - out Exponent: Integer - ָ - out MantissaLo: TUInt64 - Чֵ 64 λ - out MantissaHi: TUInt64 - Чָ 64 λ - - ֵޣ -} - -procedure CombineFloatSingle(SignNegative: Boolean; Exponent: Integer; - Mantissa: Cardinal; var Value: Single); -{* ѷλָЧƴɵȸ - - - SignNegative: Boolean - λTrue Ϊ - Exponent: Integer - ָ - Mantissa: Cardinal - Ч - var Value: Single - ϵĵȸ - - ֵޣ -} - -procedure CombineFloatDouble(SignNegative: Boolean; Exponent: Integer; - Mantissa: TUInt64; var Value: Double); -{* ѷλָЧƴ˫ȸ - - - SignNegative: Boolean - λTrue Ϊ - Exponent: Integer - ָ - Mantissa: TUInt64 - Ч - var Value: Double - ϵ˫ȸ - - ֵޣ -} - -procedure CombineFloatExtended(SignNegative: Boolean; Exponent: Integer; - Mantissa: TUInt64; var Value: Extended); -{* ѷλָЧƴչȸ֧ 10 ֽڡ - Լ 16 ֽڽضΪ 10 ֽڵ Extended ʽ - - - SignNegative: Boolean - λTrue Ϊ - Exponent: Integer - ָ - Mantissa: TUInt64 - Ч - var Value: Extended - ϵչȸ - - ֵޣ - -} - -procedure CombineFloatQuadruple(SignNegative: Boolean; Exponent: Integer; - MantissaLo: TUInt64; MantissaHi: TUInt64; var Value: Extended); -{* ѷλָЧƴչȸֻ Extended Ϊ 16 ֽ - Ҹʽ IEEE 754-2008 ıȸʱЧĿǰ Delphi ָ֧øʽ - - - SignNegative: Boolean - λTrue Ϊ - Exponent: Integer - ָ - MantissaLo: TUInt64 - Чֵ 64 λ - MantissaHi: TUInt64 - Чָ 64 λ - var Value: Extended - ϵʮֽھȸ - - ֵޣ -} - -function UInt64ToSingle(U: TUInt64): Single; -{* Int64 зģ 64 λ޷͸ֵ Singleʵͬ - - - U: TUInt64 - ֵ 64 λ޷ֵ - - ֵSingle - صĵȸ -} - -function UInt64ToDouble(U: TUInt64): Double; -{* Int64 зģ 64 λ޷͸ֵ Doubleʵͬ - - - U: TUInt64 - ֵ 64 λ޷ֵ - - ֵDouble - ص˫ȸ -} - -function UInt64ToExtended(U: TUInt64): Extended; -{* Int64 зģ 64 λ޷͸ֵ Extendedʵͬ - - - U: TUInt64 - ֵ 64 λ޷ֵ - - ֵExtended - صչȸ -} - -function SingleToUInt64(F: Single): TUInt64; -{* Single ֵ Int64 зģ 64 λ޷ͣʵͬ - - - F: Single - ֵĵȸ - - ֵTUInt64 - ص 64 λ޷ֵ -} - -function DoubleToUInt64(F: Double): TUInt64; -{* Double ֵ Int64 зģ 64 λ޷ͣʵͬ - - - F: Double - ֵ˫ȸ - - ֵTUInt64 - ص 64 λ޷ֵ -} - -function ExtendedToUInt64(F: Extended): TUInt64; -{* Extended ֵ Int64 зģ 64 λ޷ͣʵͬ - - - F: Extended - ֵ˫ȸ - - ֵTUInt64 - ص 64 λ޷ֵ -} - -function SingleIsInfinite(AValue: Single): Boolean; -{* ȸǷ - - - AValue: Single - жϵĵȸ - - ֵBoolean - Ƿ -} - -function DoubleIsInfinite(AValue: Double): Boolean; -{* ˫ȸǷ - - - AValue: Double - жϵ˫ȸ - - ֵBoolean - Ƿ -} - -function ExtendedIsInfinite(AValue: Extended): Boolean; -{* չȸǷ - - - AValue: Extended - жϵչȸ - - ֵBoolean - Ƿ -} - -function SingleIsNan(AValue: Single): Boolean; -{* ȸǷʵ - - - AValue: Single - жϵĵȸ - - ֵBoolean - Ƿʵ -} - -function DoubleIsNan(AValue: Double): Boolean; -{* ˫ȸǷʵ - - - AValue: Double - жϵ˫ȸ - - ֵBoolean - Ƿʵ -} - -function ExtendedIsNan(AValue: Extended): Boolean; -{* չȸǷʵ - - - AValue: Extended - жϵչȸ - - ֵBoolean - Ƿʵ -} - -// FPCWindows 64/Linux 64 ƽ̨Լ Delphi 56 ֧ -{$IFDEF WIN32} -{$IFDEF COMPILER7_UP} - -{ FloatDecimalToBinExtended, FloatDecimalToOctExtendedFloatDecimalToHexExtended - FloatDecimalToBinaryExtended ̣FloatDecimalToBinaryExtended } - -function FloatDecimalToBinExtended(fIn: Extended; DecimalExp: Boolean; - AlwaysUseExponent: Boolean): AnsiString; // Convert to binary - -function FloatDecimalToOctExtended(fIn: Extended; DecimalExp: Boolean; - AlwaysUseExponent: Boolean): AnsiString; // Convert to octal - -function FloatDecimalToHexExtended(fIn: Extended; DecimalExp: Boolean; - AlwaysUseExponent: Boolean): AnsiString; // Convert to hexdecimal - -{$ENDIF} -{$ENDIF} - -implementation - -const - UINT64_EXTENDED_EXP_MAX = $4040; // UINT64 Ӧ Extended ָ - -resourcestring - SCN_ERROR_EXTENDED_SIZE = 'Extended Size Error'; - -type - TExtendedRec10 = packed record - {* 10 ֽڵչȸֻ Win32 Ч} - Mantissa: TUInt64; - ExpSign: Word; - end; - PExtendedRec10 = ^TExtendedRec10; - -{$IFDEF WIN32} -{$IFDEF COMPILER7_UP} - -type - PConvertFloatSystem = ^TConvertFloatSystem; - TConvertFloatSystem = record - Negative: Boolean; - ExpFlag, ExponentI: Integer; - end; - -const - MaxBinDigits = 120; - MaxHexDigits = 30; - MaxOctDigits = 40; - -function FloatDecimalToBinaryExtended(fIn: Extended; DecimalExp, - AlwaysUseExponent: Boolean; var ForHexOct: PConvertFloatSystem): AnsiString; -var - Neg: Boolean; - i, Flag, IntExp: Integer; - Exp: AnsiString; -label UseExponent; -begin -{ -Extended(32.125) in memory: -0 100000000000100 10000000 10000000 00000000 00000000 00000000 00000000 00000000 00000000 - 9 8 7 6 5 4 3 2nd Byte 1stByte 0 -sign exponent digits -0 111111111111111 1000000000000000000000000000000000000000000000000000000000000000 + Inf -1 111111111111111 1000000000000000000000000000000000000000000000000000000000000000 - Inf -1 111111111111111 1100000000000000000000000000000000000000000000000000000000000000 Nan -0 111111111111111 1100000000000000000000000000000000000000000000000000000000000000 -Nan -} - SetLength(Result, 255); - SetLength(Exp, 2 * SizeOf(Extended) + 1); - Neg := False; - asm - push EBX - push ESI - mov EBX, Result // Address of Result - mov EBX, [EBX] - mov EAX, 0 - // Test if fIN equals 0 - lea ESI, fIn[7] // get the first byte of digits - mov AL, [ESI] - test AL, 128 // 10000000B - jz @Zero - mov ECX, 0 - lea ESI, fIn[8] - mov AX, [ESI] // Get first two bytes - test AX, 32768 // 32768D = 1000000000000000B - jz @Positive - mov Neg, 1 - sub AX, 32768 // Sign bit <- 0 - @Positive: - // Test if fIn is NaN or Infinity - cmp AX, 32767 - jnz @NotNAN_INF - mov DL, [ESI - 1] - test DL, 64 // 01000000B - jz @INF - mov Flag, 4 // NaN - jmp @Done - @INF: - mov Flag, 3 // INF - jmp @Done - @NotNAN_INF: - sub AX, 16383 // AX = AX - 011111111111111B - jns @ExpPositive - sub AX, 1 - not AX - mov Flag, 2 // // Exponent sign negative - jmp @JudgeDecimalExp - @ExpPositive: - mov Flag, 1 // Exponent sign positive - @JudgeDecimalExp: - mov IntExp, EAX - cmp DecimalExp, 1 - je @MoveDigits - // Binary string exponent. Convert AX to binary string and store it in Exp - lea EBX, Exp - mov EBX, [EBX] - push ECX - mov [EBX], 69 // 'E' // "D" for decimal exponent - mov ECX, 1 - cmp Flag, 2 - jnz @NoNegativeInExp - mov [EBX + 1], 45 // '-' // Add a "-" to exponent string - mov ECX, 2 - @NoNegativeInExp: - mov ESI, 0 // flag whehter "1" appears - // Move exponent digits to Exp - mov DX, 32768 // 1000000000000000 - @NextExpDigit: - test AX, DX - jz @AppendExp0 - mov [EBX + ECX], 49 // '1' - mov ESI, 1 - jmp @NextExpIncECX - @AppendExp0: - cmp ESI, 0 - jz @NextExpNoIncECX // do not append this "0" - mov [EBX + ECX], 48 // '0' - @NextExpIncECX: - inc ECX - @NextExpNoIncECX: - shr DX, 1 - cmp DX, 0 - jne @NextExpDigit - pop ECX - mov EBX, Result - mov EBX, [EBX] - jmp @MoveDigits - @MoveDigits: - // Move digits to Result - mov ESI, 8 - @NextByte: - dec ESI - mov EAX, EBX - lea EBX, fIn[ESI] - mov DL, [EBX] - mov EBX, EAX - mov AL, 128 // 10000000 - @NextDigit: - test DL, AL - jz @Append0 - mov [EBX + ECX], 49 // '1' - mov i, ECX - jmp @Next - @Append0: - mov [EBX + ECX], 48 // '0' - @Next: - inc ECX - shr AL, 1 - cmp AL, 0 - jne @NextDigit - cmp ESI, 0 // if the last byte - jne @NextByte - jmp @Done - @Zero: - mov Flag, 0 - @Done: - pop ESI - pop EBX - end; - case Flag of - 0: - begin - ForHexOct := nil; - Result := '0'; - Exit; - end; - 1, 2: - begin - // Delete redundant "0" in Result - Delete(Result, i + 2, MaxInt); // i stores the position of the last 1 in Result - if Assigned(ForHexOct) then - begin - // Copy to ForHexOct - with ForHexOct^ do - begin - Negative := Neg; - ExpFlag := Flag; - ExponentI := IntExp; - end; - Exit; - end; - // Add dot and exponent to Result - if (IntExp = 0) then - begin - if (Length(Result) > 1) then - Insert('.', Result, 2); - end - else - begin - { Decide whether use exponent. For example "1000.101" shouldn't be output - as 1.000101E11 when AlwaysUseExponent is False. } - if AlwaysUseExponent then - begin -UseExponent: - if DecimalExp then - if Flag = 1 then - Exp := 'D' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(IntExp)) - else - Exp := 'D-' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(IntExp)); - if Length(Result) >=2 then - Insert('.', Result, 2); - Result := Result + Exp; - end - else - begin - // IntExp may be negative. - if Flag = 1 then - begin - // Calculate all digits required without exponent - if IntExp <= Length(Result) - 2 then - begin - // Do not use exponent - Insert('.', Result, IntExp + 2); - end - else if IntExp = Length(Result) - 1 then - { 1.001, Exp = 3, output 1001 } - else - begin - if IntExp + 1> MaxBinDigits then - goto UseExponent - else - begin - Inc(IntExp); - i := Length(Result); - // Add zeros at tail - SetLength(Result, IntExp); - for i := i + 1 to IntExp do - Result := '0'; - end; - end; - end - else - begin - if IntExp + Length(Result) > MaxBinDigits then - goto UseExponent - else - begin - // Add leading zeros and place "." - SetLength(Exp, 1 + IntExp); - Exp[1] := '0'; - Exp[2] := '.'; - for i := 3 to IntExp + 1 do - Exp := '0'; //} - Result := Exp + Result; - end; - end; - end; - end; - end; - 3: // INF - begin - ForHexOct := nil; - Result := 'INF'; - end; - 4: // NaN - begin - ForHexOct := nil; - Result := 'NaN'; - Exit; - end; - end; - if Neg then - Result := '-' + Result; -end; - -function FloatDecimalToBinExtended(fIn: Extended; DecimalExp, - AlwaysUseExponent: Boolean): AnsiString; -var - PTmp: PConvertFloatSystem; -begin - PTmp := nil; - Result := FloatDecimalToBinaryExtended(fIn, DecimalExp, AlwaysUseExponent, PTmp); -end; - -function FloatDecimalToHexExtended(fIn: Extended; DecimalExp, - AlwaysUseExponent: Boolean): AnsiString; -const - DecToHex: array[0..15] of AnsiChar = - ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); - BinPow: array[0..3] of Integer = (8, 4, 2, 1); - - function IntToHex(Int: Integer): AnsiString; - var - k ,t: Integer; - Buf: array[1..5] of AnsiChar; - begin - k := 1; - while (Int <> 0) do - begin - Buf[k] := DecToHex[Int mod 16]; - Inc(k); - Int := Int div 16; - end; - Dec(k); - SetLength(Result, k); - t := 1; - while (k > 0) do - begin - Result[t] := Buf[k]; - Inc(t); - Dec(k); - end; - end; - - function ToHex(const S: AnsiString; LeftToDot: Boolean): AnsiString; - var - i, l, t, m, k: Integer; - Buf: array[1..20] of AnsiChar; - begin - { LeftToDot = True, S will be patched with zeroes on its left side. - For example, S = '110', after patching, S = '0110'. - LeftToDot = False, S will be patched with zeroes on its right side. - S = '110', after patching, S = '1100'. } - l := Length(S); - if LeftToDot then - t := (4 - (l mod 4)) mod 4 - else - t := 0; - i := 1; - m := 1; - k := 0; - while i <= l do - begin - k := k + BinPow[t] * (Ord(S[i]) - Ord('0')); - Inc(t); - if (t = 4) or (i = l) then - begin - Buf[m] := DecToHex[k]; - Inc(m); - k := 0; - t := 0; - end; - Inc(i); - end; - Dec(m); - SetLength(Result, m); - - while (m > 0) do - begin - Result[m] := Buf[m]; - Dec(m); - end; - end; - -var - PConvertData: PConvertFloatSystem; - ConvertData: TConvertFloatSystem; - tmpS: AnsiString; - k, t, i, m: Integer; -label UseExponent; -begin - PConvertData := @ConvertData; - Result := FloatDecimalToBinaryExtended(fIn, True, True, PConvertData); - // See FloatDecimalToBinaryExtended, PConvertData is set to nil when result is definite. - if PConvertData = nil then - Exit; - with ConvertData do - begin - { 3.BD^D(12) - A.BD^E(ABCE) - AB.FFFF } - k := Length(Result) - 1; - if AlwaysUseExponent then - begin -UseExponent: - { Algorithm: - X.XXXXXXXX^Y Shift Count Exp - 1.00000001^0 = 1.00000001 = 1.01^0 (16) - 1.00000001^1 = 10.0000001 = 2.02^0 (16) - 1.00000001^2 = 100.000001 = 4.04^0 (16) - 1.00000001^3 = 1000.00001 = 8.08^0 (16) - 1.00000001^4 = 1.00000001^100 = 1.01^1 (16) - 1.00000001^5 = 10.0000001^100 = 2.02^1 (16) - Shift Count = Y mod 4 - Exp = Y div 4 - X.XXXXXXXXX^Y Y < 0 Exp - 1.00000001^-1 = 0.100000001 = 1000.00001^-100 = 8.08^-1 - 1.00000001^-2 = 0.0100000001 = 100.000001^-100 = 4.04^-1 - 1.00000001^-3 = 0.00100000001 = 10.0000001^-100 = 2.02^-1 - 1.00000001^-4 = 0.000100000001 = 1.00000001^-100 = 1.01^-1 - 1.00000001^-5 = 0.0000100000001 = 1000.00001^-100 = 8.08^-2 - Shift Count = 4 - (Abs(Y) mod 4) - Exp = -(Abs(Y) div 4 + 1) } - if ExpFlag = 1 then - begin - t := ExponentI div 4; // Exp - i := ExponentI mod 4; // Shift Count - end - else - begin - t := -((ExponentI - 1) div 4 + 1); // Exp - i := (4 - (ExponentI mod 4)) mod 4; // Shift Count - end; - // Get hex digits - if k < i then - begin - // Add extra zeroes - SetLength(Result, i + 1); - for m := k + 2 to i + 1 do - Result[m] := '0'; - Result := ToHex(Result, True); - end - else if k = i then - Result := ToHex(Result, True) - else - begin - tmpS := Copy(Result, 1, i + 1); - Delete(Result, 1, i + 1); - Result := ToHex(tmpS, True) + '.' + ToHex(Result, False); - end; - if t <> 0 then - begin - // Format exponent - if DecimalExp then - Result := Result + '^D(' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(t)) + ')' - else - begin - if ExpFlag = 1 then - Result := Result + '^E(' + IntToHex(t) + ')' - else // t < 0 - Result := Result + '^E(-' + IntToHex(-t) + ')'; - end; - end; - end - else - begin - { Always remember that Result equals "XXXXXXXX" not "X.XXXXXXX". - Judge whether to use exponent: - There are K "X" after '.', K = Length(Result) - 1, no "." in Result originally. - X.XXXXXXX^Y (Binary string, ExponentI = Abs(Y)) - case Y >= 0 (Condition: ExpFlag = 2) - Y <= K: - Y+1 binary digits on left side of '.', K-Y digits on right side - totally requires ((Y+1 - 1) div 4 + 1) + ((K-Y - 1) div 4 + 1) hex digits - Y > K: - Y+1 binary digits on left side, totally ((Y+1 - 1) div 4 + 1) hex digits - case Y<0 (Condition: ExpFlag = 1) 0.XXXX or 0.000XXXX - One digit '0' on left side and K+1+Abs(Y)-1 digits on right side, - totally 1 + ((K+1+Abs(Y)-1-1) div 4 + 1) hex digits. - Compare hdc = hex digit count with MaxHexDigits. If hdc > MaxHexDigits, - goto UseExponent. } - if ExponentI = 0 then - begin - if (Length(Result) > 1) then - Result := '1.' + ToHex(Copy(Result, 2, MaxInt), False); - end - else - begin - if ExpFlag = 1 then - begin - if ExponentI < k then - begin - // No possible that "ExponentI div 4 + (k - ExponentI - 1) div 4 + 2" > MaxHexDigits - tmpS := Copy(Result, 1, ExponentI + 1); - Delete(Result, 1, ExponentI + 1); - Result := ToHex(tmpS, True) + '.' + ToHex(Result, False); - end - else if ExponentI = k then - // 1.01^2 = 101, no ".", no extra "0". - Result := ToHex(Result, True) - else - begin - t := ExponentI div 4 + 1; - if t > MaxHexDigits then - goto UseExponent - else - begin - // Append "0" after Result - Inc(ExponentI); - // Add '0' to Result - SetLength(Result, ExponentI); - for t := k + 2{original Length(Result) + 1} to ExponentI do - Result[t] := '0'; - Result := ToHex(Result, True); - end; - end; - end - else - begin - // ExpFlag = 2, X.XXXXXXX^Y, Y < 0 - t := 2 + (k + ExponentI - 1) div 4; {1 + ((K+1+Abs(Y)-1-1) div 4 + 1)} - if t > MaxHexDigits then - goto UseExponent - else - begin - // Add leading zeroes before Result - SetLength(tmpS, ExponentI - 1); // tmpS stores extra zeroes - for t := 1 to ExponentI - 1 do - tmpS[t] := '0'; - Result := '0.' + ToHex(tmpS + Result, False); - end; - end; - end; - end; - if Negative then - Result := '-' + Result; - end; -end; - -function FloatDecimalToOctExtended(fIn: Extended; DecimalExp, - AlwaysUseExponent: Boolean): AnsiString; -const - DecToOct: array[0..7] of AnsiChar = - ('0', '1', '2', '3', '4', '5', '6', '7'); - BinPow: array[0..2] of Integer = (4, 2, 1); - - function IntToOct(Int: Integer): AnsiString; - var - k ,t: Integer; - Buf: array[1..10] of AnsiChar; - begin - k := 1; - while (Int <> 0) do - begin - Buf[k] := DecToOct[Int mod 8]; - Inc(k); - Int := Int div 8; - end; - Dec(k); - SetLength(Result, k); - t := 1; - while (k > 0) do - begin - Result[t] := Buf[k]; - Inc(t); - Dec(k); - end; - end; - - function ToOct(const S: AnsiString; LeftToDot: Boolean): AnsiString; - var - i, l, t, m, k: Integer; - Buf: array[1..30] of AnsiChar; - begin - { LeftToDot = True, S will be patched with zeroes on its left side. - For example, S = '110', after patching, S = '0110'. - LeftToDot = False, S will be patched with zeroes on its right side. - S = '110', after patching, S = '1100'. } - l := Length(S); - if LeftToDot then - t := (3 - (l mod 3)) mod 3 - else - t := 0; - i := 1; - m := 1; - k := 0; - while i <= l do - begin - k := k + BinPow[t] * (Ord(S[i]) - Ord('0')); - Inc(t); - if (t = 3) or (i = l) then - begin - Buf[m] := DecToOct[k]; - Inc(m); - k := 0; - t := 0; - end; - Inc(i); - end; - Dec(m); - SetLength(Result, m); - - while (m > 0) do - begin - Result[m] := Buf[m]; - Dec(m); - end; - end; - -var - PConvertData: PConvertFloatSystem; - ConvertData: TConvertFloatSystem; - tmpS: AnsiString; - k, t, i, m: Integer; -label UseExponent; -begin - PConvertData := @ConvertData; - Result := FloatDecimalToBinaryExtended(fIn, True, True, PConvertData); - // See FloatDecimalToBinaryExtended, PConvertData is set to nil when result is definite. - if PConvertData = nil then - Exit; - with ConvertData do - begin - { 3.333D12 // 12 is decimal - 2.22E33 // 33 is octal} - k := Length(Result) - 1; - if AlwaysUseExponent then - begin -UseExponent: - if ExpFlag = 1 then - begin - t := ExponentI div 3; // Exp - i := ExponentI mod 3; // Shift Count - end - else - begin - t := -((ExponentI - 1) div 3 + 1); // Exp - i := (3 - (ExponentI mod 3)) mod 3; // Shift Count - end; - // Get hex digits - if k < i then - begin - // Add extra zeroes - SetLength(Result, i + 1); - for m := k + 2 to i + 1 do - Result[m] := '0'; - Result := ToOct(Result, True); - end - else if k = i then - Result := ToOct(Result, True) - else - begin - tmpS := Copy(Result, 1, i + 1); - Delete(Result, 1, i + 1); - Result := ToOct(tmpS, True) + '.' + ToOct(Result, False); - end; - if t <> 0 then - begin - // Format exponent - if DecimalExp then - Result := Result + 'D' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(t)) - else - begin - if ExpFlag = 1 then - Result := Result + 'E' + IntToOct(t) - else // t < 0 - Result := Result + 'E-' + IntToOct(-t); - end; - end; - end - else - begin - if ExponentI = 0 then - begin - if (Length(Result) > 1) then - Result := '1.' + ToOct(Copy(Result, 2, MaxInt), False); - end - else - begin - if ExpFlag = 1 then - begin - if ExponentI < k then - begin - tmpS := Copy(Result, 1, ExponentI + 1); - Delete(Result, 1, ExponentI + 1); - Result := ToOct(tmpS, True) + '.' + ToOct(Result, False); - end - else if ExponentI = k then - // 1.01^2 = 101, no ".", no extra "0". - Result := ToOct(Result, True) - else - begin - t := ExponentI div 3 + 1; - if t > MaxHexDigits then - goto UseExponent - else - begin - // Append "0" after Result - Inc(ExponentI); - // Add '0' to Result - SetLength(Result, ExponentI); - for t := k + 2{original Length(Result) + 1} to ExponentI do - Result[t] := '0'; - Result := ToOct(Result, True); - end; - end; - end - else - begin - // ExpFlag = 2, X.XXXXXXX^Y, Y < 0 - t := 2 + (k + ExponentI - 1) div 3; - if t > MaxHexDigits then - goto UseExponent - else - begin - // Add leading zeroes before Result - SetLength(tmpS, ExponentI - 1); // tmpS stores extra zeroes - for t := 1 to ExponentI - 1 do - tmpS[t] := '0'; - Result := '0.' + ToOct(tmpS + Result, False); - end; - end; - end; - end; - if Negative then - Result := '-' + Result; - end; -end; - -{$ENDIF} -{$ENDIF} - -procedure ExtractFloatSingle(Value: Single; out SignNegative: Boolean; - out Exponent: Integer; out Mantissa: Cardinal); -begin - SignNegative := (PCardinal(@Value)^ and CN_SIGN_SINGLE_MASK) <> 0; - Exponent := ((PCardinal(@Value)^ and CN_EXPONENT_SINGLE_MASK) shr 23) - CN_EXPONENT_OFFSET_SINGLE; - Mantissa := PCardinal(@Value)^ and CN_SIGNIFICAND_SINGLE_MASK; - Mantissa := Mantissa or (1 shl 23); // λټӸ 1 -end; - -procedure ExtractFloatDouble(Value: Double; out SignNegative: Boolean; - out Exponent: Integer; out Mantissa: TUInt64); -begin - SignNegative := (PUInt64(@Value)^ and CN_SIGN_DOUBLE_MASK) <> 0; - Exponent := ((PUInt64(@Value)^ and CN_EXPONENT_DOUBLE_MASK) shr 52) - CN_EXPONENT_OFFSET_DOUBLE; - Mantissa := PUInt64(@Value)^ and CN_SIGNIFICAND_DOUBLE_MASK; - Mantissa := Mantissa or (TUInt64(1) shl 52); // λټӸ 1 -end; - -procedure ExtractFloatExtended(Value: Extended; out SignNegative: Boolean; - out Exponent: Integer; out Mantissa: TUInt64); -begin - if (SizeOf(Extended) = CN_EXTENDED_SIZE_10) or (SizeOf(Extended) = CN_EXTENDED_SIZE_16) then - begin - SignNegative := (PExtendedRec10(@Value)^.ExpSign and CN_SIGN_EXTENDED_MASK) <> 0; - Exponent := (PExtendedRec10(@Value)^.ExpSign and CN_EXPONENT_EXTENDED_MASK) - CN_EXPONENT_OFFSET_EXTENDED; - Mantissa := PExtendedRec10(@Value)^.Mantissa; // 1ü - end - else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then - ExtractFloatDouble(Value, SignNegative, Exponent, Mantissa) - else - raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); -end; - -procedure ExtractFloatQuadruple(Value: Extended; out SignNegative: Boolean; - out Exponent: Integer; out MantissaLo, MantissaHi: TUInt64); -begin - if SizeOf(Extended) <> CN_EXTENDED_SIZE_16 then - raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); - - SignNegative := (PCnQuadruple(@Value)^.W1 and CN_SIGN_QUADRUPLE_MASK) <> 0; - Exponent := (PCnQuadruple(@Value)^.W1 and CN_EXPONENT_QUADRUPLE_MASK) - CN_EXPONENT_OFFSET_EXTENDED; - - // Extract 16 Bytes to Mantissas - MantissaLo := PCnQuadruple(@Value)^.Lo; - MantissaHi := TUInt64(PCnQuadruple(@Value)^.Hi0) or (TUInt64(PCnQuadruple(@Value)^.W0) shl 32) or (TUInt64(1) shl 48); // λټӸ 1 -end; - -procedure CombineFloatSingle(SignNegative: Boolean; Exponent: Integer; - Mantissa: Cardinal; var Value: Single); -begin - Mantissa := Mantissa and not (1 shl 23); // ȥ 23 λϵ 1еĻ - PCardinal(@Value)^ := Mantissa and CN_SIGNIFICAND_SINGLE_MASK; - Inc(Exponent, CN_EXPONENT_OFFSET_SINGLE); - - PCardinal(@Value)^ := PCardinal(@Value)^ or (LongWord(Exponent) shl 23); - if SignNegative then - PCardinal(@Value)^ := PCardinal(@Value)^ or CN_SIGN_SINGLE_MASK - else - PCardinal(@Value)^ := PCardinal(@Value)^ and not CN_SIGN_SINGLE_MASK; -end; - -procedure CombineFloatDouble(SignNegative: Boolean; Exponent: Integer; - Mantissa: TUInt64; var Value: Double); -begin - Mantissa := Mantissa and not (TUInt64(1) shl 52); // ȥ 52 λϵ 1еĻ - PUInt64(@Value)^ := Mantissa and CN_SIGNIFICAND_DOUBLE_MASK; - Inc(Exponent, CN_EXPONENT_OFFSET_DOUBLE); - - PUInt64(@Value)^ := PUInt64(@Value)^ or (TUInt64(Exponent) shl 52); - if SignNegative then - PUInt64(@Value)^ := PUInt64(@Value)^ or CN_SIGN_DOUBLE_MASK - else - PUInt64(@Value)^ := PUInt64(@Value)^ and not CN_SIGN_DOUBLE_MASK; -end; - -{$HINTS OFF} - -procedure CombineFloatExtended(SignNegative: Boolean; Exponent: Integer; - Mantissa: TUInt64; var Value: Extended); -var - D: Double; -begin - if (SizeOf(Extended) = CN_EXTENDED_SIZE_10) or (SizeOf(Extended) = CN_EXTENDED_SIZE_16) then - begin - PExtendedRec10(@Value)^.Mantissa := Mantissa; - Inc(Exponent, CN_EXPONENT_OFFSET_EXTENDED); - - PExtendedRec10(@Value)^.ExpSign := Exponent and CN_EXPONENT_EXTENDED_MASK; - if SignNegative then - PExtendedRec10(@Value)^.ExpSign := PExtendedRec10(@Value)^.ExpSign or CN_SIGN_EXTENDED_MASK - else - PExtendedRec10(@Value)^.ExpSign := PExtendedRec10(@Value)^.ExpSign and not CN_SIGN_EXTENDED_MASK; - end - else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then - begin - CombineFloatDouble(SignNegative, Exponent, Mantissa, D); - Value := D; - end - else - raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); -end; - -{$HINTS ON} - -procedure CombineFloatQuadruple(SignNegative: Boolean; Exponent: Integer; - MantissaLo, MantissaHi: TUInt64; var Value: Extended); -begin - if SizeOf(Extended) <> CN_EXTENDED_SIZE_16 then - raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); - - MantissaHi := MantissaHi and not (TUInt64(1) shl 48); // ȥ 112 λϵ 1еĻ - PCnQuadruple(@Value)^.Lo := MantissaLo; - PCnQuadruple(@Value)^.Hi0 := Cardinal(MantissaHi and $FFFFFFFF); - PCnQuadruple(@Value)^.Hi1 := (MantissaHi shr 32) and CN_SIGNIFICAND_QUADRUPLE_MASK; - - Inc(Exponent, CN_EXPONENT_OFFSET_EXTENDED); - PCnQuadruple(@Value)^.W1 := Exponent and CN_EXPONENT_QUADRUPLE_MASK; - if SignNegative then - PCnQuadruple(@Value)^.Hi1 := PCnQuadruple(@Value)^.Hi1 or CN_SIGN_QUADRUPLE_MASK - else - PCnQuadruple(@Value)^.Hi1 := PCnQuadruple(@Value)^.Hi1 and not CN_SIGN_QUADRUPLE_MASK; -end; - -// UInt64 Ϊ -function UFloat(U: TUInt64): Extended; -{$IFNDEF SUPPORT_UINT64} -var - L, H: Cardinal; -{$ENDIF} -begin -{$IFDEF SUPPORT_UINT64} - Result := U; -{$ELSE} - if U < 0 then // Int64 С 0 ʱ UInt64 Ǵ Int64 ֵ - begin - H := Int64Rec(U).Hi; - L := Int64Rec(U).Lo; - Result := Int64(H) * Int64(CN_MAX_UINT16 + 1); // - Result := Result * (CN_MAX_UINT16 + 1); - Result := Result + L; - end - else - Result := U; -{$ENDIF} -end; - -function UInt64ToSingle(U: TUInt64): Single; -begin - Result := UFloat(U); -end; - -function UInt64ToDouble(U: TUInt64): Double; -begin - Result := UFloat(U); -end; - -function UInt64ToExtended(U: TUInt64): Extended; -begin - Result := UFloat(U); -end; - -// ͨ Trunc ֻܷ Int64 UInt64 -function UTrunc(F: Extended): TUInt64; -var - T: Integer; - SignNeg: Boolean; - Exponent: Integer; - Mantissa: TUInt64; -begin - // õʵָ 1 ͷЧ֣С 1 - ExtractFloatExtended(F, SignNeg, Exponent, Mantissa); - if SignNeg then - raise ERangeError.Create(SRangeError); // ֧ - - // Mantissa 64 λЧ֣С 63 λָС 0 ˵СҪƣôֵ 0 - if Exponent < 0 then - Result := 0 - else - begin - // С Exponent λСߵ - T := 63 - Exponent; // С 0 63 λ 63 λұߣСƺ T λұ - if T < 0 then - raise ERangeError.Create(SRangeError); // Exponent ̫ - - Result := Mantissa shr T; - end; -end; - -function SingleToUInt64(F: Single): TUInt64; -begin - Result := UTrunc(F); -end; - -function DoubleToUInt64(F: Double): TUInt64; -begin - Result := UTrunc(F); -end; - -function ExtendedToUInt64(F: Extended): TUInt64; -begin - Result := UTrunc(F); -end; - -function SingleIsInfinite(AValue: Single): Boolean; -begin - Result := ((PCardinal(@AValue)^ and $7F800000) = $7F800000) and - ((PCardinal(@AValue)^ and $007FFFFF) = $00000000); -end; - -function DoubleIsInfinite(AValue: Double): Boolean; -begin - Result := ((PUInt64(@AValue)^ and $7FF0000000000000) = $7FF0000000000000) and - ((PUInt64(@AValue)^ and $000FFFFFFFFFFFFF) = $0000000000000000); -end; - -function ExtendedIsInfinite(AValue: Extended): Boolean; -begin - if SizeOf(Extended) = CN_EXTENDED_SIZE_10 then - Result := ((PExtendedRec10(@AValue)^.ExpSign and $7FFF) = $7FFF) and - ((PExtendedRec10(@AValue)^.Mantissa) = 0) - else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then - Result := DoubleIsInfinite(AValue) - else - raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); -end; - -function SingleIsNan(AValue: Single): Boolean; -begin - Result := ((PCardinal(@AValue)^ and $7F800000) = $7F800000) and - ((PCardinal(@AValue)^ and $007FFFFF) <> $00000000); -end; - -function DoubleIsNan(AValue: Double): Boolean; -begin - Result := ((PUInt64(@AValue)^ and $7FF0000000000000) = $7FF0000000000000) and - ((PUInt64(@AValue)^ and $000FFFFFFFFFFFFF) <> $0000000000000000); -end; - -function ExtendedIsNan(AValue: Extended): Boolean; -begin - if SizeOf(Extended) = CN_EXTENDED_SIZE_10 then - Result := ((PExtendedRec10(@AValue)^.ExpSign and $7FFF) = $7FFF) and - ((PExtendedRec10(@AValue)^.Mantissa and $7FFFFFFFFFFFFFFF) <> 0) - else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then - Result := DoubleIsNan(AValue) - else - raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); -end; - -end. +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnFloat; +{* |
+================================================================================
+* ƣ
+* Ԫƣת
+* ԪߣǬԪ(wqyfavor@163.com)
+*     עõԪʵ Extended תΪˡʮַĺ
+*           㷨Ƕȡ Extended ڴеĶݽת Extended ͵˵
+*           ԲοϡDouble  Single Ϊϵͳֵ֧ͨĸͣ Delphi е
+*           Extended ڴ洢ʽвͬ߾β񻯣 Double  Single β
+*           Ĭϵ 1βΪ 1.001 Double  Single д洢Ϊ 001ȥ
+*           Сǰ 1 Extended 洢Ϊ 1001
+*           NaN Ϊ "not a number"Ǹο Math.pas Ԫеij NaN
+*           Infinity Ϊ󣬶ο Math.pas Ԫеij Infinity  NegInfinity.
+*           һ DecimalExp  AlwaysUseExponent 
+*           ʮƸתʱָʽѧ㷨Щ
+*           Ҳָֻʽ 1E-1000ָʱ 0.0000000...0001תָ
+*           ҲӦӦƱʾʱʮƱʾָ֣ƴ
+*           1.001E101ֵΪ 100100ָʮƱһЩ 1.001D5ʾС
+*            5 λDecimalExp ָǷʮƱֵָġע⣬ʮ
+*           ʾָ޹涨﷨ʹ "D" ʾ"E" ΪӦƱʾ⣬
+*           ʮƱȽ⣬"D"  "E" ΪʮַʮƱʱʹ "^"
+*           ַ 3.BD^D(12)A.BD^E(ABCE)粻ϲָʽ޸ġ
+*           AlwaysUseExponent ָǷһÿѧ 100.111 λȽ٣
+*           ԶжϲҪʹÿѧ AlwaysUseExponent ΪʱһΪָ
+*           ʽ 1.00111E2
+*           const
+*             MaxBinDigits = 120;
+*             MaxHexDigits = 30;
+*             MaxOctDigits = 40;
+*           ָλʱһʹÿѧ
+*
+*           ⣬Extended ֻ Win32  10 ֽڣMacOS/Linux x64 ¾ 16 ֽڣWin64  ARM ƽ̨ 8 ֽ
+*           ңMacOS64 µ 16 ֽչȲ  IEEE 754-2008 й涨 Quadruple ʽǰ 10 ֽڽضϣ
+*           ڲṹͬ Win32 µչ 10 ֽ
+*
+* ƽ̨WinXP + Delphi 2009
+* ݲԣDelphi 2007 Extended ֻ֧Сģʽ
+*   õԪеַϱػʽ
+* ޸ļ¼2023.01.13
+*               ݴ Win64  Extended  8 ֽ Double  10 ֽչȵ
+*               ݴ MacOS64/Linux64 µ 16 ֽ Extendedֻضϴǰ 10 ֽڣ
+*           2022.02.17
+*                FPC ı֧֣
+*           2021.09.05
+*               תΪ UInt64֧ UInt64  Int64 棩ĺ
+*           2020.11.11
+*                UInt64֧ UInt64  Int64 棩תΪĺ
+*           2020.06.24
+*               ⿪ƴյĺ
+*           2009.1.12
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, SysConst, {$IFDEF MSWINDOWS} Windows, {$ENDIF} CnNative; + +{ + IEEE 754 涨ָʽЧڵλ 0 + + Single 1 λ S8 λָ E23 λЧ M 4 ֽ 32 λ + ˫ Double 1 λ S11 λָ E52 λЧ M 8 ֽ 64 λ + չ˫ Extended 1 λ S15 λָ E64 λЧ M 10 ֽ 80 λ + + IEEE 754-2008 + ı Quadruple 1 λ S15 λָ E112 λЧ M 16 ֽ 128 λ + ˱ Octuple 1 λ S19 λָ E236 λЧ M 32 ֽ 256 λ + + Уλ S0 ʾ1 ʾE Ҫȥ 127/1023/16383/16383 ָ + M: 淶/˫ȵĶ M ĸλӸ 1. Чչӣ 1. + ֵЧ 1.xxxx ʽ 2 E ηעⲻ 10 E η + + ʽ ֽ 1 ֽ 2 ֽ 3 ֽ 4 ... ֽ nÿֽڵұߵλ 0 + 4 SXXXXXXX XMMMMMMM MMMMMMMM MMMMMMMM + ˫ 8 SXXXXXXX XXXXMMMM MMMMMMMM MMMMMMMM ... MMMMMMMM + չ˫ 10 SXXXXXXX XXXXXXXX 1MMMMMMM MMMMMMMM ... MMMMMMMM // עЧְ 1඼ʡ 1 + ı 16 SXXXXXXX XXXXXXXX MMMMMMMM MMMMMMMM ... MMMMMMMM + ˱ 32 SXXXXXXX XXXXXXXX XXXXMMMM MMMMMMMM ... MMMMMMMM + + ע⣺Little Endian ϣֽ 1 n 򡣱Ԫѵ + + 0ȫ 0 + -0ȫ 0 λΪ 1 + ָȫ 1Чȫ 0 0 1 +} + +type + TCnQuadruple = packed record + {* Delphi ıͣýṹָ} + Lo: TUInt64; + Hi0: Cardinal; + case Boolean of + True: (Hi1: Cardinal); + False: (W0, W1: Word); // С˻ϣźָ W1 + end; + PCnQuadruple = ^TCnQuadruple; + + TCnOctuple = packed record + {* Delphi ް˱ͣ Int64 ָ} + F0: Int64; + F1: Int64; + F2: Int64; + F3: Int64; + end; + PCnOctuple = ^TCnOctuple; + + ECnFloatSizeError = class(Exception); + +const + CN_EXTENDED_SIZE_8 = 8; // Win64 µ Extended ֻ 8 ֽ + CN_EXTENDED_SIZE_10 = 10; // Win32 µ Extended DZ׼ 10 ֽ + CN_EXTENDED_SIZE_16 = 16; // MACOS64/Linux64 16 ֽ + + CN_SIGN_SINGLE_MASK = $80000000; + CN_SIGN_DOUBLE_MASK = $8000000000000000; + CN_SIGN_EXTENDED_MASK = $8000; // ȥ 8 ֽЧ + CN_SIGN_QUADRUPLE_MASK = $80000000; // ֻǰֽڣȥ˺ + + CN_EXPONENT_SINGLE_MASK = $7F800000; // Ҫ 23 λ + CN_EXPONENT_DOUBLE_MASK = $7FF0000000000000; // Ҫ 52 λ + CN_EXPONENT_EXTENDED_MASK = $7FFF; // ȥ 8 ֽЧ + CN_EXPONENT_QUADRUPLE_MASK = $7FFF; // ȥ 14 ֽЧ + + CN_SIGNIFICAND_SINGLE_MASK = $007FFFFF; // 23 λ + CN_SIGNIFICAND_DOUBLE_MASK = $000FFFFFFFFFFFFF; // 52 λ + CN_SIGNIFICAND_EXTENDED_MASK = $FFFFFFFFFFFFFFFF; // 64 λʵȫ 8 ֽ + CN_SIGNIFICAND_QUADRUPLE_MASK = $FFFF; + + CN_SINGLE_SIGNIFICAND_BITLENGTH = 23; + CN_DOUBLE_SIGNIFICAND_BITLENGTH = 52; + CN_EXTENDED_SIGNIFICAND_BITLENGTH = 63; + + CN_EXPONENT_OFFSET_SINGLE = 127; // ʵֵָҪܴ浽ڴָ + CN_EXPONENT_OFFSET_DOUBLE = 1023; + CN_EXPONENT_OFFSET_EXTENDED = 16383; // 10 16 ֽչȸΪ + + CN_SINGLE_MIN_EXPONENT = -127; + CN_SINGLE_MAX_EXPONENT = 127; // Max ָȫ 1 Σ + CN_DOUBLE_MIN_EXPONENT = -1023; + CN_DOUBLE_MAX_EXPONENT = 1023; + CN_EXTENDED_MIN_EXPONENT = -16383; + CN_EXTENDED_MAX_EXPONENT = 16383; + +procedure ExtractFloatSingle(Value: Single; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: Cardinal); +{* ӵȸнλָЧ֡ + עָΪʵָЧΪ 24 λԭʼΪ 0~22 λ 23 λΪȥ 1 + + + Value: Single - ⿪ĵȸ + out SignNegative: Boolean - λTrue Ϊ + out Exponent: Integer - ָ + out Mantissa: Cardinal - Ч + + ֵޣ +} + +procedure ExtractFloatDouble(Value: Double; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: TUInt64); +{* ˫ȸнλָЧ֡ + עָΪʵָЧΪ 53 λԭʼΪ 0~51 λ 52 λΪȥ 1 + + + Value: Double - ⿪˫ȸ + out SignNegative: Boolean - λTrue Ϊ + out Exponent: Integer - ָ + out Mantissa: TUInt64 - Ч + + ֵޣ +} + +procedure ExtractFloatExtended(Value: Extended; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: TUInt64); +{* չȸнλָЧ֣֧ 10 ֽڡ + Լ 16 ֽڽضΪ 10 ֽڵ Extended ʽ + עָΪʵָЧΪȫ 64 λλ 63 λΪԴ 1 + + + Value: Extended - ⿪չȸ + out SignNegative: Boolean - λTrue Ϊ + out Exponent: Integer - ָ + out Mantissa: TUInt64 - Ч + + ֵޣ +} + +procedure ExtractFloatQuadruple(Value: Extended; out SignNegative: Boolean; + out Exponent: Integer; out MantissaLo: TUInt64; out MantissaHi: TUInt64); +{* ʮֽھȸнλָЧֻ֣ Extended Ϊ 16 ֽ + Ҹʽ IEEE 754-2008 ıȸʱЧĿǰ Delphi ָ֧øʽ + עָΪʵָЧ 112 λΪߵ֡ + + + Value: Extended - ⿪ʮֽھȸ + out SignNegative: Boolean - λTrue Ϊ + out Exponent: Integer - ָ + out MantissaLo: TUInt64 - Чֵ 64 λ + out MantissaHi: TUInt64 - Чָ 64 λ + + ֵޣ +} + +procedure CombineFloatSingle(SignNegative: Boolean; Exponent: Integer; + Mantissa: Cardinal; var Value: Single); +{* ѷλָЧƴɵȸ + + + SignNegative: Boolean - λTrue Ϊ + Exponent: Integer - ָ + Mantissa: Cardinal - Ч + var Value: Single - ϵĵȸ + + ֵޣ +} + +procedure CombineFloatDouble(SignNegative: Boolean; Exponent: Integer; + Mantissa: TUInt64; var Value: Double); +{* ѷλָЧƴ˫ȸ + + + SignNegative: Boolean - λTrue Ϊ + Exponent: Integer - ָ + Mantissa: TUInt64 - Ч + var Value: Double - ϵ˫ȸ + + ֵޣ +} + +procedure CombineFloatExtended(SignNegative: Boolean; Exponent: Integer; + Mantissa: TUInt64; var Value: Extended); +{* ѷλָЧƴչȸ֧ 10 ֽڡ + Լ 16 ֽڽضΪ 10 ֽڵ Extended ʽ + + + SignNegative: Boolean - λTrue Ϊ + Exponent: Integer - ָ + Mantissa: TUInt64 - Ч + var Value: Extended - ϵչȸ + + ֵޣ + +} + +procedure CombineFloatQuadruple(SignNegative: Boolean; Exponent: Integer; + MantissaLo: TUInt64; MantissaHi: TUInt64; var Value: Extended); +{* ѷλָЧƴչȸֻ Extended Ϊ 16 ֽ + Ҹʽ IEEE 754-2008 ıȸʱЧĿǰ Delphi ָ֧øʽ + + + SignNegative: Boolean - λTrue Ϊ + Exponent: Integer - ָ + MantissaLo: TUInt64 - Чֵ 64 λ + MantissaHi: TUInt64 - Чָ 64 λ + var Value: Extended - ϵʮֽھȸ + + ֵޣ +} + +function UInt64ToSingle(U: TUInt64): Single; +{* Int64 зģ 64 λ޷͸ֵ Singleʵͬ + + + U: TUInt64 - ֵ 64 λ޷ֵ + + ֵSingle - صĵȸ +} + +function UInt64ToDouble(U: TUInt64): Double; +{* Int64 зģ 64 λ޷͸ֵ Doubleʵͬ + + + U: TUInt64 - ֵ 64 λ޷ֵ + + ֵDouble - ص˫ȸ +} + +function UInt64ToExtended(U: TUInt64): Extended; +{* Int64 зģ 64 λ޷͸ֵ Extendedʵͬ + + + U: TUInt64 - ֵ 64 λ޷ֵ + + ֵExtended - صչȸ +} + +function SingleToUInt64(F: Single): TUInt64; +{* Single ֵ Int64 зģ 64 λ޷ͣʵͬ + + + F: Single - ֵĵȸ + + ֵTUInt64 - ص 64 λ޷ֵ +} + +function DoubleToUInt64(F: Double): TUInt64; +{* Double ֵ Int64 зģ 64 λ޷ͣʵͬ + + + F: Double - ֵ˫ȸ + + ֵTUInt64 - ص 64 λ޷ֵ +} + +function ExtendedToUInt64(F: Extended): TUInt64; +{* Extended ֵ Int64 зģ 64 λ޷ͣʵͬ + + + F: Extended - ֵ˫ȸ + + ֵTUInt64 - ص 64 λ޷ֵ +} + +function SingleIsInfinite(AValue: Single): Boolean; +{* ȸǷ + + + AValue: Single - жϵĵȸ + + ֵBoolean - Ƿ +} + +function DoubleIsInfinite(AValue: Double): Boolean; +{* ˫ȸǷ + + + AValue: Double - жϵ˫ȸ + + ֵBoolean - Ƿ +} + +function ExtendedIsInfinite(AValue: Extended): Boolean; +{* չȸǷ + + + AValue: Extended - жϵչȸ + + ֵBoolean - Ƿ +} + +function SingleIsNan(AValue: Single): Boolean; +{* ȸǷʵ + + + AValue: Single - жϵĵȸ + + ֵBoolean - Ƿʵ +} + +function DoubleIsNan(AValue: Double): Boolean; +{* ˫ȸǷʵ + + + AValue: Double - жϵ˫ȸ + + ֵBoolean - Ƿʵ +} + +function ExtendedIsNan(AValue: Extended): Boolean; +{* չȸǷʵ + + + AValue: Extended - жϵչȸ + + ֵBoolean - Ƿʵ +} + +// FPCWindows 64/Linux 64 ƽ̨Լ Delphi 56 ֧ +{$IFDEF WIN32} +{$IFDEF COMPILER7_UP} + +{ FloatDecimalToBinExtended, FloatDecimalToOctExtendedFloatDecimalToHexExtended + FloatDecimalToBinaryExtended ̣FloatDecimalToBinaryExtended } + +function FloatDecimalToBinExtended(fIn: Extended; DecimalExp: Boolean; + AlwaysUseExponent: Boolean): AnsiString; // Convert to binary + +function FloatDecimalToOctExtended(fIn: Extended; DecimalExp: Boolean; + AlwaysUseExponent: Boolean): AnsiString; // Convert to octal + +function FloatDecimalToHexExtended(fIn: Extended; DecimalExp: Boolean; + AlwaysUseExponent: Boolean): AnsiString; // Convert to hexdecimal + +{$ENDIF} +{$ENDIF} + +implementation + +const + UINT64_EXTENDED_EXP_MAX = $4040; // UINT64 Ӧ Extended ָ + +resourcestring + SCN_ERROR_EXTENDED_SIZE = 'Extended Size Error'; + +type + TExtendedRec10 = packed record + {* 10 ֽڵչȸֻ Win32 Ч} + Mantissa: TUInt64; + ExpSign: Word; + end; + PExtendedRec10 = ^TExtendedRec10; + +{$IFDEF WIN32} +{$IFDEF COMPILER7_UP} + +type + PConvertFloatSystem = ^TConvertFloatSystem; + TConvertFloatSystem = record + Negative: Boolean; + ExpFlag, ExponentI: Integer; + end; + +const + MaxBinDigits = 120; + MaxHexDigits = 30; + MaxOctDigits = 40; + +function FloatDecimalToBinaryExtended(fIn: Extended; DecimalExp, + AlwaysUseExponent: Boolean; var ForHexOct: PConvertFloatSystem): AnsiString; +var + Neg: Boolean; + i, Flag, IntExp: Integer; + Exp: AnsiString; +label UseExponent; +begin +{ +Extended(32.125) in memory: +0 100000000000100 10000000 10000000 00000000 00000000 00000000 00000000 00000000 00000000 + 9 8 7 6 5 4 3 2nd Byte 1stByte 0 +sign exponent digits +0 111111111111111 1000000000000000000000000000000000000000000000000000000000000000 + Inf +1 111111111111111 1000000000000000000000000000000000000000000000000000000000000000 - Inf +1 111111111111111 1100000000000000000000000000000000000000000000000000000000000000 Nan +0 111111111111111 1100000000000000000000000000000000000000000000000000000000000000 -Nan +} + SetLength(Result, 255); + SetLength(Exp, 2 * SizeOf(Extended) + 1); + Neg := False; + asm + push EBX + push ESI + mov EBX, Result // Address of Result + mov EBX, [EBX] + mov EAX, 0 + // Test if fIN equals 0 + lea ESI, fIn[7] // get the first byte of digits + mov AL, [ESI] + test AL, 128 // 10000000B + jz @Zero + mov ECX, 0 + lea ESI, fIn[8] + mov AX, [ESI] // Get first two bytes + test AX, 32768 // 32768D = 1000000000000000B + jz @Positive + mov Neg, 1 + sub AX, 32768 // Sign bit <- 0 + @Positive: + // Test if fIn is NaN or Infinity + cmp AX, 32767 + jnz @NotNAN_INF + mov DL, [ESI - 1] + test DL, 64 // 01000000B + jz @INF + mov Flag, 4 // NaN + jmp @Done + @INF: + mov Flag, 3 // INF + jmp @Done + @NotNAN_INF: + sub AX, 16383 // AX = AX - 011111111111111B + jns @ExpPositive + sub AX, 1 + not AX + mov Flag, 2 // // Exponent sign negative + jmp @JudgeDecimalExp + @ExpPositive: + mov Flag, 1 // Exponent sign positive + @JudgeDecimalExp: + mov IntExp, EAX + cmp DecimalExp, 1 + je @MoveDigits + // Binary string exponent. Convert AX to binary string and store it in Exp + lea EBX, Exp + mov EBX, [EBX] + push ECX + mov [EBX], 69 // 'E' // "D" for decimal exponent + mov ECX, 1 + cmp Flag, 2 + jnz @NoNegativeInExp + mov [EBX + 1], 45 // '-' // Add a "-" to exponent string + mov ECX, 2 + @NoNegativeInExp: + mov ESI, 0 // flag whehter "1" appears + // Move exponent digits to Exp + mov DX, 32768 // 1000000000000000 + @NextExpDigit: + test AX, DX + jz @AppendExp0 + mov [EBX + ECX], 49 // '1' + mov ESI, 1 + jmp @NextExpIncECX + @AppendExp0: + cmp ESI, 0 + jz @NextExpNoIncECX // do not append this "0" + mov [EBX + ECX], 48 // '0' + @NextExpIncECX: + inc ECX + @NextExpNoIncECX: + shr DX, 1 + cmp DX, 0 + jne @NextExpDigit + pop ECX + mov EBX, Result + mov EBX, [EBX] + jmp @MoveDigits + @MoveDigits: + // Move digits to Result + mov ESI, 8 + @NextByte: + dec ESI + mov EAX, EBX + lea EBX, fIn[ESI] + mov DL, [EBX] + mov EBX, EAX + mov AL, 128 // 10000000 + @NextDigit: + test DL, AL + jz @Append0 + mov [EBX + ECX], 49 // '1' + mov i, ECX + jmp @Next + @Append0: + mov [EBX + ECX], 48 // '0' + @Next: + inc ECX + shr AL, 1 + cmp AL, 0 + jne @NextDigit + cmp ESI, 0 // if the last byte + jne @NextByte + jmp @Done + @Zero: + mov Flag, 0 + @Done: + pop ESI + pop EBX + end; + case Flag of + 0: + begin + ForHexOct := nil; + Result := '0'; + Exit; + end; + 1, 2: + begin + // Delete redundant "0" in Result + Delete(Result, i + 2, MaxInt); // i stores the position of the last 1 in Result + if Assigned(ForHexOct) then + begin + // Copy to ForHexOct + with ForHexOct^ do + begin + Negative := Neg; + ExpFlag := Flag; + ExponentI := IntExp; + end; + Exit; + end; + // Add dot and exponent to Result + if (IntExp = 0) then + begin + if (Length(Result) > 1) then + Insert('.', Result, 2); + end + else + begin + { Decide whether use exponent. For example "1000.101" shouldn't be output + as 1.000101E11 when AlwaysUseExponent is False. } + if AlwaysUseExponent then + begin +UseExponent: + if DecimalExp then + if Flag = 1 then + Exp := 'D' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(IntExp)) + else + Exp := 'D-' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(IntExp)); + if Length(Result) >=2 then + Insert('.', Result, 2); + Result := Result + Exp; + end + else + begin + // IntExp may be negative. + if Flag = 1 then + begin + // Calculate all digits required without exponent + if IntExp <= Length(Result) - 2 then + begin + // Do not use exponent + Insert('.', Result, IntExp + 2); + end + else if IntExp = Length(Result) - 1 then + { 1.001, Exp = 3, output 1001 } + else + begin + if IntExp + 1> MaxBinDigits then + goto UseExponent + else + begin + Inc(IntExp); + i := Length(Result); + // Add zeros at tail + SetLength(Result, IntExp); + for i := i + 1 to IntExp do + Result := '0'; + end; + end; + end + else + begin + if IntExp + Length(Result) > MaxBinDigits then + goto UseExponent + else + begin + // Add leading zeros and place "." + SetLength(Exp, 1 + IntExp); + Exp[1] := '0'; + Exp[2] := '.'; + for i := 3 to IntExp + 1 do + Exp := '0'; //} + Result := Exp + Result; + end; + end; + end; + end; + end; + 3: // INF + begin + ForHexOct := nil; + Result := 'INF'; + end; + 4: // NaN + begin + ForHexOct := nil; + Result := 'NaN'; + Exit; + end; + end; + if Neg then + Result := '-' + Result; +end; + +function FloatDecimalToBinExtended(fIn: Extended; DecimalExp, + AlwaysUseExponent: Boolean): AnsiString; +var + PTmp: PConvertFloatSystem; +begin + PTmp := nil; + Result := FloatDecimalToBinaryExtended(fIn, DecimalExp, AlwaysUseExponent, PTmp); +end; + +function FloatDecimalToHexExtended(fIn: Extended; DecimalExp, + AlwaysUseExponent: Boolean): AnsiString; +const + DecToHex: array[0..15] of AnsiChar = + ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); + BinPow: array[0..3] of Integer = (8, 4, 2, 1); + + function IntToHex(Int: Integer): AnsiString; + var + k ,t: Integer; + Buf: array[1..5] of AnsiChar; + begin + k := 1; + while (Int <> 0) do + begin + Buf[k] := DecToHex[Int mod 16]; + Inc(k); + Int := Int div 16; + end; + Dec(k); + SetLength(Result, k); + t := 1; + while (k > 0) do + begin + Result[t] := Buf[k]; + Inc(t); + Dec(k); + end; + end; + + function ToHex(const S: AnsiString; LeftToDot: Boolean): AnsiString; + var + i, l, t, m, k: Integer; + Buf: array[1..20] of AnsiChar; + begin + { LeftToDot = True, S will be patched with zeroes on its left side. + For example, S = '110', after patching, S = '0110'. + LeftToDot = False, S will be patched with zeroes on its right side. + S = '110', after patching, S = '1100'. } + l := Length(S); + if LeftToDot then + t := (4 - (l mod 4)) mod 4 + else + t := 0; + i := 1; + m := 1; + k := 0; + while i <= l do + begin + k := k + BinPow[t] * (Ord(S[i]) - Ord('0')); + Inc(t); + if (t = 4) or (i = l) then + begin + Buf[m] := DecToHex[k]; + Inc(m); + k := 0; + t := 0; + end; + Inc(i); + end; + Dec(m); + SetLength(Result, m); + + while (m > 0) do + begin + Result[m] := Buf[m]; + Dec(m); + end; + end; + +var + PConvertData: PConvertFloatSystem; + ConvertData: TConvertFloatSystem; + tmpS: AnsiString; + k, t, i, m: Integer; +label UseExponent; +begin + PConvertData := @ConvertData; + Result := FloatDecimalToBinaryExtended(fIn, True, True, PConvertData); + // See FloatDecimalToBinaryExtended, PConvertData is set to nil when result is definite. + if PConvertData = nil then + Exit; + with ConvertData do + begin + { 3.BD^D(12) + A.BD^E(ABCE) + AB.FFFF } + k := Length(Result) - 1; + if AlwaysUseExponent then + begin +UseExponent: + { Algorithm: + X.XXXXXXXX^Y Shift Count Exp + 1.00000001^0 = 1.00000001 = 1.01^0 (16) + 1.00000001^1 = 10.0000001 = 2.02^0 (16) + 1.00000001^2 = 100.000001 = 4.04^0 (16) + 1.00000001^3 = 1000.00001 = 8.08^0 (16) + 1.00000001^4 = 1.00000001^100 = 1.01^1 (16) + 1.00000001^5 = 10.0000001^100 = 2.02^1 (16) + Shift Count = Y mod 4 + Exp = Y div 4 + X.XXXXXXXXX^Y Y < 0 Exp + 1.00000001^-1 = 0.100000001 = 1000.00001^-100 = 8.08^-1 + 1.00000001^-2 = 0.0100000001 = 100.000001^-100 = 4.04^-1 + 1.00000001^-3 = 0.00100000001 = 10.0000001^-100 = 2.02^-1 + 1.00000001^-4 = 0.000100000001 = 1.00000001^-100 = 1.01^-1 + 1.00000001^-5 = 0.0000100000001 = 1000.00001^-100 = 8.08^-2 + Shift Count = 4 - (Abs(Y) mod 4) + Exp = -(Abs(Y) div 4 + 1) } + if ExpFlag = 1 then + begin + t := ExponentI div 4; // Exp + i := ExponentI mod 4; // Shift Count + end + else + begin + t := -((ExponentI - 1) div 4 + 1); // Exp + i := (4 - (ExponentI mod 4)) mod 4; // Shift Count + end; + // Get hex digits + if k < i then + begin + // Add extra zeroes + SetLength(Result, i + 1); + for m := k + 2 to i + 1 do + Result[m] := '0'; + Result := ToHex(Result, True); + end + else if k = i then + Result := ToHex(Result, True) + else + begin + tmpS := Copy(Result, 1, i + 1); + Delete(Result, 1, i + 1); + Result := ToHex(tmpS, True) + '.' + ToHex(Result, False); + end; + if t <> 0 then + begin + // Format exponent + if DecimalExp then + Result := Result + '^D(' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(t)) + ')' + else + begin + if ExpFlag = 1 then + Result := Result + '^E(' + IntToHex(t) + ')' + else // t < 0 + Result := Result + '^E(-' + IntToHex(-t) + ')'; + end; + end; + end + else + begin + { Always remember that Result equals "XXXXXXXX" not "X.XXXXXXX". + Judge whether to use exponent: + There are K "X" after '.', K = Length(Result) - 1, no "." in Result originally. + X.XXXXXXX^Y (Binary string, ExponentI = Abs(Y)) + case Y >= 0 (Condition: ExpFlag = 2) + Y <= K: + Y+1 binary digits on left side of '.', K-Y digits on right side + totally requires ((Y+1 - 1) div 4 + 1) + ((K-Y - 1) div 4 + 1) hex digits + Y > K: + Y+1 binary digits on left side, totally ((Y+1 - 1) div 4 + 1) hex digits + case Y<0 (Condition: ExpFlag = 1) 0.XXXX or 0.000XXXX + One digit '0' on left side and K+1+Abs(Y)-1 digits on right side, + totally 1 + ((K+1+Abs(Y)-1-1) div 4 + 1) hex digits. + Compare hdc = hex digit count with MaxHexDigits. If hdc > MaxHexDigits, + goto UseExponent. } + if ExponentI = 0 then + begin + if (Length(Result) > 1) then + Result := '1.' + ToHex(Copy(Result, 2, MaxInt), False); + end + else + begin + if ExpFlag = 1 then + begin + if ExponentI < k then + begin + // No possible that "ExponentI div 4 + (k - ExponentI - 1) div 4 + 2" > MaxHexDigits + tmpS := Copy(Result, 1, ExponentI + 1); + Delete(Result, 1, ExponentI + 1); + Result := ToHex(tmpS, True) + '.' + ToHex(Result, False); + end + else if ExponentI = k then + // 1.01^2 = 101, no ".", no extra "0". + Result := ToHex(Result, True) + else + begin + t := ExponentI div 4 + 1; + if t > MaxHexDigits then + goto UseExponent + else + begin + // Append "0" after Result + Inc(ExponentI); + // Add '0' to Result + SetLength(Result, ExponentI); + for t := k + 2{original Length(Result) + 1} to ExponentI do + Result[t] := '0'; + Result := ToHex(Result, True); + end; + end; + end + else + begin + // ExpFlag = 2, X.XXXXXXX^Y, Y < 0 + t := 2 + (k + ExponentI - 1) div 4; {1 + ((K+1+Abs(Y)-1-1) div 4 + 1)} + if t > MaxHexDigits then + goto UseExponent + else + begin + // Add leading zeroes before Result + SetLength(tmpS, ExponentI - 1); // tmpS stores extra zeroes + for t := 1 to ExponentI - 1 do + tmpS[t] := '0'; + Result := '0.' + ToHex(tmpS + Result, False); + end; + end; + end; + end; + if Negative then + Result := '-' + Result; + end; +end; + +function FloatDecimalToOctExtended(fIn: Extended; DecimalExp, + AlwaysUseExponent: Boolean): AnsiString; +const + DecToOct: array[0..7] of AnsiChar = + ('0', '1', '2', '3', '4', '5', '6', '7'); + BinPow: array[0..2] of Integer = (4, 2, 1); + + function IntToOct(Int: Integer): AnsiString; + var + k ,t: Integer; + Buf: array[1..10] of AnsiChar; + begin + k := 1; + while (Int <> 0) do + begin + Buf[k] := DecToOct[Int mod 8]; + Inc(k); + Int := Int div 8; + end; + Dec(k); + SetLength(Result, k); + t := 1; + while (k > 0) do + begin + Result[t] := Buf[k]; + Inc(t); + Dec(k); + end; + end; + + function ToOct(const S: AnsiString; LeftToDot: Boolean): AnsiString; + var + i, l, t, m, k: Integer; + Buf: array[1..30] of AnsiChar; + begin + { LeftToDot = True, S will be patched with zeroes on its left side. + For example, S = '110', after patching, S = '0110'. + LeftToDot = False, S will be patched with zeroes on its right side. + S = '110', after patching, S = '1100'. } + l := Length(S); + if LeftToDot then + t := (3 - (l mod 3)) mod 3 + else + t := 0; + i := 1; + m := 1; + k := 0; + while i <= l do + begin + k := k + BinPow[t] * (Ord(S[i]) - Ord('0')); + Inc(t); + if (t = 3) or (i = l) then + begin + Buf[m] := DecToOct[k]; + Inc(m); + k := 0; + t := 0; + end; + Inc(i); + end; + Dec(m); + SetLength(Result, m); + + while (m > 0) do + begin + Result[m] := Buf[m]; + Dec(m); + end; + end; + +var + PConvertData: PConvertFloatSystem; + ConvertData: TConvertFloatSystem; + tmpS: AnsiString; + k, t, i, m: Integer; +label UseExponent; +begin + PConvertData := @ConvertData; + Result := FloatDecimalToBinaryExtended(fIn, True, True, PConvertData); + // See FloatDecimalToBinaryExtended, PConvertData is set to nil when result is definite. + if PConvertData = nil then + Exit; + with ConvertData do + begin + { 3.333D12 // 12 is decimal + 2.22E33 // 33 is octal} + k := Length(Result) - 1; + if AlwaysUseExponent then + begin +UseExponent: + if ExpFlag = 1 then + begin + t := ExponentI div 3; // Exp + i := ExponentI mod 3; // Shift Count + end + else + begin + t := -((ExponentI - 1) div 3 + 1); // Exp + i := (3 - (ExponentI mod 3)) mod 3; // Shift Count + end; + // Get hex digits + if k < i then + begin + // Add extra zeroes + SetLength(Result, i + 1); + for m := k + 2 to i + 1 do + Result[m] := '0'; + Result := ToOct(Result, True); + end + else if k = i then + Result := ToOct(Result, True) + else + begin + tmpS := Copy(Result, 1, i + 1); + Delete(Result, 1, i + 1); + Result := ToOct(tmpS, True) + '.' + ToOct(Result, False); + end; + if t <> 0 then + begin + // Format exponent + if DecimalExp then + Result := Result + 'D' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(t)) + else + begin + if ExpFlag = 1 then + Result := Result + 'E' + IntToOct(t) + else // t < 0 + Result := Result + 'E-' + IntToOct(-t); + end; + end; + end + else + begin + if ExponentI = 0 then + begin + if (Length(Result) > 1) then + Result := '1.' + ToOct(Copy(Result, 2, MaxInt), False); + end + else + begin + if ExpFlag = 1 then + begin + if ExponentI < k then + begin + tmpS := Copy(Result, 1, ExponentI + 1); + Delete(Result, 1, ExponentI + 1); + Result := ToOct(tmpS, True) + '.' + ToOct(Result, False); + end + else if ExponentI = k then + // 1.01^2 = 101, no ".", no extra "0". + Result := ToOct(Result, True) + else + begin + t := ExponentI div 3 + 1; + if t > MaxHexDigits then + goto UseExponent + else + begin + // Append "0" after Result + Inc(ExponentI); + // Add '0' to Result + SetLength(Result, ExponentI); + for t := k + 2{original Length(Result) + 1} to ExponentI do + Result[t] := '0'; + Result := ToOct(Result, True); + end; + end; + end + else + begin + // ExpFlag = 2, X.XXXXXXX^Y, Y < 0 + t := 2 + (k + ExponentI - 1) div 3; + if t > MaxHexDigits then + goto UseExponent + else + begin + // Add leading zeroes before Result + SetLength(tmpS, ExponentI - 1); // tmpS stores extra zeroes + for t := 1 to ExponentI - 1 do + tmpS[t] := '0'; + Result := '0.' + ToOct(tmpS + Result, False); + end; + end; + end; + end; + if Negative then + Result := '-' + Result; + end; +end; + +{$ENDIF} +{$ENDIF} + +procedure ExtractFloatSingle(Value: Single; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: Cardinal); +begin + SignNegative := (PCardinal(@Value)^ and CN_SIGN_SINGLE_MASK) <> 0; + Exponent := ((PCardinal(@Value)^ and CN_EXPONENT_SINGLE_MASK) shr 23) - CN_EXPONENT_OFFSET_SINGLE; + Mantissa := PCardinal(@Value)^ and CN_SIGNIFICAND_SINGLE_MASK; + Mantissa := Mantissa or (1 shl 23); // λټӸ 1 +end; + +procedure ExtractFloatDouble(Value: Double; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: TUInt64); +begin + SignNegative := (PUInt64(@Value)^ and CN_SIGN_DOUBLE_MASK) <> 0; + Exponent := ((PUInt64(@Value)^ and CN_EXPONENT_DOUBLE_MASK) shr 52) - CN_EXPONENT_OFFSET_DOUBLE; + Mantissa := PUInt64(@Value)^ and CN_SIGNIFICAND_DOUBLE_MASK; + Mantissa := Mantissa or (TUInt64(1) shl 52); // λټӸ 1 +end; + +procedure ExtractFloatExtended(Value: Extended; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: TUInt64); +begin + if (SizeOf(Extended) = CN_EXTENDED_SIZE_10) or (SizeOf(Extended) = CN_EXTENDED_SIZE_16) then + begin + SignNegative := (PExtendedRec10(@Value)^.ExpSign and CN_SIGN_EXTENDED_MASK) <> 0; + Exponent := (PExtendedRec10(@Value)^.ExpSign and CN_EXPONENT_EXTENDED_MASK) - CN_EXPONENT_OFFSET_EXTENDED; + Mantissa := PExtendedRec10(@Value)^.Mantissa; // 1ü + end + else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then + ExtractFloatDouble(Value, SignNegative, Exponent, Mantissa) + else + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); +end; + +procedure ExtractFloatQuadruple(Value: Extended; out SignNegative: Boolean; + out Exponent: Integer; out MantissaLo, MantissaHi: TUInt64); +begin + if SizeOf(Extended) <> CN_EXTENDED_SIZE_16 then + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); + + SignNegative := (PCnQuadruple(@Value)^.W1 and CN_SIGN_QUADRUPLE_MASK) <> 0; + Exponent := (PCnQuadruple(@Value)^.W1 and CN_EXPONENT_QUADRUPLE_MASK) - CN_EXPONENT_OFFSET_EXTENDED; + + // Extract 16 Bytes to Mantissas + MantissaLo := PCnQuadruple(@Value)^.Lo; + MantissaHi := TUInt64(PCnQuadruple(@Value)^.Hi0) or (TUInt64(PCnQuadruple(@Value)^.W0) shl 32) or (TUInt64(1) shl 48); // λټӸ 1 +end; + +procedure CombineFloatSingle(SignNegative: Boolean; Exponent: Integer; + Mantissa: Cardinal; var Value: Single); +begin + Mantissa := Mantissa and not (1 shl 23); // ȥ 23 λϵ 1еĻ + PCardinal(@Value)^ := Mantissa and CN_SIGNIFICAND_SINGLE_MASK; + Inc(Exponent, CN_EXPONENT_OFFSET_SINGLE); + + PCardinal(@Value)^ := PCardinal(@Value)^ or (LongWord(Exponent) shl 23); + if SignNegative then + PCardinal(@Value)^ := PCardinal(@Value)^ or CN_SIGN_SINGLE_MASK + else + PCardinal(@Value)^ := PCardinal(@Value)^ and not CN_SIGN_SINGLE_MASK; +end; + +procedure CombineFloatDouble(SignNegative: Boolean; Exponent: Integer; + Mantissa: TUInt64; var Value: Double); +begin + Mantissa := Mantissa and not (TUInt64(1) shl 52); // ȥ 52 λϵ 1еĻ + PUInt64(@Value)^ := Mantissa and CN_SIGNIFICAND_DOUBLE_MASK; + Inc(Exponent, CN_EXPONENT_OFFSET_DOUBLE); + + PUInt64(@Value)^ := PUInt64(@Value)^ or (TUInt64(Exponent) shl 52); + if SignNegative then + PUInt64(@Value)^ := PUInt64(@Value)^ or CN_SIGN_DOUBLE_MASK + else + PUInt64(@Value)^ := PUInt64(@Value)^ and not CN_SIGN_DOUBLE_MASK; +end; + +{$HINTS OFF} + +procedure CombineFloatExtended(SignNegative: Boolean; Exponent: Integer; + Mantissa: TUInt64; var Value: Extended); +var + D: Double; +begin + if (SizeOf(Extended) = CN_EXTENDED_SIZE_10) or (SizeOf(Extended) = CN_EXTENDED_SIZE_16) then + begin + PExtendedRec10(@Value)^.Mantissa := Mantissa; + Inc(Exponent, CN_EXPONENT_OFFSET_EXTENDED); + + PExtendedRec10(@Value)^.ExpSign := Exponent and CN_EXPONENT_EXTENDED_MASK; + if SignNegative then + PExtendedRec10(@Value)^.ExpSign := PExtendedRec10(@Value)^.ExpSign or CN_SIGN_EXTENDED_MASK + else + PExtendedRec10(@Value)^.ExpSign := PExtendedRec10(@Value)^.ExpSign and not CN_SIGN_EXTENDED_MASK; + end + else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then + begin + CombineFloatDouble(SignNegative, Exponent, Mantissa, D); + Value := D; + end + else + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); +end; + +{$HINTS ON} + +procedure CombineFloatQuadruple(SignNegative: Boolean; Exponent: Integer; + MantissaLo, MantissaHi: TUInt64; var Value: Extended); +begin + if SizeOf(Extended) <> CN_EXTENDED_SIZE_16 then + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); + + MantissaHi := MantissaHi and not (TUInt64(1) shl 48); // ȥ 112 λϵ 1еĻ + PCnQuadruple(@Value)^.Lo := MantissaLo; + PCnQuadruple(@Value)^.Hi0 := Cardinal(MantissaHi and $FFFFFFFF); + PCnQuadruple(@Value)^.Hi1 := (MantissaHi shr 32) and CN_SIGNIFICAND_QUADRUPLE_MASK; + + Inc(Exponent, CN_EXPONENT_OFFSET_EXTENDED); + PCnQuadruple(@Value)^.W1 := Exponent and CN_EXPONENT_QUADRUPLE_MASK; + if SignNegative then + PCnQuadruple(@Value)^.Hi1 := PCnQuadruple(@Value)^.Hi1 or CN_SIGN_QUADRUPLE_MASK + else + PCnQuadruple(@Value)^.Hi1 := PCnQuadruple(@Value)^.Hi1 and not CN_SIGN_QUADRUPLE_MASK; +end; + +// UInt64 Ϊ +function UFloat(U: TUInt64): Extended; +{$IFNDEF SUPPORT_UINT64} +var + L, H: Cardinal; +{$ENDIF} +begin +{$IFDEF SUPPORT_UINT64} + Result := U; +{$ELSE} + if U < 0 then // Int64 С 0 ʱ UInt64 Ǵ Int64 ֵ + begin + H := Int64Rec(U).Hi; + L := Int64Rec(U).Lo; + Result := Int64(H) * Int64(CN_MAX_UINT16 + 1); // + Result := Result * (CN_MAX_UINT16 + 1); + Result := Result + L; + end + else + Result := U; +{$ENDIF} +end; + +function UInt64ToSingle(U: TUInt64): Single; +begin + Result := UFloat(U); +end; + +function UInt64ToDouble(U: TUInt64): Double; +begin + Result := UFloat(U); +end; + +function UInt64ToExtended(U: TUInt64): Extended; +begin + Result := UFloat(U); +end; + +// ͨ Trunc ֻܷ Int64 UInt64 +function UTrunc(F: Extended): TUInt64; +var + T: Integer; + SignNeg: Boolean; + Exponent: Integer; + Mantissa: TUInt64; +begin + // õʵָ 1 ͷЧ֣С 1 + ExtractFloatExtended(F, SignNeg, Exponent, Mantissa); + if SignNeg then + raise ERangeError.Create(SRangeError); // ֧ + + // Mantissa 64 λЧ֣С 63 λָС 0 ˵СҪƣôֵ 0 + if Exponent < 0 then + Result := 0 + else + begin + // С Exponent λСߵ + T := 63 - Exponent; // С 0 63 λ 63 λұߣСƺ T λұ + if T < 0 then + raise ERangeError.Create(SRangeError); // Exponent ̫ + + Result := Mantissa shr T; + end; +end; + +function SingleToUInt64(F: Single): TUInt64; +begin + Result := UTrunc(F); +end; + +function DoubleToUInt64(F: Double): TUInt64; +begin + Result := UTrunc(F); +end; + +function ExtendedToUInt64(F: Extended): TUInt64; +begin + Result := UTrunc(F); +end; + +function SingleIsInfinite(AValue: Single): Boolean; +begin + Result := ((PCardinal(@AValue)^ and $7F800000) = $7F800000) and + ((PCardinal(@AValue)^ and $007FFFFF) = $00000000); +end; + +function DoubleIsInfinite(AValue: Double): Boolean; +begin + Result := ((PUInt64(@AValue)^ and $7FF0000000000000) = $7FF0000000000000) and + ((PUInt64(@AValue)^ and $000FFFFFFFFFFFFF) = $0000000000000000); +end; + +function ExtendedIsInfinite(AValue: Extended): Boolean; +begin + if SizeOf(Extended) = CN_EXTENDED_SIZE_10 then + Result := ((PExtendedRec10(@AValue)^.ExpSign and $7FFF) = $7FFF) and + ((PExtendedRec10(@AValue)^.Mantissa) = 0) + else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then + Result := DoubleIsInfinite(AValue) + else + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); +end; + +function SingleIsNan(AValue: Single): Boolean; +begin + Result := ((PCardinal(@AValue)^ and $7F800000) = $7F800000) and + ((PCardinal(@AValue)^ and $007FFFFF) <> $00000000); +end; + +function DoubleIsNan(AValue: Double): Boolean; +begin + Result := ((PUInt64(@AValue)^ and $7FF0000000000000) = $7FF0000000000000) and + ((PUInt64(@AValue)^ and $000FFFFFFFFFFFFF) <> $0000000000000000); +end; + +function ExtendedIsNan(AValue: Extended): Boolean; +begin + if SizeOf(Extended) = CN_EXTENDED_SIZE_10 then + Result := ((PExtendedRec10(@AValue)^.ExpSign and $7FFF) = $7FFF) and + ((PExtendedRec10(@AValue)^.Mantissa and $7FFFFFFFFFFFFFFF) <> 0) + else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then + Result := DoubleIsNan(AValue) + else + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); +end; + +end. diff --git a/CnPack/Crypto/CnKDF.pas b/CnPack/Crypto/CnKDF.pas index 8fc6ab4..0068204 100644 --- a/CnPack/Crypto/CnKDF.pas +++ b/CnPack/Crypto/CnKDF.pas @@ -1,807 +1,807 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -unit CnKDF; -{* |
-================================================================================
-* ƣ
-* ԪƣԿ㷨KDFԪ
-* ԪߣCnPack  (master@cnpack.org)
-*     עԪʵ˻ RFC2898  PBKDF1  PBKDF2 Կ㷨 PBKDF1 ֧ MD2 㷨
-*           ͬʱҲʵ˻ RFC5869  HKDF HMac Կ㷨
-*            SM2/SM9 㷨й涨㷨
-* ƽ̨WinXP + Delphi 5.0
-* ݲԣδ
-*   õԪ豾ػ
-* ޸ļ¼2025.01.09 V1.5
-*                HKDF ʵֺ
-*           2022.06.21 V1.4
-*               ϲһֽ CnSM2SM9KDF  AnsiString ڸ߰汾 Delphi ¿
-*           2022.04.26 V1.3
-*               ޸ LongWord  Integer ַת֧ MacOS64
-*           2022.01.02 V1.2
-*                CnPBKDF2 һԼ Unicode µļ
-*           2021.11.25 V1.1
-*                CnSM2KDF  Unicode µļ
-*           2020.03.30 V1.0
-*               Ԫ CnPemUtils ж
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - SysUtils, Classes, CnNative, CnMD5, CnSHA1, CnSHA2, CnSHA3, CnSM3; - -type - TCnKeyDeriveHash = (ckdMd5, ckdSha256, ckdSha1); - {* CnGetDeriveKey ʹõӴշ} - - TCnPBKDF1KeyHash = (cpdfMd2, cpdfMd5, cpdfSha1); - {* PBKDF1 涨Ӵշ MD2 Dz֧} - - TCnPBKDF2KeyHash = (cpdfSha1Hmac, cpdfSha256Hmac); - {* PBKDF2 涨Ӵշ} - - TCnHKDFHash = (chkMd5, chkSha1, chkSha256, chkSha3_256, chkSm3); - {* HKDFHMAC-based Key Derivation Functionֵ֧Ӵ} - - ECnKDFException = class(Exception); - {* KDF 쳣} - -function CnGetDeriveKey(const Password: AnsiString; const Salt: AnsiString; - OutKey: PAnsiChar; KeyLength: Cardinal; KeyHash: TCnKeyDeriveHash = ckdMd5): Boolean; -{* Openssl е BytesToKeyָӴ㷨ɼ Key - Ŀǰ KeyLength ֧ HashҲ MD5 32 ֽڣSHA256 64 ֽڡ - - - const Password: AnsiString - - const Salt: AnsiString - ֵ - OutKey: PAnsiChar - Կݿַ - KeyLength: Cardinal - Կݿֽڳ - KeyHash: TCnKeyDeriveHash - Ӵ㷨 - - ֵBoolean - Ƿɳɹ -} - -function CnPBKDF1(const Password: AnsiString; const Salt: AnsiString; Count: Integer; - DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF1KeyHash = cpdfMd5): AnsiString; -{* Password Based KDF 1 ʵ֣򵥵Ĺ̶Ӵյֻ֧ MD5 SHA1뷵ֵΪ AnsiString - DerivedKeyByteLength Կֽȹ̶ - - - const Password: AnsiString - - const Salt: AnsiString - ֵ - Count: Integer - - DerivedKeyByteLength: Integer - ɵԿֽڳ - KeyHash: TCnPBKDF1KeyHash - Ӵ㷨 - - ֵAnsiString - ɵԿ -} - -function CnPBKDF2(const Password: AnsiString; const Salt: AnsiString; Count: Integer; - DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF2KeyHash = cpdfSha1Hmac): AnsiString; -{* Password Based KDF 2 ʵ֣ HMAC-SHA1 HMAC-SHA256뷵ֵΪ AnsiString - DerivedKeyByteLength Կֽȿɱ䣬 - - - const Password: AnsiString - - const Salt: AnsiString - ֵ - Count: Integer - - DerivedKeyByteLength: Integer - ɵԿֽڳ - KeyHash: TCnPBKDF2KeyHash - Ӵ㷨 - - ֵAnsiString - ɵԿ -} - -function CnPBKDF1Bytes(const Password: TBytes; const Salt: TBytes; Count: Integer; - DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF1KeyHash = cpdfMd5): TBytes; -{* Password Based KDF 1 ʵ֣򵥵Ĺ̶Ӵյֻ֧ MD5 SHA1뷵ֵΪֽ顣 - DerivedKeyByteLength Կֽȹ̶ - - - const Password: TBytes - - const Salt: TBytes - ֵ - Count: Integer - - DerivedKeyByteLength: Integer - ɵԿֽڳ - KeyHash: TCnPBKDF1KeyHash - Ӵ㷨 - - ֵTBytes - ɵԿ -} - -function CnPBKDF2Bytes(const Password: TBytes; const Salt: TBytes; Count: Integer; - DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF2KeyHash = cpdfSha1Hmac): TBytes; -{* Password Based KDF 2 ʵ֣ HMAC-SHA1 HMAC-SHA256뷵ֵΪֽ顣 - DerivedKeyByteLength Կֽȿɱ䣬 - - - const Password: TBytes - - const Salt: TBytes - ֵ - Count: Integer - - DerivedKeyByteLength: Integer - ɵԿֽڳ - KeyHash: TCnPBKDF2KeyHash - Ӵ㷨 - - ֵTBytes - ɵԿ -} - -// ============ SM2/SM9 й涨ͬһԿַװʵ =============== - -function CnSM2KDF(const Data: AnsiString; DerivedKeyByteLength: Integer): AnsiString; -{* SM2 Բ߹Կ㷨й涨ԿDerivedKeyLength Կֽ - AnsiStringͬʱƺҲû SharedInfo ANSI-X9.63-KDF - - - const Data: AnsiString - Կԭʼݣ - DerivedKeyByteLength: Integer - ɵԿֽڳ - - ֵAnsiString - ɵԿ -} - -function CnSM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): AnsiString; -{* SM9 ʶ㷨й涨ԿDerivedKeyLength Կֽ - AnsiStringͬʱƺҲû SharedInfo ANSI-X9.63-KDF - - - Data: Pointer - Կԭʼݿַ - DataByteLen: Integer - Կԭʼݵֽڳ - DerivedKeyByteLength: Integer - ɵԿֽڳ - - ֵAnsiString - ɵԿ -} - -function CnSM2KDFBytes(const Data: TBytes; DerivedKeyByteLength: Integer): TBytes; -{* Ϊֽʽ SM2 Բ߹Կ㷨й涨Կ - DerivedKeyLength Կֽɵֽ顣 - - - const Data: TBytes - Կԭʼݵֽ - DerivedKeyByteLength: Integer - ɵԿֽڳ - - ֵTBytes - ɵԿ -} - -function CnSM9KDFBytes(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; -{* Ϊڴʽ SM9 ʶ㷨й涨Կ - DerivedKeyLength Կֽɵֽ顣 - - - Data: Pointer - Կԭʼݿַ - DataByteLen: Integer - Կԭʼݵֽڳ - DerivedKeyByteLength: Integer - ɵԿֽڳ - - ֵTBytes - ɵԿ -} - -function CnSM2SM9KDF(Data: TBytes; DerivedKeyByteLength: Integer): TBytes; overload; -{* Ϊֽʽ SM2 Բ߹Կ㷨 SM9 ʶ㷨й涨Կ - DerivedKeyLength ԿֽɵԿֽ顣 - - - Data: TBytes - Կԭʼݵֽ - DerivedKeyByteLength: Integer - ɵԿֽڳ - - ֵTBytes - ɵԿ -} - -function CnSM2SM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; overload; -{* Ϊڴʽ SM2 Բ߹Կ㷨 SM9 ʶ㷨й涨Կ - DerivedKeyLength ԿֽԿֽ顣 - - - Data: Pointer - Կԭʼݿַ - DataByteLen: Integer - Կԭʼݵֽڳ - DerivedKeyByteLength: Integer - ɵԿֽڳ - - ֵTBytes - ɵԿ -} - -function CnHKDF(HKDF: TCnHKDFHash; IKM: Pointer; IKMByteLen: Integer; - Salt: Pointer; SaltByteLen: Integer; Info: Pointer; InfoByteLen: Integer; - DerivedKeyByteLength: Integer): TBytes; overload; -{* HMAC KDF Կ IKMSalt InfoָȵԿ - Salt Ϊգڲʹù̶Ӵսȵȫ 0Info ΪաɵԿ - - - HKDF: TCnHKDFHash - Ӵ㷨 - IKM: Pointer - ԿݣInput Keying Materialַ - IKMByteLen: Integer - Կݵֽڳ - Salt: Pointer - Կֵݿַ - SaltByteLen: Integer - Կֵݵֽڳ - Info: Pointer - ԿĿѡϢݿַ - InfoByteLen: Integer - ԿĿѡϢݵֽڳ - DerivedKeyByteLength: Integer - ɵԿֽڳ - - ֵTBytes - ɵԿ -} - -function CnHKDFBytes(HKDF: TCnHKDFHash; IKM: TBytes; Salt: TBytes; Info: TBytes; - DerivedKeyByteLength: Integer): TBytes; overload; -{* HMAC KDF Կ IKMSalt Info ֽ飬ָȵԿ - Salt Ϊգڲʹù̶Ӵսȵȫ 0Info ΪաɵԿ - - HKDF: TCnHKDFHash - Ӵ㷨 - IKM: TBytes - Կ - Salt: TBytes - Կֵ - Info: TBytes - ԿĿѡϢ - DerivedKeyByteLength: Integer - ɵԿֽڳ - - ֵTBytes - ɵԿ -} - -implementation - -resourcestring - SCnErrorKDFKeyTooLong = 'Derived Key Too Long.'; - SCnErrorKDFParam = 'Invalid Parameters.'; - SCnErrorKDFHashNOTSupport = 'Hash Method NOT Support.'; - -function Min(A, B: Integer): Integer; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - if A < B then - Result := A - else - Result := B; -end; - -function CnGetDeriveKey(const Password, Salt: AnsiString; OutKey: PAnsiChar; KeyLength: Cardinal; - KeyHash: TCnKeyDeriveHash): Boolean; -var - Md5Dig, Md5Dig2: TCnMD5Digest; - Sha256Dig, Sha256Dig2: TCnSHA256Digest; - SaltBuf, PS, PSMD5, PSSHA256: AnsiString; -begin - Result := False; - - if (Password = '') or (OutKey = nil) or (KeyLength < 8) then - Exit; - - SetLength(SaltBuf, 8); - FillChar(SaltBuf[1], Length(SaltBuf), 0); - if Salt <> '' then - Move(Salt[1], SaltBuf[1], Min(Length(Salt), 8)); - - if not (KeyHash in [ckdMd5, ckdSha256]) then - raise ECnKDFException.Create(SCnErrorKDFHashNOTSupport); - - PS := AnsiString(Password) + SaltBuf; // 涨ǰ 8 ֽΪ Salt - if KeyHash = ckdMd5 then - begin - SetLength(PSMD5, SizeOf(TCnMD5Digest) + Length(PS)); - Move(PS[1], PSMD5[SizeOf(TCnMD5Digest) + 1], Length(PS)); - Md5Dig := MD5StringA(PS); - // Salt ƴ MD5 16 ByteΪһ - - Move(Md5Dig[0], OutKey^, Min(KeyLength, SizeOf(TCnMD5Digest))); - if KeyLength <= SizeOf(TCnMD5Digest) then - begin - Result := True; - Exit; - end; - - KeyLength := KeyLength - SizeOf(TCnMD5Digest); - OutKey := PAnsiChar(TCnNativeInt(OutKey) + SizeOf(TCnMD5Digest)); - - Move(Md5Dig[0], PSMD5[1], SizeOf(TCnMD5Digest)); - Md5Dig2 := MD5StringA(PSMD5); - Move(Md5Dig2[0], OutKey^, Min(KeyLength, SizeOf(TCnMD5Digest))); - if KeyLength <= SizeOf(TCnMD5Digest) then - Result := True; - - // KeyLength ̫㲻 - end - else if KeyHash = ckdSha256 then - begin - SetLength(PSSHA256, SizeOf(TCnSHA256Digest) + Length(PS)); - Move(PS[1], PSSHA256[SizeOf(TCnSHA256Digest) + 1], Length(PS)); - Sha256Dig := SHA256StringA(PS); - // Salt ƴ SHA256 32 ByteΪһ - - Move(Sha256Dig[0], OutKey^, Min(KeyLength, SizeOf(TCnSHA256Digest))); - if KeyLength <= SizeOf(TCnSHA256Digest) then - begin - Result := True; - Exit; - end; - - KeyLength := KeyLength - SizeOf(TCnSHA256Digest); - OutKey := PAnsiChar(TCnNativeInt(OutKey) + SizeOf(TCnSHA256Digest)); - - Move(Sha256Dig[0], PSSHA256[1], SizeOf(TCnSHA256Digest)); - Sha256Dig2 := SHA256StringA(PSSHA256); - Move(Sha256Dig2[0], OutKey^, Min(KeyLength, SizeOf(TCnSHA256Digest))); - if KeyLength <= SizeOf(TCnSHA256Digest) then - Result := True; - - // KeyLength ̫㲻 - end; -end; - -(* - T_1 = Hash (P || S) , - T_2 = Hash (T_1) , - ... - T_c = Hash (T_{c-1}) , - DK = Tc<0..dkLen-1> -*) -function CnPBKDF1(const Password, Salt: AnsiString; Count, DerivedKeyByteLength: Integer; - KeyHash: TCnPBKDF1KeyHash): AnsiString; -var - P, S, Res: TBytes; -begin - P := AnsiToBytes(Password); - S := AnsiToBytes(Salt); - Res := CnPBKDF1Bytes(P, S, Count, DerivedKeyByteLength, KeyHash); - Result := BytesToAnsi(Res); -end; - -{ - DK = T1 + T2 + ... + Tdklen/hlen - Ti = F(Password, Salt, c, i) - - F(Password, Salt, c, i) = U1 ^ U2 ^ ... ^ Uc - - U1 = PRF(Password, Salt + INT_32_BE(i)) - U2 = PRF(Password, U1) - ... - Uc = PRF(Password, Uc-1) -} -function CnPBKDF2(const Password, Salt: AnsiString; Count, DerivedKeyByteLength: Integer; - KeyHash: TCnPBKDF2KeyHash): AnsiString; -var - P, S, Res: TBytes; -begin - P := AnsiToBytes(Password); - S := AnsiToBytes(Salt); - Res := CnPBKDF2Bytes(P, S, Count, DerivedKeyByteLength, KeyHash); - Result := BytesToAnsi(Res); -end; - -function CnPBKDF1Bytes(const Password, Salt: TBytes; Count, DerivedKeyByteLength: Integer; - KeyHash: TCnPBKDF1KeyHash = cpdfMd5): TBytes; -var - I: Integer; - Md5Dig, TM: TCnMD5Digest; - Sha1Dig, TS: TCnSHA1Digest; - Ptr: PAnsiChar; -begin - Result := nil; - if (Password = nil) or (Count <= 0) or (DerivedKeyByteLength <= 0) then - raise ECnKDFException.Create(SCnErrorKDFParam); - - case KeyHash of - cpdfMd5: - begin - if DerivedKeyByteLength > SizeOf(TCnMD5Digest) then - raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); - - SetLength(Result, DerivedKeyByteLength); - Md5Dig := MD5Bytes(ConcatBytes(Password, Salt)); // Got T1 - if Count > 1 then - begin - Ptr := PAnsiChar(@TM[0]); - for I := 2 to Count do - begin - TM := Md5Dig; - Md5Dig := MD5Buffer(Ptr, SizeOf(TCnMD5Digest)); // Got T_c - end; - end; - - Move(Md5Dig[0], Result[0], DerivedKeyByteLength); - end; - cpdfSha1: - begin - if DerivedKeyByteLength > SizeOf(TCnSHA1Digest) then - raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); - - SetLength(Result, DerivedKeyByteLength); - Sha1Dig := SHA1Bytes(ConcatBytes(Password, Salt)); // Got T1 - if Count > 1 then - begin - Ptr := PAnsiChar(@TS[0]); - for I := 2 to Count do - begin - TS := Sha1Dig; - Sha1Dig := SHA1Buffer(Ptr, SizeOf(TCnSHA1Digest)); // Got T_c - end; - end; - - Move(Sha1Dig[0], Result[0], DerivedKeyByteLength); - end; - else - raise ECnKDFException.Create(SCnErrorKDFHashNOTSupport); - end; -end; - -function CnPBKDF2Bytes(const Password, Salt: TBytes; Count, DerivedKeyByteLength: Integer; - KeyHash: TCnPBKDF2KeyHash = cpdfSha1Hmac): TBytes; -var - HLen, D, I, J, K: Integer; - Sha1Dig1, Sha1Dig, T1: TCnSHA1Digest; - Sha256Dig1, Sha256Dig, T256: TCnSHA256Digest; - S, S1, S256, Pad: TBytes; - PAddr: Pointer; -begin - Result := nil; - if (Salt = nil) or (Count <= 0) or (DerivedKeyByteLength <=0) then - raise ECnKDFException.Create(SCnErrorKDFParam); - - if (Password = nil) or (Length(Password) = 0) then - PAddr := nil - else - PAddr := @Password[0]; - - case KeyHash of - cpdfSha1Hmac: - HLen := 20; - cpdfSha256Hmac: - HLen := 32; - else - raise ECnKDFException.Create(SCnErrorKDFParam); - end; - - D := (DerivedKeyByteLength div HLen) + 1; - SetLength(S1, SizeOf(TCnSHA1Digest)); - SetLength(S256, SizeOf(TCnSHA256Digest)); - - SetLength(Pad, 4); - if KeyHash = cpdfSha1Hmac then - begin - for I := 1 to D do - begin - Pad[0] := I shr 24; - Pad[1] := I shr 16; - Pad[2] := I shr 8; - Pad[3] := I; - S := ConcatBytes(Salt, Pad); - - SHA1Hmac(PAddr, Length(Password), PAnsiChar(@S[0]), Length(S), Sha1Dig1); - T1 := Sha1Dig1; - - for J := 2 to Count do - begin - SHA1Hmac(PAddr, Length(Password), PAnsiChar(@T1[0]), SizeOf(TCnSHA1Digest), Sha1Dig); - T1 := Sha1Dig; - for K := Low(TCnSHA1Digest) to High(TCnSHA1Digest) do - Sha1Dig1[K] := Sha1Dig1[K] xor T1[K]; - end; - - Move(Sha1Dig1[0], S1[0], Length(S1)); - Result := ConcatBytes(Result, S1); - end; - Result := Copy(Result, 0, DerivedKeyByteLength); - end - else if KeyHash = cpdfSha256Hmac then - begin - for I := 1 to D do - begin - Pad[0] := I shr 24; - Pad[1] := I shr 16; - Pad[2] := I shr 8; - Pad[3] := I; - S := ConcatBytes(Salt, Pad); - - SHA256Hmac(PAddr, Length(Password), PAnsiChar(@S[0]), Length(S), Sha256Dig1); - T256 := Sha256Dig1; - - for J := 2 to Count do - begin - SHA256Hmac(PAddr, Length(Password), PAnsiChar(@T256[0]), SizeOf(TCnSHA256Digest), Sha256Dig); - T256 := Sha256Dig; - for K := Low(TCnSHA256Digest) to High(TCnSHA256Digest) do - Sha256Dig1[K] := Sha256Dig1[K] xor T256[K]; - end; - - Move(Sha256Dig1[0], S256[0], SizeOf(TCnSHA256Digest)); - Result := ConcatBytes(Result, S256); - end; - Result := Copy(Result, 0, DerivedKeyByteLength); - end; -end; - -function CnSM2KDF(const Data: AnsiString; DerivedKeyByteLength: Integer): AnsiString; -var - Res: TBytes; -begin - if (Data = '') or (DerivedKeyByteLength <= 0) then - raise ECnKDFException.Create(SCnErrorKDFParam); - - Res := CnSM2SM9KDF(@Data[1], Length(Data), DerivedKeyByteLength); - Result := BytesToAnsi(Res); -end; - -function CnSM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): AnsiString; -var - Res: TBytes; -begin - Res := CnSM2SM9KDF(Data, DataByteLen, DerivedKeyByteLength); - Result := BytesToAnsi(Res); -end; - -function CnSM2KDFBytes(const Data: TBytes; DerivedKeyByteLength: Integer): TBytes; -begin - Result := CnSM2SM9KDF(Data, DerivedKeyByteLength); -end; - -function CnSM9KDFBytes(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; -begin - Result := CnSM2SM9KDF(Data, DataByteLen, DerivedKeyByteLength); -end; - -function CnSM2SM9KDF(Data: TBytes; DerivedKeyByteLength: Integer): TBytes; -begin - if (Data = nil) or (Length(Data) <= 0) or (DerivedKeyByteLength <= 0) then - raise ECnKDFException.Create(SCnErrorKDFParam); - - Result := CnSM2SM9KDF(@Data[0], Length(Data), DerivedKeyByteLength); -end; - -function CnSM2SM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; overload; -var - DArr: TBytes; - CT, SCT: Cardinal; - I, CeilLen: Integer; - IsInt: Boolean; - SM3D: TCnSM3Digest; -begin - Result := nil; - if (Data = nil) or (DataByteLen <= 0) or (DerivedKeyByteLength <= 0) then - raise ECnKDFException.Create(SCnErrorKDFParam); - - DArr := nil; - CT := 1; - - try - SetLength(DArr, DataByteLen + SizeOf(Cardinal)); - Move(Data^, DArr[0], DataByteLen); - - IsInt := DerivedKeyByteLength mod SizeOf(TCnSM3Digest) = 0; - CeilLen := (DerivedKeyByteLength + SizeOf(TCnSM3Digest) - 1) div SizeOf(TCnSM3Digest); - - SetLength(Result, DerivedKeyByteLength); - for I := 1 to CeilLen do - begin - SCT := UInt32HostToNetwork(CT); // Ȼĵû˵Ҫһ - Move(SCT, DArr[DataByteLen], SizeOf(Cardinal)); - SM3D := SM3(@DArr[0], Length(DArr)); - - if (I = CeilLen) and not IsInt then - begin - // һ 32 ʱֻƶһ - Move(SM3D[0], Result[(I - 1) * SizeOf(TCnSM3Digest)], (DerivedKeyByteLength mod SizeOf(TCnSM3Digest))); - end - else - Move(SM3D[0], Result[(I - 1) * SizeOf(TCnSM3Digest)], SizeOf(TCnSM3Digest)); - - Inc(CT); - end; - finally - SetLength(DArr, 0); - end; -end; - -function CnHKDF(HKDF: TCnHKDFHash; IKM: Pointer; IKMByteLen: Integer; - Salt: Pointer; SaltByteLen: Integer; Info: Pointer; InfoByteLen: Integer; - DerivedKeyByteLength: Integer): TBytes; -const - MAX_BYTE = 255; -var - PRKMd5, Md5T: TCnMD5Digest; - PRKSha1, Sha1T: TCnSHA1Digest; - PRKSha256, Sha256T: TCnSHA256Digest; - PRKSha3256, Sha3256T: TCnSHA3_256Digest; - PRKSm3, Sm3T: TCnSM3Digest; - T0, T: TBytes; - N, I, Start, HashLen: Integer; -begin - if IKM = nil then - IKMByteLen := 0; - - if Salt = nil then - SaltByteLen := 0; - - if Info = nil then - InfoByteLen := 0; - - if (IKMByteLen < 0) or (SaltByteLen < 0) or (InfoByteLen < 0) then - raise ECnKDFException.Create(SCnErrorKDFParam); - - // Extract HMac(Salt, IKM)ע IKM ݣ HMac Key - case HKDF of - chkMd5: - begin - if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnMD5Digest)) then - raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); - - HashLen := SizeOf(TCnMD5Digest); - if (Salt = nil) or (SaltByteLen <= 0) then - begin - FillChar(PRKMd5[0], HashLen, 0); - MD5Hmac(@PRKMd5[0], HashLen, IKM, IKMByteLen, PRKMd5); - end - else - MD5Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKMd5); - end; - chkSha1: - begin - if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSHA1Digest)) then - raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); - - HashLen := SizeOf(TCnSHA1Digest); - if (Salt = nil) or (SaltByteLen <= 0) then - begin - FillChar(PRKSha1[0], HashLen, 0); - SHA1Hmac(@PRKSha1[0], HashLen, IKM, IKMByteLen, PRKSha1); - end - else - SHA1Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSha1); - end; - chkSha256: - begin - if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSHA256Digest)) then - raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); - - HashLen := SizeOf(TCnSHA256Digest); - if (Salt = nil) or (SaltByteLen <= 0) then - begin - FillChar(PRKSha256[0], HashLen, 0); - SHA256Hmac(@PRKSha256[0], HashLen, IKM, IKMByteLen, PRKSha256); - end - else - SHA256Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSha256); - end; - chkSha3_256: - begin - if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSHA3_256Digest)) then - raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); - - HashLen := SizeOf(TCnSHA3_256Digest); - if (Salt = nil) or (SaltByteLen <= 0) then - begin - FillChar(PRKSha3256[0], HashLen, 0); - SHA3_256Hmac(@PRKSha3256[0], HashLen, IKM, IKMByteLen, PRKSha3256); - end - else - SHA3_256Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSha3256); - end; - chkSm3: - begin - if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSM3Digest)) then - raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); - - HashLen := SizeOf(TCnSM3Digest); - if (Salt = nil) or (SaltByteLen <= 0) then - begin - FillChar(PRKSm3[0], HashLen, 0); - SM3Hmac(@PRKSm3[0], HashLen, IKM, IKMByteLen, PRKSm3); - end - else - SM3Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSm3); - end; - else - raise ECnKDFException.Create(SCnErrorKDFHashNOTSupport); - end; - - // ʼ Expand - SetLength(T0, InfoByteLen + 1); - if InfoByteLen > 0 then - Move(Info^, T0[0], InfoByteLen); - T0[InfoByteLen] := 1; // ƴװ T0 - - // ʼÿֵļ - SetLength(T, HashLen + InfoByteLen + 1); - - // ýȲ - N := (DerivedKeyByteLength + HashLen - 1) div HashLen; - SetLength(Result, DerivedKeyByteLength); - - // T0 һ T1 - case HKDF of - chkMd5: MD5Hmac(@PRKMd5[0], HashLen, @T0[0], Length(T0), Md5T); - chkSha1: SHA1Hmac(@PRKSha1[0], HashLen, @T0[0], Length(T0), Sha1T); - chkSha256: SHA256Hmac(@PRKSha256[0], HashLen, @T0[0], Length(T0), Sha256T); - chkSha3_256: SHA3_256Hmac(@PRKSha3256[0], HashLen, @T0[0], Length(T0), Sha3256T); - chkSm3: SM3Hmac(@PRKSm3[0], HashLen, @T0[0], Length(T0), Sm3T); - end; - - Start := 0; - for I := 1 to N do - begin - // T1 ƴڽ - if DerivedKeyByteLength > HashLen then - begin - case HKDF of - chkMd5: Move(Md5T[0], Result[Start], HashLen); - chkSha1: Move(Sha1T[0], Result[Start], HashLen); - chkSha256: Move(Sha256T[0], Result[Start], HashLen); - chkSha3_256: Move(Sha3256T[0], Result[Start], HashLen); - chkSm3: Move(Sm3T[0], Result[Start], HashLen); - end; - Inc(Start, HashLen); - Dec(DerivedKeyByteLength, HashLen); - end - else - begin - case HKDF of - chkMd5: Move(Md5T[0], Result[Start], DerivedKeyByteLength); - chkSha1: Move(Sha1T[0], Result[Start], DerivedKeyByteLength); - chkSha256: Move(Sha256T[0], Result[Start], DerivedKeyByteLength); - chkSha3_256: Move(Sha3256T[0], Result[Start], DerivedKeyByteLength); - chkSm3: Move(Sm3T[0], Result[Start], DerivedKeyByteLength); - end; - Break; - end; - - // T1 Info ƴһ𲢼һ - case HKDF of - chkMd5: Move(Md5T[0], T[0], HashLen); - chkSha1: Move(Sha1T[0], T[0], HashLen); - chkSha256: Move(Sha256T[0], T[0], HashLen); - chkSha3_256: Move(Sha3256T[0], T[0], HashLen); - chkSm3: Move(Sm3T[0], T[0], HashLen); - end; - Move(Info^, T[HashLen], InfoByteLen); - T[HashLen + InfoByteLen] := I + 1; - - // Ӵ T2 T1 - case HKDF of - chkMd5: MD5Hmac(@PRKMd5[0], HashLen, @T[0], Length(T), Md5T); - chkSha1: SHA1Hmac(@PRKSha1[0], HashLen, @T[0], Length(T), Sha1T); - chkSha256: SHA256Hmac(@PRKSha256[0], HashLen, @T[0], Length(T), Sha256T); - chkSha3_256: SHA3_256Hmac(@PRKSha3256[0], HashLen, @T[0], Length(T), Sha3256T); - chkSm3: SM3Hmac(@PRKSm3[0], HashLen, @T[0], Length(T), Sm3T); - end; - end; -end; - -function CnHKDFBytes(HKDF: TCnHKDFHash; IKM: TBytes; Salt: TBytes; Info: TBytes; - DerivedKeyByteLength: Integer): TBytes; -var - IKMP, SaltP, InfoP: Pointer; - IKML, SaltL, InfoL: Integer; -begin - IKMP := nil; - SaltP := nil; - InfoP := nil; - IKML := 0; - SaltL := 0; - InfoL := 0; - - if Length(IKM) > 0 then - begin - IKMP := @IKM[0]; - IKML := Length(IKM); - end; - if Length(Salt) > 0 then - begin - SaltP := @Salt[0]; - SaltL := Length(Salt); - end; - if Length(Info) > 0 then - begin - InfoP := @Info[0]; - InfoL := Length(Info); - end; - - Result := CnHKDF(HKDF, IKMP, IKML, SaltP, SaltL, InfoP, InfoL, DerivedKeyByteLength); -end; - -end. +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnKDF; +{* |
+================================================================================
+* ƣ
+* ԪƣԿ㷨KDFԪ
+* ԪߣCnPack  (master@cnpack.org)
+*     עԪʵ˻ RFC2898  PBKDF1  PBKDF2 Կ㷨 PBKDF1 ֧ MD2 㷨
+*           ͬʱҲʵ˻ RFC5869  HKDF HMac Կ㷨
+*            SM2/SM9 㷨й涨㷨
+* ƽ̨WinXP + Delphi 5.0
+* ݲԣδ
+*   õԪ豾ػ
+* ޸ļ¼2025.01.09 V1.5
+*                HKDF ʵֺ
+*           2022.06.21 V1.4
+*               ϲһֽ CnSM2SM9KDF  AnsiString ڸ߰汾 Delphi ¿
+*           2022.04.26 V1.3
+*               ޸ LongWord  Integer ַת֧ MacOS64
+*           2022.01.02 V1.2
+*                CnPBKDF2 һԼ Unicode µļ
+*           2021.11.25 V1.1
+*                CnSM2KDF  Unicode µļ
+*           2020.03.30 V1.0
+*               Ԫ CnPemUtils ж
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, CnNative, CnMD5, CnSHA1, CnSHA2, CnSHA3, CnSM3; + +type + TCnKeyDeriveHash = (ckdMd5, ckdSha256, ckdSha1); + {* CnGetDeriveKey ʹõӴշ} + + TCnPBKDF1KeyHash = (cpdfMd2, cpdfMd5, cpdfSha1); + {* PBKDF1 涨Ӵշ MD2 Dz֧} + + TCnPBKDF2KeyHash = (cpdfSha1Hmac, cpdfSha256Hmac); + {* PBKDF2 涨Ӵշ} + + TCnHKDFHash = (chkMd5, chkSha1, chkSha256, chkSha3_256, chkSm3); + {* HKDFHMAC-based Key Derivation Functionֵ֧Ӵ} + + ECnKDFException = class(Exception); + {* KDF 쳣} + +function CnGetDeriveKey(const Password: AnsiString; const Salt: AnsiString; + OutKey: PAnsiChar; KeyLength: Cardinal; KeyHash: TCnKeyDeriveHash = ckdMd5): Boolean; +{* Openssl е BytesToKeyָӴ㷨ɼ Key + Ŀǰ KeyLength ֧ HashҲ MD5 32 ֽڣSHA256 64 ֽڡ + + + const Password: AnsiString - + const Salt: AnsiString - ֵ + OutKey: PAnsiChar - Կݿַ + KeyLength: Cardinal - Կݿֽڳ + KeyHash: TCnKeyDeriveHash - Ӵ㷨 + + ֵBoolean - Ƿɳɹ +} + +function CnPBKDF1(const Password: AnsiString; const Salt: AnsiString; Count: Integer; + DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF1KeyHash = cpdfMd5): AnsiString; +{* Password Based KDF 1 ʵ֣򵥵Ĺ̶Ӵյֻ֧ MD5 SHA1뷵ֵΪ AnsiString + DerivedKeyByteLength Կֽȹ̶ + + + const Password: AnsiString - + const Salt: AnsiString - ֵ + Count: Integer - + DerivedKeyByteLength: Integer - ɵԿֽڳ + KeyHash: TCnPBKDF1KeyHash - Ӵ㷨 + + ֵAnsiString - ɵԿ +} + +function CnPBKDF2(const Password: AnsiString; const Salt: AnsiString; Count: Integer; + DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF2KeyHash = cpdfSha1Hmac): AnsiString; +{* Password Based KDF 2 ʵ֣ HMAC-SHA1 HMAC-SHA256뷵ֵΪ AnsiString + DerivedKeyByteLength Կֽȿɱ䣬 + + + const Password: AnsiString - + const Salt: AnsiString - ֵ + Count: Integer - + DerivedKeyByteLength: Integer - ɵԿֽڳ + KeyHash: TCnPBKDF2KeyHash - Ӵ㷨 + + ֵAnsiString - ɵԿ +} + +function CnPBKDF1Bytes(const Password: TBytes; const Salt: TBytes; Count: Integer; + DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF1KeyHash = cpdfMd5): TBytes; +{* Password Based KDF 1 ʵ֣򵥵Ĺ̶Ӵյֻ֧ MD5 SHA1뷵ֵΪֽ顣 + DerivedKeyByteLength Կֽȹ̶ + + + const Password: TBytes - + const Salt: TBytes - ֵ + Count: Integer - + DerivedKeyByteLength: Integer - ɵԿֽڳ + KeyHash: TCnPBKDF1KeyHash - Ӵ㷨 + + ֵTBytes - ɵԿ +} + +function CnPBKDF2Bytes(const Password: TBytes; const Salt: TBytes; Count: Integer; + DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF2KeyHash = cpdfSha1Hmac): TBytes; +{* Password Based KDF 2 ʵ֣ HMAC-SHA1 HMAC-SHA256뷵ֵΪֽ顣 + DerivedKeyByteLength Կֽȿɱ䣬 + + + const Password: TBytes - + const Salt: TBytes - ֵ + Count: Integer - + DerivedKeyByteLength: Integer - ɵԿֽڳ + KeyHash: TCnPBKDF2KeyHash - Ӵ㷨 + + ֵTBytes - ɵԿ +} + +// ============ SM2/SM9 й涨ͬһԿַװʵ =============== + +function CnSM2KDF(const Data: AnsiString; DerivedKeyByteLength: Integer): AnsiString; +{* SM2 Բ߹Կ㷨й涨ԿDerivedKeyLength Կֽ + AnsiStringͬʱƺҲû SharedInfo ANSI-X9.63-KDF + + + const Data: AnsiString - Կԭʼݣ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵAnsiString - ɵԿ +} + +function CnSM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): AnsiString; +{* SM9 ʶ㷨й涨ԿDerivedKeyLength Կֽ + AnsiStringͬʱƺҲû SharedInfo ANSI-X9.63-KDF + + + Data: Pointer - Կԭʼݿַ + DataByteLen: Integer - Կԭʼݵֽڳ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵAnsiString - ɵԿ +} + +function CnSM2KDFBytes(const Data: TBytes; DerivedKeyByteLength: Integer): TBytes; +{* Ϊֽʽ SM2 Բ߹Կ㷨й涨Կ + DerivedKeyLength Կֽɵֽ顣 + + + const Data: TBytes - Կԭʼݵֽ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnSM9KDFBytes(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; +{* Ϊڴʽ SM9 ʶ㷨й涨Կ + DerivedKeyLength Կֽɵֽ顣 + + + Data: Pointer - Կԭʼݿַ + DataByteLen: Integer - Կԭʼݵֽڳ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnSM2SM9KDF(Data: TBytes; DerivedKeyByteLength: Integer): TBytes; overload; +{* Ϊֽʽ SM2 Բ߹Կ㷨 SM9 ʶ㷨й涨Կ + DerivedKeyLength ԿֽɵԿֽ顣 + + + Data: TBytes - Կԭʼݵֽ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnSM2SM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; overload; +{* Ϊڴʽ SM2 Բ߹Կ㷨 SM9 ʶ㷨й涨Կ + DerivedKeyLength ԿֽԿֽ顣 + + + Data: Pointer - Կԭʼݿַ + DataByteLen: Integer - Կԭʼݵֽڳ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnHKDF(HKDF: TCnHKDFHash; IKM: Pointer; IKMByteLen: Integer; + Salt: Pointer; SaltByteLen: Integer; Info: Pointer; InfoByteLen: Integer; + DerivedKeyByteLength: Integer): TBytes; overload; +{* HMAC KDF Կ IKMSalt InfoָȵԿ + Salt Ϊգڲʹù̶Ӵսȵȫ 0Info ΪաɵԿ + + + HKDF: TCnHKDFHash - Ӵ㷨 + IKM: Pointer - ԿݣInput Keying Materialַ + IKMByteLen: Integer - Կݵֽڳ + Salt: Pointer - Կֵݿַ + SaltByteLen: Integer - Կֵݵֽڳ + Info: Pointer - ԿĿѡϢݿַ + InfoByteLen: Integer - ԿĿѡϢݵֽڳ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnHKDFBytes(HKDF: TCnHKDFHash; IKM: TBytes; Salt: TBytes; Info: TBytes; + DerivedKeyByteLength: Integer): TBytes; overload; +{* HMAC KDF Կ IKMSalt Info ֽ飬ָȵԿ + Salt Ϊգڲʹù̶Ӵսȵȫ 0Info ΪաɵԿ + + HKDF: TCnHKDFHash - Ӵ㷨 + IKM: TBytes - Կ + Salt: TBytes - Կֵ + Info: TBytes - ԿĿѡϢ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +implementation + +resourcestring + SCnErrorKDFKeyTooLong = 'Derived Key Too Long.'; + SCnErrorKDFParam = 'Invalid Parameters.'; + SCnErrorKDFHashNOTSupport = 'Hash Method NOT Support.'; + +function Min(A, B: Integer): Integer; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + if A < B then + Result := A + else + Result := B; +end; + +function CnGetDeriveKey(const Password, Salt: AnsiString; OutKey: PAnsiChar; KeyLength: Cardinal; + KeyHash: TCnKeyDeriveHash): Boolean; +var + Md5Dig, Md5Dig2: TCnMD5Digest; + Sha256Dig, Sha256Dig2: TCnSHA256Digest; + SaltBuf, PS, PSMD5, PSSHA256: AnsiString; +begin + Result := False; + + if (Password = '') or (OutKey = nil) or (KeyLength < 8) then + Exit; + + SetLength(SaltBuf, 8); + FillChar(SaltBuf[1], Length(SaltBuf), 0); + if Salt <> '' then + Move(Salt[1], SaltBuf[1], Min(Length(Salt), 8)); + + if not (KeyHash in [ckdMd5, ckdSha256]) then + raise ECnKDFException.Create(SCnErrorKDFHashNOTSupport); + + PS := AnsiString(Password) + SaltBuf; // 涨ǰ 8 ֽΪ Salt + if KeyHash = ckdMd5 then + begin + SetLength(PSMD5, SizeOf(TCnMD5Digest) + Length(PS)); + Move(PS[1], PSMD5[SizeOf(TCnMD5Digest) + 1], Length(PS)); + Md5Dig := MD5StringA(PS); + // Salt ƴ MD5 16 ByteΪһ + + Move(Md5Dig[0], OutKey^, Min(KeyLength, SizeOf(TCnMD5Digest))); + if KeyLength <= SizeOf(TCnMD5Digest) then + begin + Result := True; + Exit; + end; + + KeyLength := KeyLength - SizeOf(TCnMD5Digest); + OutKey := PAnsiChar(TCnNativeInt(OutKey) + SizeOf(TCnMD5Digest)); + + Move(Md5Dig[0], PSMD5[1], SizeOf(TCnMD5Digest)); + Md5Dig2 := MD5StringA(PSMD5); + Move(Md5Dig2[0], OutKey^, Min(KeyLength, SizeOf(TCnMD5Digest))); + if KeyLength <= SizeOf(TCnMD5Digest) then + Result := True; + + // KeyLength ̫㲻 + end + else if KeyHash = ckdSha256 then + begin + SetLength(PSSHA256, SizeOf(TCnSHA256Digest) + Length(PS)); + Move(PS[1], PSSHA256[SizeOf(TCnSHA256Digest) + 1], Length(PS)); + Sha256Dig := SHA256StringA(PS); + // Salt ƴ SHA256 32 ByteΪһ + + Move(Sha256Dig[0], OutKey^, Min(KeyLength, SizeOf(TCnSHA256Digest))); + if KeyLength <= SizeOf(TCnSHA256Digest) then + begin + Result := True; + Exit; + end; + + KeyLength := KeyLength - SizeOf(TCnSHA256Digest); + OutKey := PAnsiChar(TCnNativeInt(OutKey) + SizeOf(TCnSHA256Digest)); + + Move(Sha256Dig[0], PSSHA256[1], SizeOf(TCnSHA256Digest)); + Sha256Dig2 := SHA256StringA(PSSHA256); + Move(Sha256Dig2[0], OutKey^, Min(KeyLength, SizeOf(TCnSHA256Digest))); + if KeyLength <= SizeOf(TCnSHA256Digest) then + Result := True; + + // KeyLength ̫㲻 + end; +end; + +(* + T_1 = Hash (P || S) , + T_2 = Hash (T_1) , + ... + T_c = Hash (T_{c-1}) , + DK = Tc<0..dkLen-1> +*) +function CnPBKDF1(const Password, Salt: AnsiString; Count, DerivedKeyByteLength: Integer; + KeyHash: TCnPBKDF1KeyHash): AnsiString; +var + P, S, Res: TBytes; +begin + P := AnsiToBytes(Password); + S := AnsiToBytes(Salt); + Res := CnPBKDF1Bytes(P, S, Count, DerivedKeyByteLength, KeyHash); + Result := BytesToAnsi(Res); +end; + +{ + DK = T1 + T2 + ... + Tdklen/hlen + Ti = F(Password, Salt, c, i) + + F(Password, Salt, c, i) = U1 ^ U2 ^ ... ^ Uc + + U1 = PRF(Password, Salt + INT_32_BE(i)) + U2 = PRF(Password, U1) + ... + Uc = PRF(Password, Uc-1) +} +function CnPBKDF2(const Password, Salt: AnsiString; Count, DerivedKeyByteLength: Integer; + KeyHash: TCnPBKDF2KeyHash): AnsiString; +var + P, S, Res: TBytes; +begin + P := AnsiToBytes(Password); + S := AnsiToBytes(Salt); + Res := CnPBKDF2Bytes(P, S, Count, DerivedKeyByteLength, KeyHash); + Result := BytesToAnsi(Res); +end; + +function CnPBKDF1Bytes(const Password, Salt: TBytes; Count, DerivedKeyByteLength: Integer; + KeyHash: TCnPBKDF1KeyHash = cpdfMd5): TBytes; +var + I: Integer; + Md5Dig, TM: TCnMD5Digest; + Sha1Dig, TS: TCnSHA1Digest; + Ptr: PAnsiChar; +begin + Result := nil; + if (Password = nil) or (Count <= 0) or (DerivedKeyByteLength <= 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + case KeyHash of + cpdfMd5: + begin + if DerivedKeyByteLength > SizeOf(TCnMD5Digest) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + SetLength(Result, DerivedKeyByteLength); + Md5Dig := MD5Bytes(ConcatBytes(Password, Salt)); // Got T1 + if Count > 1 then + begin + Ptr := PAnsiChar(@TM[0]); + for I := 2 to Count do + begin + TM := Md5Dig; + Md5Dig := MD5Buffer(Ptr, SizeOf(TCnMD5Digest)); // Got T_c + end; + end; + + Move(Md5Dig[0], Result[0], DerivedKeyByteLength); + end; + cpdfSha1: + begin + if DerivedKeyByteLength > SizeOf(TCnSHA1Digest) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + SetLength(Result, DerivedKeyByteLength); + Sha1Dig := SHA1Bytes(ConcatBytes(Password, Salt)); // Got T1 + if Count > 1 then + begin + Ptr := PAnsiChar(@TS[0]); + for I := 2 to Count do + begin + TS := Sha1Dig; + Sha1Dig := SHA1Buffer(Ptr, SizeOf(TCnSHA1Digest)); // Got T_c + end; + end; + + Move(Sha1Dig[0], Result[0], DerivedKeyByteLength); + end; + else + raise ECnKDFException.Create(SCnErrorKDFHashNOTSupport); + end; +end; + +function CnPBKDF2Bytes(const Password, Salt: TBytes; Count, DerivedKeyByteLength: Integer; + KeyHash: TCnPBKDF2KeyHash = cpdfSha1Hmac): TBytes; +var + HLen, D, I, J, K: Integer; + Sha1Dig1, Sha1Dig, T1: TCnSHA1Digest; + Sha256Dig1, Sha256Dig, T256: TCnSHA256Digest; + S, S1, S256, Pad: TBytes; + PAddr: Pointer; +begin + Result := nil; + if (Salt = nil) or (Count <= 0) or (DerivedKeyByteLength <=0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + if (Password = nil) or (Length(Password) = 0) then + PAddr := nil + else + PAddr := @Password[0]; + + case KeyHash of + cpdfSha1Hmac: + HLen := 20; + cpdfSha256Hmac: + HLen := 32; + else + raise ECnKDFException.Create(SCnErrorKDFParam); + end; + + D := (DerivedKeyByteLength div HLen) + 1; + SetLength(S1, SizeOf(TCnSHA1Digest)); + SetLength(S256, SizeOf(TCnSHA256Digest)); + + SetLength(Pad, 4); + if KeyHash = cpdfSha1Hmac then + begin + for I := 1 to D do + begin + Pad[0] := I shr 24; + Pad[1] := I shr 16; + Pad[2] := I shr 8; + Pad[3] := I; + S := ConcatBytes(Salt, Pad); + + SHA1Hmac(PAddr, Length(Password), PAnsiChar(@S[0]), Length(S), Sha1Dig1); + T1 := Sha1Dig1; + + for J := 2 to Count do + begin + SHA1Hmac(PAddr, Length(Password), PAnsiChar(@T1[0]), SizeOf(TCnSHA1Digest), Sha1Dig); + T1 := Sha1Dig; + for K := Low(TCnSHA1Digest) to High(TCnSHA1Digest) do + Sha1Dig1[K] := Sha1Dig1[K] xor T1[K]; + end; + + Move(Sha1Dig1[0], S1[0], Length(S1)); + Result := ConcatBytes(Result, S1); + end; + Result := Copy(Result, 0, DerivedKeyByteLength); + end + else if KeyHash = cpdfSha256Hmac then + begin + for I := 1 to D do + begin + Pad[0] := I shr 24; + Pad[1] := I shr 16; + Pad[2] := I shr 8; + Pad[3] := I; + S := ConcatBytes(Salt, Pad); + + SHA256Hmac(PAddr, Length(Password), PAnsiChar(@S[0]), Length(S), Sha256Dig1); + T256 := Sha256Dig1; + + for J := 2 to Count do + begin + SHA256Hmac(PAddr, Length(Password), PAnsiChar(@T256[0]), SizeOf(TCnSHA256Digest), Sha256Dig); + T256 := Sha256Dig; + for K := Low(TCnSHA256Digest) to High(TCnSHA256Digest) do + Sha256Dig1[K] := Sha256Dig1[K] xor T256[K]; + end; + + Move(Sha256Dig1[0], S256[0], SizeOf(TCnSHA256Digest)); + Result := ConcatBytes(Result, S256); + end; + Result := Copy(Result, 0, DerivedKeyByteLength); + end; +end; + +function CnSM2KDF(const Data: AnsiString; DerivedKeyByteLength: Integer): AnsiString; +var + Res: TBytes; +begin + if (Data = '') or (DerivedKeyByteLength <= 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + Res := CnSM2SM9KDF(@Data[1], Length(Data), DerivedKeyByteLength); + Result := BytesToAnsi(Res); +end; + +function CnSM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): AnsiString; +var + Res: TBytes; +begin + Res := CnSM2SM9KDF(Data, DataByteLen, DerivedKeyByteLength); + Result := BytesToAnsi(Res); +end; + +function CnSM2KDFBytes(const Data: TBytes; DerivedKeyByteLength: Integer): TBytes; +begin + Result := CnSM2SM9KDF(Data, DerivedKeyByteLength); +end; + +function CnSM9KDFBytes(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; +begin + Result := CnSM2SM9KDF(Data, DataByteLen, DerivedKeyByteLength); +end; + +function CnSM2SM9KDF(Data: TBytes; DerivedKeyByteLength: Integer): TBytes; +begin + if (Data = nil) or (Length(Data) <= 0) or (DerivedKeyByteLength <= 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + Result := CnSM2SM9KDF(@Data[0], Length(Data), DerivedKeyByteLength); +end; + +function CnSM2SM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; overload; +var + DArr: TBytes; + CT, SCT: Cardinal; + I, CeilLen: Integer; + IsInt: Boolean; + SM3D: TCnSM3Digest; +begin + Result := nil; + if (Data = nil) or (DataByteLen <= 0) or (DerivedKeyByteLength <= 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + DArr := nil; + CT := 1; + + try + SetLength(DArr, DataByteLen + SizeOf(Cardinal)); + Move(Data^, DArr[0], DataByteLen); + + IsInt := DerivedKeyByteLength mod SizeOf(TCnSM3Digest) = 0; + CeilLen := (DerivedKeyByteLength + SizeOf(TCnSM3Digest) - 1) div SizeOf(TCnSM3Digest); + + SetLength(Result, DerivedKeyByteLength); + for I := 1 to CeilLen do + begin + SCT := UInt32HostToNetwork(CT); // Ȼĵû˵Ҫһ + Move(SCT, DArr[DataByteLen], SizeOf(Cardinal)); + SM3D := SM3(@DArr[0], Length(DArr)); + + if (I = CeilLen) and not IsInt then + begin + // һ 32 ʱֻƶһ + Move(SM3D[0], Result[(I - 1) * SizeOf(TCnSM3Digest)], (DerivedKeyByteLength mod SizeOf(TCnSM3Digest))); + end + else + Move(SM3D[0], Result[(I - 1) * SizeOf(TCnSM3Digest)], SizeOf(TCnSM3Digest)); + + Inc(CT); + end; + finally + SetLength(DArr, 0); + end; +end; + +function CnHKDF(HKDF: TCnHKDFHash; IKM: Pointer; IKMByteLen: Integer; + Salt: Pointer; SaltByteLen: Integer; Info: Pointer; InfoByteLen: Integer; + DerivedKeyByteLength: Integer): TBytes; +const + MAX_BYTE = 255; +var + PRKMd5, Md5T: TCnMD5Digest; + PRKSha1, Sha1T: TCnSHA1Digest; + PRKSha256, Sha256T: TCnSHA256Digest; + PRKSha3256, Sha3256T: TCnSHA3_256Digest; + PRKSm3, Sm3T: TCnSM3Digest; + T0, T: TBytes; + N, I, Start, HashLen: Integer; +begin + if IKM = nil then + IKMByteLen := 0; + + if Salt = nil then + SaltByteLen := 0; + + if Info = nil then + InfoByteLen := 0; + + if (IKMByteLen < 0) or (SaltByteLen < 0) or (InfoByteLen < 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + // Extract HMac(Salt, IKM)ע IKM ݣ HMac Key + case HKDF of + chkMd5: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnMD5Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnMD5Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKMd5[0], HashLen, 0); + MD5Hmac(@PRKMd5[0], HashLen, IKM, IKMByteLen, PRKMd5); + end + else + MD5Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKMd5); + end; + chkSha1: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSHA1Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnSHA1Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKSha1[0], HashLen, 0); + SHA1Hmac(@PRKSha1[0], HashLen, IKM, IKMByteLen, PRKSha1); + end + else + SHA1Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSha1); + end; + chkSha256: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSHA256Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnSHA256Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKSha256[0], HashLen, 0); + SHA256Hmac(@PRKSha256[0], HashLen, IKM, IKMByteLen, PRKSha256); + end + else + SHA256Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSha256); + end; + chkSha3_256: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSHA3_256Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnSHA3_256Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKSha3256[0], HashLen, 0); + SHA3_256Hmac(@PRKSha3256[0], HashLen, IKM, IKMByteLen, PRKSha3256); + end + else + SHA3_256Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSha3256); + end; + chkSm3: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSM3Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnSM3Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKSm3[0], HashLen, 0); + SM3Hmac(@PRKSm3[0], HashLen, IKM, IKMByteLen, PRKSm3); + end + else + SM3Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSm3); + end; + else + raise ECnKDFException.Create(SCnErrorKDFHashNOTSupport); + end; + + // ʼ Expand + SetLength(T0, InfoByteLen + 1); + if InfoByteLen > 0 then + Move(Info^, T0[0], InfoByteLen); + T0[InfoByteLen] := 1; // ƴװ T0 + + // ʼÿֵļ + SetLength(T, HashLen + InfoByteLen + 1); + + // ýȲ + N := (DerivedKeyByteLength + HashLen - 1) div HashLen; + SetLength(Result, DerivedKeyByteLength); + + // T0 һ T1 + case HKDF of + chkMd5: MD5Hmac(@PRKMd5[0], HashLen, @T0[0], Length(T0), Md5T); + chkSha1: SHA1Hmac(@PRKSha1[0], HashLen, @T0[0], Length(T0), Sha1T); + chkSha256: SHA256Hmac(@PRKSha256[0], HashLen, @T0[0], Length(T0), Sha256T); + chkSha3_256: SHA3_256Hmac(@PRKSha3256[0], HashLen, @T0[0], Length(T0), Sha3256T); + chkSm3: SM3Hmac(@PRKSm3[0], HashLen, @T0[0], Length(T0), Sm3T); + end; + + Start := 0; + for I := 1 to N do + begin + // T1 ƴڽ + if DerivedKeyByteLength > HashLen then + begin + case HKDF of + chkMd5: Move(Md5T[0], Result[Start], HashLen); + chkSha1: Move(Sha1T[0], Result[Start], HashLen); + chkSha256: Move(Sha256T[0], Result[Start], HashLen); + chkSha3_256: Move(Sha3256T[0], Result[Start], HashLen); + chkSm3: Move(Sm3T[0], Result[Start], HashLen); + end; + Inc(Start, HashLen); + Dec(DerivedKeyByteLength, HashLen); + end + else + begin + case HKDF of + chkMd5: Move(Md5T[0], Result[Start], DerivedKeyByteLength); + chkSha1: Move(Sha1T[0], Result[Start], DerivedKeyByteLength); + chkSha256: Move(Sha256T[0], Result[Start], DerivedKeyByteLength); + chkSha3_256: Move(Sha3256T[0], Result[Start], DerivedKeyByteLength); + chkSm3: Move(Sm3T[0], Result[Start], DerivedKeyByteLength); + end; + Break; + end; + + // T1 Info ƴһ𲢼һ + case HKDF of + chkMd5: Move(Md5T[0], T[0], HashLen); + chkSha1: Move(Sha1T[0], T[0], HashLen); + chkSha256: Move(Sha256T[0], T[0], HashLen); + chkSha3_256: Move(Sha3256T[0], T[0], HashLen); + chkSm3: Move(Sm3T[0], T[0], HashLen); + end; + Move(Info^, T[HashLen], InfoByteLen); + T[HashLen + InfoByteLen] := I + 1; + + // Ӵ T2 T1 + case HKDF of + chkMd5: MD5Hmac(@PRKMd5[0], HashLen, @T[0], Length(T), Md5T); + chkSha1: SHA1Hmac(@PRKSha1[0], HashLen, @T[0], Length(T), Sha1T); + chkSha256: SHA256Hmac(@PRKSha256[0], HashLen, @T[0], Length(T), Sha256T); + chkSha3_256: SHA3_256Hmac(@PRKSha3256[0], HashLen, @T[0], Length(T), Sha3256T); + chkSm3: SM3Hmac(@PRKSm3[0], HashLen, @T[0], Length(T), Sm3T); + end; + end; +end; + +function CnHKDFBytes(HKDF: TCnHKDFHash; IKM: TBytes; Salt: TBytes; Info: TBytes; + DerivedKeyByteLength: Integer): TBytes; +var + IKMP, SaltP, InfoP: Pointer; + IKML, SaltL, InfoL: Integer; +begin + IKMP := nil; + SaltP := nil; + InfoP := nil; + IKML := 0; + SaltL := 0; + InfoL := 0; + + if Length(IKM) > 0 then + begin + IKMP := @IKM[0]; + IKML := Length(IKM); + end; + if Length(Salt) > 0 then + begin + SaltP := @Salt[0]; + SaltL := Length(Salt); + end; + if Length(Info) > 0 then + begin + InfoP := @Info[0]; + InfoL := Length(Info); + end; + + Result := CnHKDF(HKDF, IKMP, IKML, SaltP, SaltL, InfoP, InfoL, DerivedKeyByteLength); +end; + +end. diff --git a/CnPack/Crypto/CnMD5.pas b/CnPack/Crypto/CnMD5.pas index e859993..90d1cad 100644 --- a/CnPack/Crypto/CnMD5.pas +++ b/CnPack/Crypto/CnMD5.pas @@ -1,884 +1,884 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -{******************************************************************************} -{ } -{ MD5 Message-Digest for Delphi 4 } -{ } -{ Delphi 4 Unit implementing the } -{ RSA Data Security, Inc. MD5 Message-Digest Algorithm } -{ } -{ Implementation of Ronald L. Rivest's RFC 1321 } -{ } -{ Copyright ?1997-1999 Medienagentur Fichtner & Meyer } -{ Written by Matthias Fichtner } -{ } -{ -----------------------------------------------------------------------------} -{ See RFC 1321 for RSA Data Security's copyright and license notice! } -{ -----------------------------------------------------------------------------} -{ The latest release of md5.pas will always be available from } -{ the distribution site at: http://www.fichtner.net/delphi/md5/ } -{ -----------------------------------------------------------------------------} -{ Please send questions, bug reports and suggestions } -{ regarding this code to: mfichtner@fichtner-meyer.com } -{ -----------------------------------------------------------------------------} -{ This code is provided "as is" without express or } -{ implied warranty of any kind. Use it at your own risk. } -{******************************************************************************} - -unit CnMD5; -{* |
-================================================================================
-* ƣ
-* ԪƣMD5 Ӵ㷨ʵֵԪ
-* Ԫߣ壨QSoft hq.com@263.net; http://qsoft.51.net
-*            Ronald L. Rivest  MD5.pas дԭʼ
-*     עԪʵ MD5 Ӵ㷨Ӧ HMAC 㷨
-* ƽ̨PWin2000Pro + Delphi 5.0
-* ݲԣPWin9X/2000/XP + Delphi 5/6
-*   õԪеַϱػʽ
-* ޸ļ¼2019.12.12 V1.4
-*               ֧ TBytes
-*           2019.04.15 V1.3
-*               ֧ Win32/Win64/MacOS
-*           2014.11.14 V1.2
-*               л Pascal ֿ֧ƽ̨
-*           2003.09.18 V1.1
-*               òҵ˸õԪԭߵİȨ
-*           2003.09.18 V1.0
-*               Ԫ
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - Classes, SysUtils, CnConsts, CnNative {$IFDEF MSWINDOWS}, Windows {$ENDIF}; - -type - PMD5Digest = ^TCnMD5Digest; - TCnMD5Digest = array[0..15] of Byte; - {* MD5 Ӵս16 ֽ} - - TCnMD5Count = array[0..1] of Cardinal; - TCnMD5State = array[0..3] of Cardinal; - TCnMD5Block = array[0..15] of Cardinal; - - TCnMD5Buffer = array[0..63] of Byte; - - TCnMD5Context = record - {* MD5 Ľṹ} - State : TCnMD5State; - Count : TCnMD5Count; - Buffer : TCnMD5Buffer; - Ipad : array[0..63] of Byte; {!< HMAC: inner padding } - Opad : array[0..63] of Byte; {!< HMAC: outer padding } - end; - - TCnMD5CalcProgressFunc = procedure (ATotal, AProgress: Int64; - var Cancel: Boolean) of object; - {* Ȼص¼} - -//---------------------------------------------------------------- -// û API -//---------------------------------------------------------------- - -function MD5(Input: PAnsiChar; ByteLength: Cardinal): TCnMD5Digest; -{* ݿ MD5 㡣 - - - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵTCnMD5Digest - ص MD5 Ӵֵ -} - -function MD5Buffer(const Buffer; Count: Cardinal): TCnMD5Digest; -{* ݿ MD5 㡣 - - - const Buffer - ݿַ - Count: Cardinal - ݿֽڳ - - ֵTCnMD5Digest - ص MD5 Ӵֵ -} - -function MD5Bytes(Data: TBytes): TCnMD5Digest; -{* ֽ MD5 㡣 - - - Data: TBytes - ֽ - - ֵTCnMD5Digest - ص MD5 Ӵֵ -} - -function MD5String(const Str: string): TCnMD5Digest; -{* String ݽ MD5 㡣ע D2009 ϰ汾 string Ϊ UnicodeString - лὫǿת AnsiString м㡣 - - - - const Str: string - ַ - - ֵTCnMD5Digest - ص MD5 Ӵֵ -} - -function MD5StringA(const Str: AnsiString): TCnMD5Digest; -{* AnsiString ݽ MD5 㣬ֱӼڲݣޱ봦 - - - const Str: AnsiString - ַ - - ֵTCnMD5Digest - ص MD5 Ӵֵ -} - -function MD5StringW(const Str: WideString): TCnMD5Digest; -{* WideString ַת MD5 㡣 - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - - ֵTCnMD5Digest - ص MD5 Ӵֵ -} - -{$IFDEF UNICODE} - -function MD5UnicodeString(const Str: string): TCnMD5Digest; -{* UnicodeString ݽֱӵ MD5 㣬ֱӼڲ UTF16 ݣת - - - const Str: string - Ŀַ - - ֵTCnMD5Digest - ص MD5 Ӵֵ -} - -{$ELSE} - -function MD5UnicodeString(const Str: WideString ): TCnMD5Digest; -{* UnicodeString ݽֱӵ MD5 㣬ֱӼڲ UTF16 ݣת - - - - const Str: WideString - Ŀַ - - ֵTCnMD5Digest - ص MD5 Ӵֵ -} - -{$ENDIF} - -function MD5File(const FileName: string; - CallBack: TCnMD5CalcProgressFunc = nil): TCnMD5Digest; -{* ָļݽ MD5 㡣 - - - const FileName: string - ļ - CallBack: TCnMD5CalcProgressFunc - ȻصĬΪ - - ֵTCnMD5Digest - ص MD5 Ӵֵ -} - -function MD5Stream(Stream: TStream; - CallBack: TCnMD5CalcProgressFunc = nil): TCnMD5Digest; -{* ָݽ MD5 㡣 - - - Stream: TStream - - CallBack: TCnMD5CalcProgressFunc - ȻصĬΪ - - ֵTCnMD5Digest - ص MD5 Ӵֵ -} - -// ⲿݽɢ MD5 㣬MD5Update ɶα - -procedure MD5Init(var Context: TCnMD5Context); -{* ʼһ MD5 ģ׼ MD5 - - - var Context: TCnMD5Context - ʼ MD5 - - ֵޣ -} - -procedure MD5Update(var Context: TCnMD5Context; Input: PAnsiChar; ByteLength: Cardinal); -{* ԳʼĶһݽ MD5 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnMD5Context - MD5 - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵޣ -} - -procedure MD5Final(var Context: TCnMD5Context; var Digest: TCnMD5Digest); -{* ּ㣬 MD5 Digest С - - - var Context: TCnMD5Context - MD5 - var Digest: TCnMD5Digest - ص MD5 Ӵֵ - - ֵޣ -} - -function MD5Print(const Digest: TCnMD5Digest): string; -{* ʮƸʽ MD5 Ӵֵ - - - const Digest: TCnMD5Digest - ָ MD5 Ӵֵ - - ֵstring - ʮַ -} - -function MD5Match(const D1: TCnMD5Digest; const D2: TCnMD5Digest): Boolean; -{* Ƚ MD5 ӴֵǷȡ - - - const D1: TCnMD5Digest - Ƚϵ MD5 Ӵֵһ - const D2: TCnMD5Digest - Ƚϵ MD5 Ӵֵ - - ֵBoolean - Ƿ -} - -function MD5DigestToStr(const Digest: TCnMD5Digest): string; -{* MD5 Ӵֱֵת stringÿֽڶӦһַ - - - const Digest: TCnMD5Digest - ת MD5 Ӵֵ - - ֵstring - صַ -} - -procedure MD5Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnMD5Digest); -{* MD5 HMACHash-based Message Authentication Code㣬 - ͨݵļϼԿĸҲмΡ - - - Key: PAnsiChar - MD5 Կݿַ - KeyByteLength: Integer - MD5 Կݿֽڳ - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - var Output: TCnMD5Digest - ص MD5 Ӵֵ - - ֵޣ -} - -implementation - -const - MAX_FILE_SIZE = 512 * 1024 * 1024; - // If file size <= this size (bytes), using Mapping, else stream - - HMAC_MD5_BLOCK_SIZE_BYTE = 64; - HMAC_MD5_OUTPUT_LENGTH_BYTE = 16; - -type - TMD5CBits = array[0..7] of Byte; - -var - PADDING: TCnMD5Buffer = ( - $80, $00, $00, $00, $00, $00, $00, $00, - $00, $00, $00, $00, $00, $00, $00, $00, - $00, $00, $00, $00, $00, $00, $00, $00, - $00, $00, $00, $00, $00, $00, $00, $00, - $00, $00, $00, $00, $00, $00, $00, $00, - $00, $00, $00, $00, $00, $00, $00, $00, - $00, $00, $00, $00, $00, $00, $00, $00, - $00, $00, $00, $00, $00, $00, $00, $00 - ); - -function F(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (X and y) or ((not X) and z); -end; - -function G(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (X and z) or (y and (not z)); -end; - -function H(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := X xor y xor z; -end; - -function I(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := y xor (X or (not z)); -end; - -procedure ROT(var X: Cardinal; N: BYTE); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - X := (X shl N) or (X shr (32 - N)); -end; - -procedure FF(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Inc(A, F(B, C, D) + X + AC); - ROT(A, S); - Inc(A, B); -end; - -procedure GG(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Inc(A, G(B, C, D) + X + AC); - ROT(A, S); - Inc(A, B); -end; - -procedure HH(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Inc(A, H(B, C, D) + X + AC); - ROT(A, S); - Inc(A, B); -end; - -procedure II(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Inc(A, I(B, C, D) + X + AC); - ROT(A, S); - Inc(A, B); -end; - -// Encode Count bytes at Source into (Count / 4) DWORDs at Target -procedure Encode(Source, Target: Pointer; Count: Cardinal); -var - S: PByte; - T: PCardinal; - I: Cardinal; -begin - S := Source; - T := Target; - for I := 1 to Count div 4 do - begin - T^ := S^; - Inc(S); - T^ := T^ or (S^ shl 8); - Inc(S); - T^ := T^ or (S^ shl 16); - Inc(S); - T^ := T^ or (S^ shl 24); - Inc(S); - Inc(T); - end; -end; - -// Decode Count DWORDs at Source into (Count * 4) Bytes at Target -procedure Decode(Source, Target: Pointer; Count: Cardinal); -var - S: PCardinal; - T: PByte; - I: Cardinal; -begin - S := Source; - T := Target; - for I := 1 to Count do - begin - T^ := S^ and $ff; - Inc(T); - T^ := (S^ shr 8) and $ff; - Inc(T); - T^ := (S^ shr 16) and $ff; - Inc(T); - T^ := (S^ shr 24) and $ff; - Inc(T); - Inc(S); - end; -end; - -// Transform State according to first 64 bytes at Buffer -procedure Transform(Buffer: Pointer; var State: TCnMD5State); -var - A, B, C, D: Cardinal; - Block: TCnMD5Block; -begin - Encode(Buffer, @Block, 64); - A := State[0]; - B := State[1]; - C := State[2]; - D := State[3]; - FF (A, B, C, D, Block[ 0], 7, $d76aa478); - FF (D, A, B, C, Block[ 1], 12, $e8c7b756); - FF (C, D, A, B, Block[ 2], 17, $242070db); - FF (B, C, D, A, Block[ 3], 22, $c1bdceee); - FF (A, B, C, D, Block[ 4], 7, $f57c0faf); - FF (D, A, B, C, Block[ 5], 12, $4787c62a); - FF (C, D, A, B, Block[ 6], 17, $a8304613); - FF (B, C, D, A, Block[ 7], 22, $fd469501); - FF (A, B, C, D, Block[ 8], 7, $698098d8); - FF (D, A, B, C, Block[ 9], 12, $8b44f7af); - FF (C, D, A, B, Block[10], 17, $ffff5bb1); - FF (B, C, D, A, Block[11], 22, $895cd7be); - FF (A, B, C, D, Block[12], 7, $6b901122); - FF (D, A, B, C, Block[13], 12, $fd987193); - FF (C, D, A, B, Block[14], 17, $a679438e); - FF (B, C, D, A, Block[15], 22, $49b40821); - GG (A, B, C, D, Block[ 1], 5, $f61e2562); - GG (D, A, B, C, Block[ 6], 9, $c040b340); - GG (C, D, A, B, Block[11], 14, $265e5a51); - GG (B, C, D, A, Block[ 0], 20, $e9b6c7aa); - GG (A, B, C, D, Block[ 5], 5, $d62f105d); - GG (D, A, B, C, Block[10], 9, $2441453); - GG (C, D, A, B, Block[15], 14, $d8a1e681); - GG (B, C, D, A, Block[ 4], 20, $e7d3fbc8); - GG (A, B, C, D, Block[ 9], 5, $21e1cde6); - GG (D, A, B, C, Block[14], 9, $c33707d6); - GG (C, D, A, B, Block[ 3], 14, $f4d50d87); - GG (B, C, D, A, Block[ 8], 20, $455a14ed); - GG (A, B, C, D, Block[13], 5, $a9e3e905); - GG (D, A, B, C, Block[ 2], 9, $fcefa3f8); - GG (C, D, A, B, Block[ 7], 14, $676f02d9); - GG (B, C, D, A, Block[12], 20, $8d2a4c8a); - HH (A, B, C, D, Block[ 5], 4, $fffa3942); - HH (D, A, B, C, Block[ 8], 11, $8771f681); - HH (C, D, A, B, Block[11], 16, $6d9d6122); - HH (B, C, D, A, Block[14], 23, $fde5380c); - HH (A, B, C, D, Block[ 1], 4, $a4beea44); - HH (D, A, B, C, Block[ 4], 11, $4bdecfa9); - HH (C, D, A, B, Block[ 7], 16, $f6bb4b60); - HH (B, C, D, A, Block[10], 23, $bebfbc70); - HH (A, B, C, D, Block[13], 4, $289b7ec6); - HH (D, A, B, C, Block[ 0], 11, $eaa127fa); - HH (C, D, A, B, Block[ 3], 16, $d4ef3085); - HH (B, C, D, A, Block[ 6], 23, $4881d05); - HH (A, B, C, D, Block[ 9], 4, $d9d4d039); - HH (D, A, B, C, Block[12], 11, $e6db99e5); - HH (C, D, A, B, Block[15], 16, $1fa27cf8); - HH (B, C, D, A, Block[ 2], 23, $c4ac5665); - II (A, B, C, D, Block[ 0], 6, $f4292244); - II (D, A, B, C, Block[ 7], 10, $432aff97); - II (C, D, A, B, Block[14], 15, $ab9423a7); - II (B, C, D, A, Block[ 5], 21, $fc93a039); - II (A, B, C, D, Block[12], 6, $655b59c3); - II (D, A, B, C, Block[ 3], 10, $8f0ccc92); - II (C, D, A, B, Block[10], 15, $ffeff47d); - II (B, C, D, A, Block[ 1], 21, $85845dd1); - II (A, B, C, D, Block[ 8], 6, $6fa87e4f); - II (D, A, B, C, Block[15], 10, $fe2ce6e0); - II (C, D, A, B, Block[ 6], 15, $a3014314); - II (B, C, D, A, Block[13], 21, $4e0811a1); - II (A, B, C, D, Block[ 4], 6, $f7537e82); - II (D, A, B, C, Block[11], 10, $bd3af235); - II (C, D, A, B, Block[ 2], 15, $2ad7d2bb); - II (B, C, D, A, Block[ 9], 21, $eb86d391); - Inc(State[0], A); - Inc(State[1], B); - Inc(State[2], C); - Inc(State[3], D); -end; - -// Initialize given Context -procedure MD5Init(var Context: TCnMD5Context); -begin - with Context do - begin - State[0] := $67452301; - State[1] := $EFCDAB89; - State[2] := $98BADCFE; - State[3] := $10325476; - Count[0] := 0; - Count[1] := 0; - // ZeroMemory(@Buffer, SizeOf(TMD5Buffer)); - FillChar(Buffer, SizeOf(TCnMD5Buffer), 0); - end; -end; - -// Update given Context to include Length bytes of Input -procedure MD5Update(var Context: TCnMD5Context; Input: PAnsiChar; ByteLength: Cardinal); -var - Index: Cardinal; - PartLen: Cardinal; - I: Cardinal; -begin - with Context do - begin - Index := (Count[0] shr 3) and $3F; - Inc(Count[0], ByteLength shl 3); - if Count[0] < (ByteLength shl 3) then Inc(Count[1]); - Inc(Count[1], ByteLength shr 29); - end; - - PartLen := 64 - Index; - if ByteLength >= PartLen then - begin - Move(Input^, Context.Buffer[Index], PartLen); - Transform(@Context.Buffer, Context.State); - I := PartLen; - while I + 63 < ByteLength do - begin - Transform(@Input[I], Context.State); - Inc(I, 64); - end; - Index := 0; - end - else - I := 0; - - Move(Input[I], Context.Buffer[Index], ByteLength - I); -end; - -procedure MD5UpdateW(var Context: TCnMD5Context; Input: PWideChar; CharLength: Cardinal); -var -{$IFDEF MSWINDOWS} - pContent: PAnsiChar; - iLen: Cardinal; -{$ELSE} - S: string; // UnicodeString - A: AnsiString; -{$ENDIF} -begin -{$IFDEF MSWINDOWS} - GetMem(pContent, CharLength * SizeOf(WideChar)); - try - iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 - PAnsiChar(pContent), CharLength * SizeOf(WideChar), nil, nil); - MD5Update(Context, pContent, iLen); - finally - FreeMem(pContent); - end; -{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ - S := StrNew(Input); - A := AnsiString(S); - MD5Update(Context, @A[1], Length(A)); -{$ENDIF} -end; - -// Finalize given Context, create Digest -procedure MD5Final(var Context: TCnMD5Context; var Digest: TCnMD5Digest); -var - Bits: TMD5CBits; - Index: Cardinal; - PadLen: Cardinal; -begin - Decode(@Context.Count, @Bits, 2); - Index := (Context.Count[0] shr 3) and $3f; - if Index < 56 then - PadLen := 56 - Index - else - PadLen := 120 - Index; - MD5Update(Context, @PADDING, PadLen); - MD5Update(Context, @Bits, 8); - Decode(@Context.State, @Digest, 4); -end; - -function InternalMD5Stream(Stream: TStream; const BufSize: Cardinal; var D: - TCnMD5Digest; CallBack: TCnMD5CalcProgressFunc = nil): Boolean; -var - Context: TCnMD5Context; - Buf: PAnsiChar; - BufLen: Cardinal; - Size: Int64; - ReadBytes: Cardinal; - TotalBytes: Int64; - SavePos: Int64; - CancelCalc: Boolean; -begin - Result := False; - Size := Stream.Size; - if Size = 0 then - Exit; - - SavePos := Stream.Position; - TotalBytes := 0; - - if Size < BufSize then - BufLen := Size - else - BufLen := BufSize; - - CancelCalc := False; - MD5Init(Context); - GetMem(Buf, BufLen); - try - Stream.Position := 0; - repeat - ReadBytes := Stream.Read(Buf^, BufLen); - if ReadBytes <> 0 then - begin - Inc(TotalBytes, ReadBytes); - MD5Update(Context, Buf, ReadBytes); - if Assigned(CallBack) then - begin - CallBack(Size, TotalBytes, CancelCalc); - if CancelCalc then Exit; - end; - end; - until (ReadBytes = 0) or (TotalBytes = Size); - MD5Final(Context, D); - Result := True; - finally - FreeMem(Buf, BufLen); - Stream.Position := SavePos; - end; -end; - -// ݿ MD5 -function MD5(Input: PAnsiChar; ByteLength: Cardinal): TCnMD5Digest; -var - Context: TCnMD5Context; -begin - MD5Init(Context); - MD5Update(Context, Input, ByteLength); - MD5Final(Context, Result); -end; - -// ݿ MD5 -function MD5Buffer(const Buffer; Count: Cardinal): TCnMD5Digest; -var - Context: TCnMD5Context; -begin - MD5Init(Context); - MD5Update(Context, PAnsiChar(Buffer), Count); - MD5Final(Context, Result); -end; - -function MD5Bytes(Data: TBytes): TCnMD5Digest; -var - Context: TCnMD5Context; -begin - MD5Init(Context); - MD5Update(Context, PAnsiChar(@Data[0]), Length(Data)); - MD5Final(Context, Result); -end; - -// String ݽ MD5 -function MD5String(const Str: string): TCnMD5Digest; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := MD5StringA(AStr); -end; - -// AnsiString ݽ MD5 -function MD5StringA(const Str: AnsiString): TCnMD5Digest; -var - Context: TCnMD5Context; -begin - MD5Init(Context); - MD5Update(Context, PAnsiChar(Str), Length(Str)); - MD5Final(Context, Result); -end; - -// WideString ݽ MD5 -function MD5StringW(const Str: WideString): TCnMD5Digest; -var - Context: TCnMD5Context; -begin - MD5Init(Context); - MD5UpdateW(Context, PWideChar(Str), Length(Str)); - MD5Final(Context, Result); -end; - -// UnicodeString ݽֱӵ MD5 㣬ת -{$IFDEF UNICODE} -function MD5UnicodeString(const Str: string): TCnMD5Digest; -{$ELSE} -function MD5UnicodeString(const Str: WideString): TCnMD5Digest; -{$ENDIF} -var - Context: TCnMD5Context; -begin - MD5Init(Context); - MD5Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - MD5Final(Context, Result); -end; - -// ָļݽ MD5 -function MD5File(const FileName: string; - CallBack: TCnMD5CalcProgressFunc): TCnMD5Digest; -var -{$IFDEF MSWINDOWS} - FileHandle: THandle; - MapHandle: THandle; - ViewPointer: Pointer; - Context: TCnMD5Context; -{$ENDIF} - Stream: TStream; - FileIsZeroSize: Boolean; - - function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; -{$IFDEF MSWINDOWS} - var - H: THandle; - Info: BY_HANDLE_FILE_INFORMATION; - Rec : Int64Rec; -{$ENDIF} - begin -{$IFDEF MSWINDOWS} - Result := False; - IsEmpty := False; - H := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); - if H = INVALID_HANDLE_VALUE then Exit; - try - if not GetFileInformationByHandle(H, Info) then Exit; - finally - CloseHandle(H); - end; - Rec.Lo := Info.nFileSizeLow; - Rec.Hi := Info.nFileSizeHigh; - Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); - IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); -{$ELSE} - Result := True; // Windows ƽ̨ Trueʾ Mapping -{$ENDIF} - end; - -begin - FileIsZeroSize := False; - if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then - begin - // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ - Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try - InternalMD5Stream(Stream, 4096 * 1024, Result, CallBack); - finally - Stream.Free; - end; - end - else - begin -{$IFDEF MSWINDOWS} - MD5Init(Context); - FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or - FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or - FILE_FLAG_SEQUENTIAL_SCAN, 0); - if FileHandle <> INVALID_HANDLE_VALUE then - begin - try - MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); - if MapHandle <> 0 then - begin - try - ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); - if ViewPointer <> nil then - begin - try - MD5Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); - finally - UnmapViewOfFile(ViewPointer); - end; - end - else - begin - raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); - end; - finally - CloseHandle(MapHandle); - end; - end - else - begin - if not FileIsZeroSize then - raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); - end; - finally - CloseHandle(FileHandle); - end; - end; - MD5Final(Context, Result); -{$ENDIF} - end; -end; - -// ָ MD5 -function MD5Stream(Stream: TStream; - CallBack: TCnMD5CalcProgressFunc = nil): TCnMD5Digest; -begin - InternalMD5Stream(Stream, 4096 * 1024, Result, CallBack); -end; - -// ʮƸʽ MD5 Ӵֵ -function MD5Print(const Digest: TCnMD5Digest): string; -begin - Result := DataToHex(@Digest[0], SizeOf(TCnMD5Digest)); -end; - -// Ƚ MD5 ӴֵǷ -function MD5Match(const D1, D2: TCnMD5Digest): Boolean; -begin - Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnMD5Digest)); -end; - -// MD5 Ӵֵת string -function MD5DigestToStr(const Digest: TCnMD5Digest): string; -begin - Result := MemoryToString(@Digest[0], SizeOf(TCnMD5Digest)); -end; - -procedure MD5HmacInit(var Ctx: TCnMD5Context; Key: PAnsiChar; KeyLength: Integer); -var - I: Integer; - Sum: TCnMD5Digest; -begin - if KeyLength > HMAC_MD5_BLOCK_SIZE_BYTE then - begin - Sum := MD5Buffer(Key, KeyLength); - KeyLength := HMAC_MD5_OUTPUT_LENGTH_BYTE; - Key := @(Sum[0]); - end; - - FillChar(Ctx.Ipad, HMAC_MD5_BLOCK_SIZE_BYTE, $36); - FillChar(Ctx.Opad, HMAC_MD5_BLOCK_SIZE_BYTE, $5C); - - for I := 0 to KeyLength - 1 do - begin - Ctx.Ipad[I] := Byte(Ctx.Ipad[I] xor Byte(Key[I])); - Ctx.Opad[I] := Byte(Ctx.Opad[I] xor Byte(Key[I])); - end; - - MD5Init(Ctx); - MD5Update(Ctx, @(Ctx.Ipad[0]), HMAC_MD5_BLOCK_SIZE_BYTE); -end; - -procedure MD5HmacUpdate(var Ctx: TCnMD5Context; Input: PAnsiChar; Length: Cardinal); -begin - MD5Update(Ctx, Input, Length); -end; - -procedure MD5HmacFinal(var Ctx: TCnMD5Context; var Output: TCnMD5Digest); -var - Len: Integer; - TmpBuf: TCnMD5Digest; -begin - Len := HMAC_MD5_OUTPUT_LENGTH_BYTE; - MD5Final(Ctx, TmpBuf); - MD5Init(Ctx); - MD5Update(Ctx, @(Ctx.Opad[0]), HMAC_MD5_BLOCK_SIZE_BYTE); - MD5Update(Ctx, @(TmpBuf[0]), Len); - MD5Final(Ctx, Output); -end; - -procedure MD5Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnMD5Digest); -var - Ctx: TCnMD5Context; -begin - MD5HmacInit(Ctx, Key, KeyByteLength); - MD5HmacUpdate(Ctx, Input, ByteLength); - MD5HmacFinal(Ctx, Output); -end; - -end. +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +{******************************************************************************} +{ } +{ MD5 Message-Digest for Delphi 4 } +{ } +{ Delphi 4 Unit implementing the } +{ RSA Data Security, Inc. MD5 Message-Digest Algorithm } +{ } +{ Implementation of Ronald L. Rivest's RFC 1321 } +{ } +{ Copyright ?1997-1999 Medienagentur Fichtner & Meyer } +{ Written by Matthias Fichtner } +{ } +{ -----------------------------------------------------------------------------} +{ See RFC 1321 for RSA Data Security's copyright and license notice! } +{ -----------------------------------------------------------------------------} +{ The latest release of md5.pas will always be available from } +{ the distribution site at: http://www.fichtner.net/delphi/md5/ } +{ -----------------------------------------------------------------------------} +{ Please send questions, bug reports and suggestions } +{ regarding this code to: mfichtner@fichtner-meyer.com } +{ -----------------------------------------------------------------------------} +{ This code is provided "as is" without express or } +{ implied warranty of any kind. Use it at your own risk. } +{******************************************************************************} + +unit CnMD5; +{* |
+================================================================================
+* ƣ
+* ԪƣMD5 Ӵ㷨ʵֵԪ
+* Ԫߣ壨QSoft hq.com@263.net; http://qsoft.51.net
+*            Ronald L. Rivest  MD5.pas дԭʼ
+*     עԪʵ MD5 Ӵ㷨Ӧ HMAC 㷨
+* ƽ̨PWin2000Pro + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2019.12.12 V1.4
+*               ֧ TBytes
+*           2019.04.15 V1.3
+*               ֧ Win32/Win64/MacOS
+*           2014.11.14 V1.2
+*               л Pascal ֿ֧ƽ̨
+*           2003.09.18 V1.1
+*               òҵ˸õԪԭߵİȨ
+*           2003.09.18 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + Classes, SysUtils, CnConsts, CnNative {$IFDEF MSWINDOWS}, Windows {$ENDIF}; + +type + PMD5Digest = ^TCnMD5Digest; + TCnMD5Digest = array[0..15] of Byte; + {* MD5 Ӵս16 ֽ} + + TCnMD5Count = array[0..1] of Cardinal; + TCnMD5State = array[0..3] of Cardinal; + TCnMD5Block = array[0..15] of Cardinal; + + TCnMD5Buffer = array[0..63] of Byte; + + TCnMD5Context = record + {* MD5 Ľṹ} + State : TCnMD5State; + Count : TCnMD5Count; + Buffer : TCnMD5Buffer; + Ipad : array[0..63] of Byte; {!< HMAC: inner padding } + Opad : array[0..63] of Byte; {!< HMAC: outer padding } + end; + + TCnMD5CalcProgressFunc = procedure (ATotal, AProgress: Int64; + var Cancel: Boolean) of object; + {* Ȼص¼} + +//---------------------------------------------------------------- +// û API +//---------------------------------------------------------------- + +function MD5(Input: PAnsiChar; ByteLength: Cardinal): TCnMD5Digest; +{* ݿ MD5 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5Buffer(const Buffer; Count: Cardinal): TCnMD5Digest; +{* ݿ MD5 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5Bytes(Data: TBytes): TCnMD5Digest; +{* ֽ MD5 㡣 + + + Data: TBytes - ֽ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5String(const Str: string): TCnMD5Digest; +{* String ݽ MD5 㡣ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + + const Str: string - ַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5StringA(const Str: AnsiString): TCnMD5Digest; +{* AnsiString ݽ MD5 㣬ֱӼڲݣޱ봦 + + + const Str: AnsiString - ַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5StringW(const Str: WideString): TCnMD5Digest; +{* WideString ַת MD5 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +{$IFDEF UNICODE} + +function MD5UnicodeString(const Str: string): TCnMD5Digest; +{* UnicodeString ݽֱӵ MD5 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +{$ELSE} + +function MD5UnicodeString(const Str: WideString ): TCnMD5Digest; +{* UnicodeString ݽֱӵ MD5 㣬ֱӼڲ UTF16 ݣת + + + + const Str: WideString - Ŀַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +{$ENDIF} + +function MD5File(const FileName: string; + CallBack: TCnMD5CalcProgressFunc = nil): TCnMD5Digest; +{* ָļݽ MD5 㡣 + + + const FileName: string - ļ + CallBack: TCnMD5CalcProgressFunc - ȻصĬΪ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5Stream(Stream: TStream; + CallBack: TCnMD5CalcProgressFunc = nil): TCnMD5Digest; +{* ָݽ MD5 㡣 + + + Stream: TStream - + CallBack: TCnMD5CalcProgressFunc - ȻصĬΪ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +// ⲿݽɢ MD5 㣬MD5Update ɶα + +procedure MD5Init(var Context: TCnMD5Context); +{* ʼһ MD5 ģ׼ MD5 + + + var Context: TCnMD5Context - ʼ MD5 + + ֵޣ +} + +procedure MD5Update(var Context: TCnMD5Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ MD5 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnMD5Context - MD5 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure MD5Final(var Context: TCnMD5Context; var Digest: TCnMD5Digest); +{* ּ㣬 MD5 Digest С + + + var Context: TCnMD5Context - MD5 + var Digest: TCnMD5Digest - ص MD5 Ӵֵ + + ֵޣ +} + +function MD5Print(const Digest: TCnMD5Digest): string; +{* ʮƸʽ MD5 Ӵֵ + + + const Digest: TCnMD5Digest - ָ MD5 Ӵֵ + + ֵstring - ʮַ +} + +function MD5Match(const D1: TCnMD5Digest; const D2: TCnMD5Digest): Boolean; +{* Ƚ MD5 ӴֵǷȡ + + + const D1: TCnMD5Digest - Ƚϵ MD5 Ӵֵһ + const D2: TCnMD5Digest - Ƚϵ MD5 Ӵֵ + + ֵBoolean - Ƿ +} + +function MD5DigestToStr(const Digest: TCnMD5Digest): string; +{* MD5 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnMD5Digest - ת MD5 Ӵֵ + + ֵstring - صַ +} + +procedure MD5Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnMD5Digest); +{* MD5 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - MD5 Կݿַ + KeyByteLength: Integer - MD5 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnMD5Digest - ص MD5 Ӵֵ + + ֵޣ +} + +implementation + +const + MAX_FILE_SIZE = 512 * 1024 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + HMAC_MD5_BLOCK_SIZE_BYTE = 64; + HMAC_MD5_OUTPUT_LENGTH_BYTE = 16; + +type + TMD5CBits = array[0..7] of Byte; + +var + PADDING: TCnMD5Buffer = ( + $80, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00 + ); + +function F(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and y) or ((not X) and z); +end; + +function G(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and z) or (y and (not z)); +end; + +function H(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor y xor z; +end; + +function I(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := y xor (X or (not z)); +end; + +procedure ROT(var X: Cardinal; N: BYTE); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + X := (X shl N) or (X shr (32 - N)); +end; + +procedure FF(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Inc(A, F(B, C, D) + X + AC); + ROT(A, S); + Inc(A, B); +end; + +procedure GG(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Inc(A, G(B, C, D) + X + AC); + ROT(A, S); + Inc(A, B); +end; + +procedure HH(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Inc(A, H(B, C, D) + X + AC); + ROT(A, S); + Inc(A, B); +end; + +procedure II(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Inc(A, I(B, C, D) + X + AC); + ROT(A, S); + Inc(A, B); +end; + +// Encode Count bytes at Source into (Count / 4) DWORDs at Target +procedure Encode(Source, Target: Pointer; Count: Cardinal); +var + S: PByte; + T: PCardinal; + I: Cardinal; +begin + S := Source; + T := Target; + for I := 1 to Count div 4 do + begin + T^ := S^; + Inc(S); + T^ := T^ or (S^ shl 8); + Inc(S); + T^ := T^ or (S^ shl 16); + Inc(S); + T^ := T^ or (S^ shl 24); + Inc(S); + Inc(T); + end; +end; + +// Decode Count DWORDs at Source into (Count * 4) Bytes at Target +procedure Decode(Source, Target: Pointer; Count: Cardinal); +var + S: PCardinal; + T: PByte; + I: Cardinal; +begin + S := Source; + T := Target; + for I := 1 to Count do + begin + T^ := S^ and $ff; + Inc(T); + T^ := (S^ shr 8) and $ff; + Inc(T); + T^ := (S^ shr 16) and $ff; + Inc(T); + T^ := (S^ shr 24) and $ff; + Inc(T); + Inc(S); + end; +end; + +// Transform State according to first 64 bytes at Buffer +procedure Transform(Buffer: Pointer; var State: TCnMD5State); +var + A, B, C, D: Cardinal; + Block: TCnMD5Block; +begin + Encode(Buffer, @Block, 64); + A := State[0]; + B := State[1]; + C := State[2]; + D := State[3]; + FF (A, B, C, D, Block[ 0], 7, $d76aa478); + FF (D, A, B, C, Block[ 1], 12, $e8c7b756); + FF (C, D, A, B, Block[ 2], 17, $242070db); + FF (B, C, D, A, Block[ 3], 22, $c1bdceee); + FF (A, B, C, D, Block[ 4], 7, $f57c0faf); + FF (D, A, B, C, Block[ 5], 12, $4787c62a); + FF (C, D, A, B, Block[ 6], 17, $a8304613); + FF (B, C, D, A, Block[ 7], 22, $fd469501); + FF (A, B, C, D, Block[ 8], 7, $698098d8); + FF (D, A, B, C, Block[ 9], 12, $8b44f7af); + FF (C, D, A, B, Block[10], 17, $ffff5bb1); + FF (B, C, D, A, Block[11], 22, $895cd7be); + FF (A, B, C, D, Block[12], 7, $6b901122); + FF (D, A, B, C, Block[13], 12, $fd987193); + FF (C, D, A, B, Block[14], 17, $a679438e); + FF (B, C, D, A, Block[15], 22, $49b40821); + GG (A, B, C, D, Block[ 1], 5, $f61e2562); + GG (D, A, B, C, Block[ 6], 9, $c040b340); + GG (C, D, A, B, Block[11], 14, $265e5a51); + GG (B, C, D, A, Block[ 0], 20, $e9b6c7aa); + GG (A, B, C, D, Block[ 5], 5, $d62f105d); + GG (D, A, B, C, Block[10], 9, $2441453); + GG (C, D, A, B, Block[15], 14, $d8a1e681); + GG (B, C, D, A, Block[ 4], 20, $e7d3fbc8); + GG (A, B, C, D, Block[ 9], 5, $21e1cde6); + GG (D, A, B, C, Block[14], 9, $c33707d6); + GG (C, D, A, B, Block[ 3], 14, $f4d50d87); + GG (B, C, D, A, Block[ 8], 20, $455a14ed); + GG (A, B, C, D, Block[13], 5, $a9e3e905); + GG (D, A, B, C, Block[ 2], 9, $fcefa3f8); + GG (C, D, A, B, Block[ 7], 14, $676f02d9); + GG (B, C, D, A, Block[12], 20, $8d2a4c8a); + HH (A, B, C, D, Block[ 5], 4, $fffa3942); + HH (D, A, B, C, Block[ 8], 11, $8771f681); + HH (C, D, A, B, Block[11], 16, $6d9d6122); + HH (B, C, D, A, Block[14], 23, $fde5380c); + HH (A, B, C, D, Block[ 1], 4, $a4beea44); + HH (D, A, B, C, Block[ 4], 11, $4bdecfa9); + HH (C, D, A, B, Block[ 7], 16, $f6bb4b60); + HH (B, C, D, A, Block[10], 23, $bebfbc70); + HH (A, B, C, D, Block[13], 4, $289b7ec6); + HH (D, A, B, C, Block[ 0], 11, $eaa127fa); + HH (C, D, A, B, Block[ 3], 16, $d4ef3085); + HH (B, C, D, A, Block[ 6], 23, $4881d05); + HH (A, B, C, D, Block[ 9], 4, $d9d4d039); + HH (D, A, B, C, Block[12], 11, $e6db99e5); + HH (C, D, A, B, Block[15], 16, $1fa27cf8); + HH (B, C, D, A, Block[ 2], 23, $c4ac5665); + II (A, B, C, D, Block[ 0], 6, $f4292244); + II (D, A, B, C, Block[ 7], 10, $432aff97); + II (C, D, A, B, Block[14], 15, $ab9423a7); + II (B, C, D, A, Block[ 5], 21, $fc93a039); + II (A, B, C, D, Block[12], 6, $655b59c3); + II (D, A, B, C, Block[ 3], 10, $8f0ccc92); + II (C, D, A, B, Block[10], 15, $ffeff47d); + II (B, C, D, A, Block[ 1], 21, $85845dd1); + II (A, B, C, D, Block[ 8], 6, $6fa87e4f); + II (D, A, B, C, Block[15], 10, $fe2ce6e0); + II (C, D, A, B, Block[ 6], 15, $a3014314); + II (B, C, D, A, Block[13], 21, $4e0811a1); + II (A, B, C, D, Block[ 4], 6, $f7537e82); + II (D, A, B, C, Block[11], 10, $bd3af235); + II (C, D, A, B, Block[ 2], 15, $2ad7d2bb); + II (B, C, D, A, Block[ 9], 21, $eb86d391); + Inc(State[0], A); + Inc(State[1], B); + Inc(State[2], C); + Inc(State[3], D); +end; + +// Initialize given Context +procedure MD5Init(var Context: TCnMD5Context); +begin + with Context do + begin + State[0] := $67452301; + State[1] := $EFCDAB89; + State[2] := $98BADCFE; + State[3] := $10325476; + Count[0] := 0; + Count[1] := 0; + // ZeroMemory(@Buffer, SizeOf(TMD5Buffer)); + FillChar(Buffer, SizeOf(TCnMD5Buffer), 0); + end; +end; + +// Update given Context to include Length bytes of Input +procedure MD5Update(var Context: TCnMD5Context; Input: PAnsiChar; ByteLength: Cardinal); +var + Index: Cardinal; + PartLen: Cardinal; + I: Cardinal; +begin + with Context do + begin + Index := (Count[0] shr 3) and $3F; + Inc(Count[0], ByteLength shl 3); + if Count[0] < (ByteLength shl 3) then Inc(Count[1]); + Inc(Count[1], ByteLength shr 29); + end; + + PartLen := 64 - Index; + if ByteLength >= PartLen then + begin + Move(Input^, Context.Buffer[Index], PartLen); + Transform(@Context.Buffer, Context.State); + I := PartLen; + while I + 63 < ByteLength do + begin + Transform(@Input[I], Context.State); + Inc(I, 64); + end; + Index := 0; + end + else + I := 0; + + Move(Input[I], Context.Buffer[Index], ByteLength - I); +end; + +procedure MD5UpdateW(var Context: TCnMD5Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + pContent: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(pContent, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(pContent), CharLength * SizeOf(WideChar), nil, nil); + MD5Update(Context, pContent, iLen); + finally + FreeMem(pContent); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + MD5Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +// Finalize given Context, create Digest +procedure MD5Final(var Context: TCnMD5Context; var Digest: TCnMD5Digest); +var + Bits: TMD5CBits; + Index: Cardinal; + PadLen: Cardinal; +begin + Decode(@Context.Count, @Bits, 2); + Index := (Context.Count[0] shr 3) and $3f; + if Index < 56 then + PadLen := 56 - Index + else + PadLen := 120 - Index; + MD5Update(Context, @PADDING, PadLen); + MD5Update(Context, @Bits, 8); + Decode(@Context.State, @Digest, 4); +end; + +function InternalMD5Stream(Stream: TStream; const BufSize: Cardinal; var D: + TCnMD5Digest; CallBack: TCnMD5CalcProgressFunc = nil): Boolean; +var + Context: TCnMD5Context; + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; +begin + Result := False; + Size := Stream.Size; + if Size = 0 then + Exit; + + SavePos := Stream.Position; + TotalBytes := 0; + + if Size < BufSize then + BufLen := Size + else + BufLen := BufSize; + + CancelCalc := False; + MD5Init(Context); + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + MD5Update(Context, Buf, ReadBytes); + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + MD5Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ݿ MD5 +function MD5(Input: PAnsiChar; ByteLength: Cardinal): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, Input, ByteLength); + MD5Final(Context, Result); +end; + +// ݿ MD5 +function MD5Buffer(const Buffer; Count: Cardinal): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, PAnsiChar(Buffer), Count); + MD5Final(Context, Result); +end; + +function MD5Bytes(Data: TBytes): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, PAnsiChar(@Data[0]), Length(Data)); + MD5Final(Context, Result); +end; + +// String ݽ MD5 +function MD5String(const Str: string): TCnMD5Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := MD5StringA(AStr); +end; + +// AnsiString ݽ MD5 +function MD5StringA(const Str: AnsiString): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, PAnsiChar(Str), Length(Str)); + MD5Final(Context, Result); +end; + +// WideString ݽ MD5 +function MD5StringW(const Str: WideString): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5UpdateW(Context, PWideChar(Str), Length(Str)); + MD5Final(Context, Result); +end; + +// UnicodeString ݽֱӵ MD5 㣬ת +{$IFDEF UNICODE} +function MD5UnicodeString(const Str: string): TCnMD5Digest; +{$ELSE} +function MD5UnicodeString(const Str: WideString): TCnMD5Digest; +{$ENDIF} +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + MD5Final(Context, Result); +end; + +// ָļݽ MD5 +function MD5File(const FileName: string; + CallBack: TCnMD5CalcProgressFunc): TCnMD5Digest; +var +{$IFDEF MSWINDOWS} + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; + Context: TCnMD5Context; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; + + function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} + var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec : Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then Exit; + try + if not GetFileInformationByHandle(H, Info) then Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} + end; + +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalMD5Stream(Stream, 4096 * 1024, Result, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + MD5Init(Context); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + MD5Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + MD5Final(Context, Result); +{$ENDIF} + end; +end; + +// ָ MD5 +function MD5Stream(Stream: TStream; + CallBack: TCnMD5CalcProgressFunc = nil): TCnMD5Digest; +begin + InternalMD5Stream(Stream, 4096 * 1024, Result, CallBack); +end; + +// ʮƸʽ MD5 Ӵֵ +function MD5Print(const Digest: TCnMD5Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnMD5Digest)); +end; + +// Ƚ MD5 ӴֵǷ +function MD5Match(const D1, D2: TCnMD5Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnMD5Digest)); +end; + +// MD5 Ӵֵת string +function MD5DigestToStr(const Digest: TCnMD5Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnMD5Digest)); +end; + +procedure MD5HmacInit(var Ctx: TCnMD5Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnMD5Digest; +begin + if KeyLength > HMAC_MD5_BLOCK_SIZE_BYTE then + begin + Sum := MD5Buffer(Key, KeyLength); + KeyLength := HMAC_MD5_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Ctx.Ipad, HMAC_MD5_BLOCK_SIZE_BYTE, $36); + FillChar(Ctx.Opad, HMAC_MD5_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Ctx.Ipad[I] := Byte(Ctx.Ipad[I] xor Byte(Key[I])); + Ctx.Opad[I] := Byte(Ctx.Opad[I] xor Byte(Key[I])); + end; + + MD5Init(Ctx); + MD5Update(Ctx, @(Ctx.Ipad[0]), HMAC_MD5_BLOCK_SIZE_BYTE); +end; + +procedure MD5HmacUpdate(var Ctx: TCnMD5Context; Input: PAnsiChar; Length: Cardinal); +begin + MD5Update(Ctx, Input, Length); +end; + +procedure MD5HmacFinal(var Ctx: TCnMD5Context; var Output: TCnMD5Digest); +var + Len: Integer; + TmpBuf: TCnMD5Digest; +begin + Len := HMAC_MD5_OUTPUT_LENGTH_BYTE; + MD5Final(Ctx, TmpBuf); + MD5Init(Ctx); + MD5Update(Ctx, @(Ctx.Opad[0]), HMAC_MD5_BLOCK_SIZE_BYTE); + MD5Update(Ctx, @(TmpBuf[0]), Len); + MD5Final(Ctx, Output); +end; + +procedure MD5Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnMD5Digest); +var + Ctx: TCnMD5Context; +begin + MD5HmacInit(Ctx, Key, KeyByteLength); + MD5HmacUpdate(Ctx, Input, ByteLength); + MD5HmacFinal(Ctx, Output); +end; + +end. diff --git a/CnPack/Crypto/CnNative.pas b/CnPack/Crypto/CnNative.pas index 972f9e4..c863fdc 100644 --- a/CnPack/Crypto/CnNative.pas +++ b/CnPack/Crypto/CnNative.pas @@ -1,4904 +1,4904 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -unit CnNative; -{* |
-================================================================================
-* ƣCnPack 
-* Ԫƣ32 λ 64 λƽ̨һЩͳһԼһʵֵԪ
-* ԪߣCnPack  (master@cnpack.org)
-*     עԪһ 32 λ 64 λƽ̨һЩͳһʵ֡
-*           Delphi XE 2 ֧ 32  64 ų NativeInt  NativeUInt 
-*           ǰ 32 λ 64 ̬仯Ӱ쵽 PointerReferenceȶ
-*           ǵԣ̶ȵ 32 λ Cardinal/Integer Ⱥ Pointer Щ
-*           ͨˣʹ 32 λҲֹ˱Ԫ˼ͣ
-*           ͬʱڵͰ汾͸߰汾 Delphi ʹá
-*
-*           ԪҲڲ֧ UInt64 ı Delphi 5/6/7  Int64 ģ UInt64
-*           ĸ㣬ӼȻ֧֣˳Ҫģ div  mod
-*           ַ Integer(APtr)  64 λ MacOS ׳ֽضϣҪ NativeInt
-*
-*           ʵ˴Сءֽת̶ʱȷĴײ㺯빤ࡣ
-*
-* ƽ̨PWin2000 + Delphi 5.0
-* ݲԣPWin9X/2000/XP + Delphi 5/6/7 XE 2
-*   õԪеַϱػʽ
-* ޸ļ¼2023.08.14 V2.4
-*               ϼʱ̶ĺ
-*           2022.11.11 V2.3
-*               ϼ޷ֽ˳
-*           2022.07.23 V2.2
-*               Ӽڴλ㺯תַΪ CnNative
-*           2022.06.08 V2.1
-*               ĸʱ̶ĽԼڴ浹ź
-*           2022.03.14 V2.0
-*               Ӽʮת
-*           2022.02.17 V1.9
-*                FPC ı֧
-*           2022.02.09 V1.8
-*               ڵĴСжϺ
-*           2021.09.05 V1.7
-*                Int64/UInt64 㺯
-*           2020.10.28 V1.6
-*                UInt64 صж㺯
-*           2020.09.06 V1.5
-*                UInt64 ƽĺ
-*           2020.07.01 V1.5
-*               ж 32 λ 64 λ޷Ƿĺ
-*           2020.06.20 V1.4
-*                32 λ 64 λȡ͵ 1 λλõĺ
-*           2020.01.01 V1.3
-*                32 λ޷͵ mul 㣬ڲ֧ UInt64 ϵͳ Int64 Ա
-*           2018.06.05 V1.2
-*                64 λ͵ div/mod 㣬ڲ֧ UInt64 ϵͳ Int64  
-*           2016.09.27 V1.1
-*                64 λ͵һЩ
-*           2011.07.06 V1.0
-*               Ԫʵֹ
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - Classes, SysUtils, SysConst, Math {$IFDEF COMPILER5}, Windows {$ENDIF}; - // D5 Ҫ Windows е PByte -type - ECnNativeException = class(Exception); - {* Native 쳣} - -{$IFDEF COMPILER5} - PCardinal = ^Cardinal; - {* D5 System Ԫδ壬} - PByte = Windows.PByte; - {* D5 PByte Windows У汾 System У - ͳһһ¹ʹ PByte ʱ uses Windowsڿƽ̨} -{$ENDIF} - -{$IFDEF BCB5OR6} - PInt64 = ^Int64; - {* C++Builder 5/6 sysmac.h û PInt64 Ķ壨е PUINT64 Сдͬ㣩} -{$ENDIF} - -{$IFDEF SUPPORT_32_AND_64} - TCnNativeInt = NativeInt; - TCnNativeUInt = NativeUInt; - TCnNativePointer = NativeInt; - TCnNativeIntPtr = PNativeInt; - TCnNativeUIntPtr = PNativeUInt; -{$ELSE} - TCnNativeInt = Integer; - TCnNativeUInt = Cardinal; - TCnNativePointer = Integer; - TCnNativeIntPtr = PInteger; - TCnNativeUIntPtr = PCardinal; -{$ENDIF} - -{$IFDEF CPU64BITS} - TCnUInt64 = NativeUInt; - TCnInt64 = NativeInt; -{$ELSE} - {$IFDEF SUPPORT_UINT64} - TCnUInt64 = UInt64; - {$ELSE} - TCnUInt64 = packed record // ֻĽṹ - case Boolean of - True: (Value: Int64); - False: (Lo32, Hi32: Cardinal); - end; - {$ENDIF} - TCnInt64 = Int64; -{$ENDIF} - -// TUInt64 cnvcl в֧ UInt64 div mod -{$IFDEF SUPPORT_UINT64} - TUInt64 = UInt64; - {$IFNDEF SUPPORT_PUINT64} - PUInt64 = ^UInt64; - {$ENDIF} -{$ELSE} - TUInt64 = Int64; - PUInt64 = ^TUInt64; -{$ENDIF} - -{$IFNDEF SUPPORT_INT64ARRAY} - // ϵͳûж Int64Array - Int64Array = array[0..$0FFFFFFE] of Int64; - PInt64Array = ^Int64Array; -{$ENDIF} - - TUInt64Array = array of TUInt64; // ̬ƺ׺;̬гͻ - - ExtendedArray = array[0..65537] of Extended; - PExtendedArray = ^ExtendedArray; - - PCnWord16Array = ^TCnWord16Array; - TCnWord16Array = array [0..0] of Word; - -{$IFDEF POSIX64} - TCnLongWord32 = Cardinal; // Linux64/MacOS64 (or POSIX64?) LongWord is 64 Bits -{$ELSE} - TCnLongWord32 = LongWord; -{$ENDIF} - PCnLongWord32 = ^TCnLongWord32; - - TCnLongWord32Array = array [0..MaxInt div SizeOf(Integer) - 1] of TCnLongWord32; - - PCnLongWord32Array = ^TCnLongWord32Array; - -{$IFNDEF TBYTES_DEFINED} - TBytes = array of Byte; - {* ޷ֽڶ̬飬δʱ} -{$ENDIF} - - TShortInts = array of ShortInt; - {* зֽڶ̬} - - TSmallInts = array of SmallInt; - {* з˫ֽڶ̬} - - TWords = array of Word; - {* ޷˫ֽڶ̬} - - TIntegers = array of Integer; - {* зֽڶ̬} - - TCardinals = array of Cardinal; - {* ޷ֽڶ̬} - - PCnByte = ^Byte; - PCnWord = ^Word; - - TCnBitOperation = (boAnd, boOr, boXor, boNot); - {* λ} - -type - TCnMemSortCompareProc = function (P1, P2: Pointer; ElementByteSize: Integer): Integer; - {* ڴ̶ߴȽϺԭ} - -const - CN_MAX_SQRT_INT64: Cardinal = 3037000499; - CN_MAX_INT8: ShortInt = $7F; - CN_MIN_INT8: ShortInt = -128; - CN_MAX_INT16: SmallInt = $7FFF; - CN_MIN_INT16: SmallInt = -32768; - CN_MAX_INT32: Integer = $7FFFFFFF; - CN_MIN_INT32: Integer = $80000000; // 뾯棬 -2147483648 - CN_MIN_INT32_IN_INT64: Int64 = $0000000080000000; - CN_MAX_INT64: Int64 = $7FFFFFFFFFFFFFFF; - CN_MIN_INT64: Int64 = $8000000000000000; - CN_MAX_UINT8: Byte = $FF; - CN_MAX_UINT16: Word = $FFFF; - CN_MAX_UINT32: Cardinal = $FFFFFFFF; - CN_MAX_TUINT64: TUInt64 = $FFFFFFFFFFFFFFFF; - CN_MAX_SIGNED_INT64_IN_TUINT64: TUInt64 = $7FFFFFFFFFFFFFFF; - -{* - D567 Ȳ֧ UInt64 ıȻ Int64 UInt64 мӼ洢 - ˳޷ֱɣװ System е _lludiv _llumod - ʵ Int64 ʾ UInt64 ݵ div mod ܡ -} -function UInt64Mod(A: TUInt64; B: TUInt64): TUInt64; -{* 64 λ޷ࡣ - - - A: TUInt64 - - B: TUInt64 - - - ֵTUInt64 - -} - -function UInt64Div(A: TUInt64; B: TUInt64): TUInt64; -{* 64 λ޷ - - - A: TUInt64 - - B: TUInt64 - - - ֵTUInt64 - -} - -function UInt64Mul(A: Cardinal; B: Cardinal): TUInt64; -{* 32 λ޷ˡڲ֧ UInt64 ƽ̨ϣ UInt64 ʽ Int64  - ֱʹ Int64 п - - - A: Cardinal - һ - B: Cardinal - - - ֵTUInt64 - -} - -procedure UInt64AddUInt64(A: TUInt64; B: TUInt64; var ResLo: TUInt64; var ResHi: TUInt64); -{* 64 λ޷ӣ ResLo ResHi С - עڲʵְ㷨ΪӣʵResHi Ȼ 1ֱж 1 - - - A: TUInt64 - һ - B: TUInt64 - - var ResLo: TUInt64 - ͵λ - var ResHi: TUInt64 - ͸λ - - ֵޣ -} - -procedure UInt64MulUInt64(A: TUInt64; B: TUInt64; var ResLo: TUInt64; var ResHi: TUInt64); -{* 64 λ޷ˣ ResLo ResHi СWin 64 λûʵ֣Լһϡ - - - A: TUInt64 - һ - B: TUInt64 - - var ResLo: TUInt64 - λ - var ResHi: TUInt64 - λ - - ֵޣ -} - -function UInt64ToHex(N: TUInt64): string; -{* 64 λ޷תΪʮַ - - - N: TUInt64 - תֵ - - ֵstring - ʮַ -} - -function UInt64ToStr(N: TUInt64): string; -{* 64 λ޷תΪʮַ - - - N: TUInt64 - תֵ - - ֵstring - ʮַ -} - -function StrToUInt64(const S: string): TUInt64; -{* ַתΪ 64 λ޷ - - - const S: string - תַ - - ֵTUInt64 - ת -} - -function UInt64Compare(A: TUInt64; B: TUInt64): Integer; -{* Ƚ 64 λ޷ֱֵݱȽϵĽǴڡڻС 10-1 - - - A: TUInt64 - Ƚϵһ - B: TUInt64 - Ƚϵ - - ֵInteger - رȽϽ -} - -function UInt64Sqrt(N: TUInt64): TUInt64; -{* 64 λ޷ƽ֡ - - - N: TUInt64 - ƽ - - ֵTUInt64 - ƽ -} - -function UInt32IsNegative(N: Cardinal): Boolean; -{* ж 32 λ޷ 32 λзʱǷС 0 - - - N: Cardinal - жϵֵ - - ֵBoolean - ǷС 0 -} - -function UInt64IsNegative(N: TUInt64): Boolean; -{* ж 64 λ޷ 64 λзʱǷС 0 - - - N: TUInt64 - жϵֵ - - ֵBoolean - ǷС 0 -} - -procedure UInt64SetBit(var B: TUInt64; Index: Integer); -{* 64 λijһλ 1λ Index 0 ʼ 63 - - - var B: TUInt64 - λֵ - Index: Integer - 1 λ - - ֵޣ -} - -procedure UInt64ClearBit(var B: TUInt64; Index: Integer); -{* 64 λijһλ 0λ Index 0 ʼ 63 - - - var B: TUInt64 - λֵ - Index: Integer - 0 λ - - ֵޣ -} - -function GetUInt64BitSet(B: TUInt64; Index: Integer): Boolean; -{* 64 λijһλǷ 1λ Index 0 ʼ 63 - - - B: TUInt64 - жϵֵ - Index: Integer - жϵλ - - ֵBoolean - ظλǷ 1 -} - -function GetUInt64HighBits(B: TUInt64): Integer; -{* 64 λ 1 ߶λǵڼλλ 0û 1 -1 - - - B: TUInt64 - жϵֵ - - ֵInteger - 1 λ -} - -function GetUInt32HighBits(B: Cardinal): Integer; -{* 32 λ 1 ߶λǵڼλλ 0û 1 -1 - - - B: Cardinal - жϵֵ - - ֵInteger - 1 λ -} - -function GetUInt16HighBits(B: Word): Integer; -{* 16 λ 1 ߶λǵڼλλ 0û 1 -1 - - - B: Word - жϵֵ - - ֵInteger - 1 λ -} - -function GetUInt8HighBits(B: Byte): Integer; -{* 8 λ 1 ߶λǵڼλλ 0û 1 -1 - - - B: Byte - жϵֵ - - ֵInteger - 1 λ -} - -function GetUInt64LowBits(B: TUInt64): Integer; -{* 64 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 - - - B: TUInt64 - жϵֵ - - ֵInteger - 1 λ -} - -function GetUInt32LowBits(B: Cardinal): Integer; -{* 32 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 - - - B: Cardinal - жϵֵ - - ֵInteger - 1 λ -} - -function GetUInt16LowBits(B: Word): Integer; -{* 16 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 - - - B: Word - жϵֵ - - ֵInteger - 1 λ -} - -function GetUInt8LowBits(B: Byte): Integer; -{* 8 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 - - - B: Byte - жϵֵ - - ֵInteger - 1 λ -} - -function Int64Mod(M: Int64; N: Int64): Int64; -{* װ Int64 ModM ֵʱȡģģ N Ҫס - - - M: Int64 - - N: Int64 - - - ֵInt64 - -} - -function IsUInt32PowerOf2(N: Cardinal): Boolean; -{* жһ 32 λ޷Ƿ 2 ݡ - - - N: Cardinal - жϵֵ - - ֵBoolean - Ƿ 2 -} - -function IsUInt64PowerOf2(N: TUInt64): Boolean; -{* жһ 64 λ޷Ƿ 2 ݡ - - - N: TUInt64 - жϵֵ - - ֵBoolean - Ƿ 2 -} - -function GetUInt32PowerOf2GreaterEqual(N: Cardinal): Cardinal; -{* õһָ 32 λ޷ȵ 2 ݣ򷵻 0 - - - N: Cardinal - ֵ - - ֵCardinal - ط 2 ݻ 0 -} - -function GetUInt64PowerOf2GreaterEqual(N: TUInt64): TUInt64; -{* õһָ 64 λ޷ȵ 2 ݣ򷵻 0 - - - N: TUInt64 - ֵ - - ֵTUInt64 - ط 2 ݻ 0 -} - -function IsInt32AddOverflow(A: Integer; B: Integer): Boolean; -{* ж 32 λзǷ 32 λзޡ - - - A: Integer - һ - B: Integer - - - ֵBoolean - Ƿ -} - -function IsUInt32AddOverflow(A: Cardinal; B: Cardinal): Boolean; -{* ж 32 λ޷Ƿ 32 λ޷ޡ - - - A: Cardinal - һ - B: Cardinal - - - ֵBoolean - Ƿ -} - -function IsInt64AddOverflow(A: Int64; B: Int64): Boolean; -{* ж 64 λзǷ 64 λзޡ - - - A: Int64 - һ - B: Int64 - - - ֵBoolean - Ƿ -} - -function IsUInt64AddOverflow(A: TUInt64; B: TUInt64): Boolean; -{* ж 64 λ޷Ƿ 64 λ޷ޡ - - - A: TUInt64 - һ - B: TUInt64 - - - ֵBoolean - Ƿ -} - -function IsUInt64SubOverflowInt32(A: TUInt64; B: TUInt64): Boolean; -{* жһ 64 λ޷ȥһ 64 λ޷ĽǷ񳬳 32 λзΧ - 64 λе JMP תжϡ - - - A: TUInt64 - - B: TUInt64 - - - ֵBoolean - Ƿ񳬳 32 λзΧ -} - -procedure UInt64Add(var R: TUInt64; A: TUInt64; B: TUInt64; out Carry: Integer); -{* 64 λ޷ӣA + B => R 1 ýλλ㡣 - - - var R: TUInt64 - - A: TUInt64 - һ - B: TUInt64 - - out Carry: Integer - λ - - ֵޣ -} - -procedure UInt64Sub(var R: TUInt64; A: TUInt64; B: TUInt64; out Carry: Integer); -{* 64 λ޷A - B => Rнλ 1 ýλλ㡣 - - - var R: TUInt64 - - A: TUInt64 - - B: TUInt64 - - out Carry: Integer - λ - - ֵޣ -} - -function IsInt32MulOverflow(A: Integer; B: Integer): Boolean; -{* ж 32 λзǷ 32 λзޡ - - - A: Integer - һ - B: Integer - - - ֵBoolean - Ƿ -} - -function IsUInt32MulOverflow(A: Cardinal; B: Cardinal): Boolean; -{* ж 32 λ޷Ƿ 32 λ޷ - - - A: Cardinal - һ - B: Cardinal - - - ֵBoolean - Ƿ -} - -function IsUInt32MulOverflowInt64(A: Cardinal; B: Cardinal; out R: TUInt64): Boolean; -{* ж 32 λ޷Ƿ 64 λзޣδҲ False ʱR ֱӷؽ - Ҳ TrueҪµ UInt64Mul ʵʩˡ - - - A: Cardinal - һ - B: Cardinal - - out R: TUInt64 - δʱػ - - ֵBoolean - Ƿ -} - -function IsInt64MulOverflow(A: Int64; B: Int64): Boolean; -{* ж 64 λзǷ 64 λзޡ - - - A: Int64 - һ - B: Int64 - - - ֵBoolean - Ƿ -} - -function PointerToInteger(P: Pointer): Integer; -{* ָת֧ͣ 32/64 λע 64 λ¿ܻᶪ 32 λݡ - - - P: Pointer - תָ - - ֵInteger - ת -} - -function IntegerToPointer(I: Integer): Pointer; -{* תָ֧ͣ 32/64 λ - - - I: Integer - ת - - ֵPointer - תָ -} - -function Int64NonNegativeAddMod(A: Int64; B: Int64; N: Int64): Int64; -{* 64 λзΧĺ࣬Ҫ N 0 - - - A: Int64 - һ - B: Int64 - һ - N: Int64 - ģ - - ֵInt64 - Ľ -} - -function UInt64NonNegativeAddMod(A: TUInt64; B: TUInt64; N: TUInt64): TUInt64; -{* 64 λ޷Χĺ࣬Ҫ N 0 - - - A: TUInt64 - һ - B: TUInt64 - - N: TUInt64 - ģ - - ֵTUInt64 - Ľ -} - -function Int64NonNegativeMulMod(A: Int64; B: Int64; N: Int64): Int64; -{* 64 λзΧڵֱ࣬Ӽ㣬Ҫ N 0 - - - A: Int64 - һ - B: Int64 - - N: Int64 - ģ - - ֵInt64 - Ľ -} - -function UInt64NonNegativeMulMod(A: TUInt64; B: TUInt64; N: TUInt64): TUInt64; -{* 64 λ޷Χڵֱ࣬Ӽ㣬 - - - A: TUInt64 - һ - B: TUInt64 - - N: TUInt64 - ģ - - ֵTUInt64 - Ľ -} - -function Int64NonNegativeMod(N: Int64; P: Int64): Int64; -{* װ 64 λзķǸຯҲΪʱӸ豣֤ P 0 - - - N: Int64 - - P: Int64 - - - ֵInt64 - طǸĽ -} - -function Int64NonNegativPower(N: Int64; Exp: Integer): Int64; -{* 64 λзķǸָݣ - - - N: Int64 - - Exp: Integer - ָҪ 0 - - ֵInt64 - ݵĽ -} - -function Int64NonNegativeRoot(N: Int64; Exp: Integer): Int64; -{* 64 λзķǸη֣ - - - N: Int64 - - Exp: Integer - - - ֵInt64 - ؿֽ -} - -function UInt64NonNegativPower(N: TUInt64; Exp: Integer): TUInt64; -{* 64 λ޷ķǸָݣ - - - N: TUInt64 - - Exp: Integer - ָҪ 0 - - ֵTUInt64 - ݵĽ -} - -function UInt64NonNegativeRoot(N: TUInt64; Exp: Integer): TUInt64; -{* 64 λ޷ķǸη֣ - - - N: TUInt64 - - Exp: Integer - - - ֵTUInt64 - ؿֽ -} - -function CurrentByteOrderIsBigEndian: Boolean; -{* صǰڻǷǴˣҲǷеĸֽڴ洢ڽϵ͵ʼַ - ϴҵĶϰߣ粿ָ ARM MIPS - - - ޣ - - ֵBoolean - صǰڻǷǴ -} - -function CurrentByteOrderIsLittleEndian: Boolean; -{* صǰڻǷСˣҲǷеĸֽڴ洢ڽϸߵʼַ x86 벿Ĭ ARM - - - ޣ - - ֵBoolean - صǰڻǷС -} - -function Int64ToBigEndian(Value: Int64): Int64; -{* ȷ 64 λзֵΪˣС˻лת - - - Value: Int64 - ת 64 λз - - ֵInt64 - شֵ -} - -function Int32ToBigEndian(Value: Integer): Integer; -{* ȷ 32 λзֵΪˣС˻лת - - - Value: Integer - ת 32 λз - - ֵInteger - شֵ -} - -function Int16ToBigEndian(Value: SmallInt): SmallInt; -{* ȷ 16 λзֵΪˣС˻лת - - - Value: SmallInt - ת 16 λз - - ֵSmallInt - شֵ -} - -function Int64ToLittleEndian(Value: Int64): Int64; -{* ȷ 64 λзֵΪСˣڴ˻лת - - - Value: Int64 - ת 64 λз - - ֵInt64 - شֵ -} - -function Int32ToLittleEndian(Value: Integer): Integer; -{* ȷ 32 λзֵΪСˣڴ˻лת - - - Value: Integer - ת 32 λз - - ֵInteger - Сֵ -} - -function Int16ToLittleEndian(Value: SmallInt): SmallInt; -{* ȷ 16 λзֵΪСˣڴ˻лת - - - Value: SmallInt - ת 16 λз - - ֵSmallInt - Сֵ -} - -function UInt64ToBigEndian(Value: TUInt64): TUInt64; -{* ȷ 64 λ޷ֵΪˣС˻лת - - - Value: TUInt64 - ת 64 λ޷ - - ֵTUInt64 - شֵ -} - -function UInt32ToBigEndian(Value: Cardinal): Cardinal; -{* ȷ 32 λ޷ֵΪˣС˻лת - - - Value: Cardinal - ת 32 λ޷ - - ֵCardinal - شֵ -} - -function UInt16ToBigEndian(Value: Word): Word; -{* ȷ 16 λ޷ֵΪˣС˻лת - - - Value: Word - ת 16 λ޷ - - ֵWord - شֵ -} - -function UInt64ToLittleEndian(Value: TUInt64): TUInt64; -{* ȷ 64 λ޷ֵΪСˣڴ˻лת - - - Value: TUInt64 - ת 64 λ޷ - - ֵTUInt64 - شֵ -} - -function UInt32ToLittleEndian(Value: Cardinal): Cardinal; -{* ȷ 32 λ޷ֵΪСˣڴ˻лת - - - Value: Cardinal - ת 32 λ޷ - - ֵCardinal - Сֵ -} - -function UInt16ToLittleEndian(Value: Word): Word; -{* ȷ 16 λ޷ֵΪСˣڴ˻лת - - - Value: Word - ת 16 λ޷ - - ֵWord - Сֵ -} - -function Int64HostToNetwork(Value: Int64): Int64; -{* 64 λзֵֽ˳תΪֽ˳С˻лת - - - Value: Int64 - ת 64 λз - - ֵInt64 - ֽ˳ֵ -} - -function Int32HostToNetwork(Value: Integer): Integer; -{* 32 λзֵֽ˳תΪֽ˳С˻лת - - - Value: Integer - ת 32 λз - - ֵInteger - ֽ˳ֵ -} - -function Int16HostToNetwork(Value: SmallInt): SmallInt; -{* 16 λзֵֽ˳תΪֽ˳С˻лת - - - Value: SmallInt - ת 16 λз - - ֵSmallInt - ֽ˳ֵ -} - -function Int64NetworkToHost(Value: Int64): Int64; -{* 64 λзֵֽ˳תΪֽ˳С˻лת - - - Value: Int64 - ת 64 λз - - ֵInt64 - ֽ˳ֵ -} - -function Int32NetworkToHost(Value: Integer): Integer; -{* 32 λзֵֽ˳תΪֽ˳С˻лת - - - Value: Integer - ת 32 λз - - ֵInteger - ֽ˳ֵ -} - -function Int16NetworkToHost(Value: SmallInt): SmallInt; -{* 16 λзֵֽ˳תΪֽ˳С˻лת - - - Value: SmallInt - ת 16 λз - - ֵSmallInt - ֽ˳ֵ -} - -function UInt64HostToNetwork(Value: TUInt64): TUInt64; -{* 64 λ޷ֵֽ˳תΪֽ˳С˻лת - - - Value: TUInt64 - ת 64 λ޷ - - ֵTUInt64 - ֽ˳ֵ -} - -function UInt32HostToNetwork(Value: Cardinal): Cardinal; -{* 32 λ޷ֵֽ˳תΪֽ˳С˻лת - - - Value: Cardinal - ת 32 λ޷ - - ֵCardinal - ֽ˳ֵ -} - -function UInt16HostToNetwork(Value: Word): Word; -{* 16 λ޷ֵֽ˳תΪֽ˳С˻лת - - - Value: Word - ת 16 λ޷ - - ֵWord - ֽ˳ֵ -} - -function UInt64NetworkToHost(Value: TUInt64): TUInt64; -{* 64 λ޷ֵֽ˳תΪֽ˳С˻лת - - - Value: TUInt64 - ת 64 λ޷ - - ֵTUInt64 - ֽ˳ֵ -} - -function UInt32NetworkToHost(Value: Cardinal): Cardinal; -{* 32 λ޷ֵֽ˳תΪֽ˳С˻лת - - - Value: Cardinal - ת 32 λ޷ - - ֵCardinal - ֽ˳ֵ -} - -function UInt16NetworkToHost(Value: Word): Word; -{* 16 λ޷ֵֽ˳תΪֽ˳С˻лת - - - Value: Word - ת 16 λ޷ - - ֵWord - ֽ˳ֵ -} - -procedure MemoryNetworkToHost(Mem: Pointer; MemByteLen: Integer); -{* һƬڴֽ˳תΪֽ˳С˻лת - ÷ӦóϽ٣¶ġֽתѾ㹻 - - - Mem: Pointer - תݿַ - MemByteLen: Integer - תݿֽڳ - - ֵޣ -} - -procedure MemoryHostToNetwork(Mem: Pointer; MemByteLen: Integer); -{* һƬڴֽ˳תΪֽ˳С˻лת - ÷ӦóϽ٣¶ġֽתѾ㹻 - - - Mem: Pointer - תݿַ - MemByteLen: Integer - תݿֽڳ - - ֵޣ -} - -procedure ReverseMemory(Mem: Pointer; MemByteLen: Integer); -{* ֽ˳һڴ飬ֽڲ䡣 - - - Mem: Pointer - õݿַ - MemByteLen: Integer - õݿֽڳ - - ֵޣ -} - -function ReverseBitsInInt8(V: Byte): Byte; -{* һֽڲλݡ - - - V: Byte - õһֽ - - ֵByte - صֵ -} - -function ReverseBitsInInt16(V: Word): Word; -{* öֽڼڲλݡ - - - V: Word - õĶֽ - - ֵWord - صֵ -} - -function ReverseBitsInInt32(V: Cardinal): Cardinal; -{* ֽڼڲλݡ - - - V: Cardinal - õֽ - - ֵCardinal - صֵ -} - -function ReverseBitsInInt64(V: Int64): Int64; -{* ðֽڼڲλݡ - - - V: Int64 - õİֽ - - ֵInt64 - صֵ -} - -procedure ReverseMemoryWithBits(Mem: Pointer; MemByteLen: Integer); -{* ֽ˳һڴ飬ÿֽҲ - - - Mem: Pointer - õݿַ - MemByteLen: Integer - õݿֽڳ - - ֵޣ -} - -procedure MemoryAnd(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); -{* 鳤ͬڴ AMem BMem λ룬 ResMem У߿ͬ - - - AMem: Pointer - ݿַһ - BMem: Pointer - ݿַ - MemByteLen: Integer - ݿֽڳ - ResMem: Pointer - ݿַ - - ֵޣ -} - -procedure MemoryOr(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); -{* 鳤ͬڴ AMem BMem λ򣬽 ResMem У߿ͬ - - - AMem: Pointer - ݿַһ - BMem: Pointer - ݿַ - MemByteLen: Integer - ݿֽڳ - ResMem: Pointer - ݿַ - - ֵޣ -} - -procedure MemoryXor(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); -{* 鳤ͬڴ AMem BMem λ򣬽 ResMem У߿ͬ - - - AMem: Pointer - ݿַһ - BMem: Pointer - ݿַ - MemByteLen: Integer - ݿֽڳ - ResMem: Pointer - ݿַ - - ֵޣ -} - -procedure MemoryNot(Mem: Pointer; MemByteLen: Integer; ResMem: Pointer); -{* һڴ AMem ȡ ResMem У߿ͬ - - - Mem: Pointer - ݿַ - MemByteLen: Integer - ݿֽڳ - ResMem: Pointer - ݿַ - - ֵޣ -} - -procedure MemoryShiftLeft(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; BitCount: Integer); -{* AMem ڴ BitCount λ BMemڴַλƣλ 0߿ȡ - - - AMem: Pointer - ݿַһ - BMem: Pointer - ݿַ - MemByteLen: Integer - ݿֽڳ - BitCount: Integer - Ƶλ - - ֵޣ -} - -procedure MemoryShiftRight(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; BitCount: Integer); -{* AMem ڴ BitCount λ BMemڴַλƣλ 0߿ȡ - - - AMem: Pointer - ݿַһ - BMem: Pointer - ݿַ - MemByteLen: Integer - ݿֽڳ - BitCount: Integer - Ƶλ - - ֵޣ -} - -function MemoryIsBitSet(Mem: Pointer; N: Integer): Boolean; -{* ڴij Bit λǷ 1ڴַλ 0ֽڻұΪ 0 - - - Mem: Pointer - ݿַ - N: Integer - λ - - ֵBoolean - Ƿ 1 -} - -procedure MemorySetBit(Mem: Pointer; N: Integer); -{* ڴij Bit λ 1ڴַλ 0ֽڻұΪ 0 - - - Mem: Pointer - ݿַ - N: Integer - λ - - ֵޣ -} - -procedure MemoryClearBit(Mem: Pointer; N: Integer); -{* ڴij Bit λ 0ڴַλ 0ֽڻұΪ 0 - - - Mem: Pointer - ݿַ - N: Integer - λ - - ֵޣ -} - -function MemoryToBinStr(Mem: Pointer; MemByteLen: Integer; Sep: Boolean = False): string; -{* һڴݴӵ͵ֽ˳ΪַSep ʾֽ֮Ƿոָ - - - Mem: Pointer - ݿַ - MemByteLen: Integer - ݿֽڳ - Sep: Boolean - ֽ֮Ƿÿոָ - - ֵstring - ضַ -} - -procedure MemorySwap(AMem: Pointer; BMem: Pointer; MemByteLen: Integer); -{* ͬȵڴݣͬڴʲô - - - AMem: Pointer - ݿַһ - BMem: Pointer - ݿַ - MemByteLen: Integer - ݿֽڳ - - ֵޣ -} - -function MemoryCompare(AMem: Pointer; BMem: Pointer; MemByteLen: Integer): Integer; -{* ޷ķʽȽڴ棬 10-1ͬڴֱӷ 0 - - - AMem: Pointer - Ƚϵݿַһ - BMem: Pointer - Ƚϵݿַ - MemByteLen: Integer - Ƚϵݿֽڳ - - ֵInteger - رȽϵĽ -} - -procedure MemoryQuickSort(Mem: Pointer; ElementByteSize: Integer; - ElementCount: Integer; CompareProc: TCnMemSortCompareProc = nil); -{* Թ̶СԪص - - - Mem: Pointer - ݿַ - ElementByteSize: Integer - Ԫֽڳ - ElementCount: Integer - ݿԪصĸ - CompareProc: TCnMemSortCompareProc - ԪرȽϵĻص - - ֵޣ -} - -function UInt8ToBinStr(V: Byte): string; -{* һ 8 λ޷תΪַ - - - V: Byte - ת 8 λ޷ - - ֵstring - ضַ -} - -function UInt16ToBinStr(V: Word): string; -{* һ 16 λ޷תΪַ - - - V: Word - ת 16 λ޷ - - ֵstring - ضַ -} - -function UInt32ToBinStr(V: Cardinal): string; -{* һ 32 λ޷תΪַ - - - V: Cardinal - ת 32 λ޷ - - ֵstring - ضַ -} - -function UInt32ToStr(V: Cardinal): string; -{* һ 32 λ޷תΪʮַ - - - V: Cardinal - ת 32 λ޷ - - ֵstring - ʮַ -} - -function UInt64ToBinStr(V: TUInt64): string; -{* һ 64 λ޷תΪַ - - - V: TUInt64 - ת 64 λ޷ - - ֵstring - ضַ -} - -function HexToInt(const Hex: string): Integer; overload; -{* һʮַתΪͣʺϽ϶ 2 ַַ - - - const Hex: string - תʮַ - - ֵInteger - -} - -function HexToInt(Hex: PChar; CharLen: Integer): Integer; overload; -{* һʮַָָתΪͣʺϽ϶ 2 ַַ - - - Hex: PChar - תʮַַ - CharLen: Integer - ַ - - ֵInteger - -} - -function IsHexString(const Hex: string): Boolean; -{* жһַǷϷʮִַСд - - - const Hex: string - жϵʮַ - - ֵBoolean - ǷǺϷʮַ -} - -function DataToHex(InData: Pointer; ByteLength: Integer; UseUpperCase: Boolean = True): string; -{* ڴתΪʮַڴλݳַ󷽣൱ֽ˳ - UseUpperCase ݵĴСд - - - InData: Pointer - תݿַ - ByteLength: Integer - תݿֽڳ - UseUpperCase: Boolean - ʮַڲǷд - - ֵstring - ʮַ -} - -function HexToData(const Hex: string; OutData: Pointer = nil): Integer; -{* ʮַתΪڴ飬ַ󷽵ݳڴλ൱ֽ˳ - ʮַΪתʧʱ׳쳣תɹֽ - ע OutData Ӧָ㹻תݵֽڳΪ Length(Hex) div 2 - nilֻֽڳȣʽת - - - const Hex: string - תʮַ - OutData: Pointer - ֽڳӦΪ Length(Hex) div 2 - - ֵInteger - תֽڳ -} - -function StringToHex(const Data: string; UseUpperCase: Boolean = True): string; -{* ַתΪʮַUseUpperCase ݵĴСд - - - const Data: string - תַ - UseUpperCase: Boolean - ʮַڲǷд - - ֵstring - תʮַ -} - -function HexToString(const Hex: string): string; -{* ʮַתΪַʮַΪתʧʱ׳쳣 - - - const Hex: string - תʮַ - - ֵstring - תַ -} - -function HexToAnsiStr(const Hex: AnsiString): AnsiString; -{* ʮַתΪַʮַΪתʧʱ׳쳣 - - - const Hex: AnsiString - תʮַ - - ֵAnsiString - תַ -} - -function AnsiStrToHex(const Data: AnsiString; UseUpperCase: Boolean = True): AnsiString; -{* AnsiString תΪʮַUseUpperCase ݵĴСд - - - const Data: AnsiString - תַ - UseUpperCase: Boolean - ʮַڲǷд - - ֵAnsiString - ʮַ -} - -function BytesToHex(Data: TBytes; UseUpperCase: Boolean = True): string; -{* ֽתΪʮַ±λݳַ󷽣൱ֽ˳ - UseUpperCase ݵĴСд - - - Data: TBytes - תֽ - UseUpperCase: Boolean - ʮַڲǷд - - ֵstring - ʮַ -} - -function HexToBytes(const Hex: string): TBytes; -{* ʮַתΪֽ飬ַߵݳ±λ൱ֽ˳ - ַΪתʧʱ׳쳣 - - - const Hex: string - תʮַ - - ֵTBytes - ½ֽ -} - -function StreamToHex(Stream: TStream; UseUpperCase: Boolean = True): string; -{* еȫݴͷתΪʮַ - - - Stream: TStream - - UseUpperCase: Boolean - ʮַڲǷд - - ֵstring - ʮַ -} - -function HexToStream(const Hex: string; Stream: TStream): Integer; -{* ʮַתдУдֽ - - - const Hex: string - תʮַ - Stream: TStream - д - - ֵInteger - дֽ -} - -procedure ReverseBytes(Data: TBytes); -{* ֽ˳һֽ顣 - - - Data: TBytes - õֽ - - ֵޣ -} - -function CloneBytes(Data: TBytes): TBytes; -{* һµֽ - - - Data: TBytes - Ƶֽ - - ֵTBytes - ½ֽ -} - -function StreamToBytes(Stream: TStream): TBytes; -{* ͷȫֽ飬½ֽ顣 - - - Stream: TStream - - - ֵTBytes - ½ֽ -} - -function BytesToStream(Data: TBytes; OutStream: TStream): Integer; -{* ֽдԭʼдֽ - - - Data: TBytes - дֽ - OutStream: TStream - д - - ֵInteger - дֽ -} - -function AnsiToBytes(const Str: AnsiString): TBytes; -{* AnsiString ֱתΪֽ飬롣 - - - const Str: AnsiString - תַ - - ֵTBytes - תֽ -} - -function BytesToAnsi(Data: TBytes): AnsiString; -{* ֱֽתΪ AnsiString롣 - - - Data: TBytes - תֽ - - ֵAnsiString - תַ -} - -function BytesToString(Data: TBytes): string; -{* ֽתΪ stringڲ Byte ֵΪ Char롣 - - - Data: TBytes - תֽ - - ֵstring - תַ -} - -function MemoryToString(Mem: Pointer; MemByteLen: Integer): string; -{* ڴתΪ stringڲֽڸֵ롣 - - - Mem: Pointer - תݿַ - MemByteLen: Integer - תݿֽڳ - - ֵstring - תַ -} - -function BitsToString(Bits: TBits): string; -{* λתΪ 0 1 ַ - - - Bits: TBits - תλ - - ֵstring - תַ -} - -function ConcatBytes(A: TBytes; B: TBytes): TBytes; -{* A B ֽ˳ƴ÷һֽ飬A B ֲ䡣 - - - A: TBytes - ƴӵֽһ - B: TBytes - ƴӵֽ - - ֵTBytes - ƴӵֽ -} - -function NewBytesFromMemory(Data: Pointer; DataByteLen: Integer): TBytes; -{* ½һֽ飬һƬڴݹ - - - Data: Pointer - ݿַ - DataByteLen: Integer - ݿֽڳ - - ֵTBytes - ½ֽ -} - -function CompareBytes(A: TBytes; B: TBytes): Boolean; overload; -{* ȽֽǷͬ - - - A: TBytes - Ƚϵֽһ - B: TBytes - Ƚϵֽ - - ֵBoolean - رȽϽǷͬ -} - -function CompareBytes(A: TBytes; B: TBytes; MaxLength: Integer): Boolean; overload; -{* Ƚֽǰ MaxLength ֽڵǷͬ - - - A: TBytes - Ƚϵֽһ - B: TBytes - Ƚϵֽ - MaxLength: Integer - Ƚϵֽ - - ֵBoolean - رȽϽǷͬ -} - -function MoveMost(const Source; var Dest; ByteLen: Integer; MostLen: Integer): Integer; -{* Source ƶ ByteLen Ҳ MostLen ֽڵ Dest Уʵƶֽ - ByteLen С MostLen Dest 0Ҫ Dest MostLen - - - const Source - ƶԴλáַ - var Dest - ƶĿλáַҪ MostLen ֽ - ByteLen: Integer - ƶֽ - MostLen: Integer - ƶֽ - - ֵInteger - ʵƶֽ -} - -// =============================== =================================== - -function SarInt8(var V: Byte; ShiftCount: Integer): Byte; -{* һ 8 λƣҲDZλơ - - - var V: Byte - Ƶ 8 λ - ShiftCount: Integer - Ƶλ - - ֵByte - λֵ -} - -function SarInt16(var V: Word; ShiftCount: Integer): Word; -{* һ 16 λƣҲDZλơ - - - var V: Word - Ƶ 16 λ - ShiftCount: Integer - Ƶλ - - ֵWord - λֵ -} - -function SarInt32(var V: Cardinal; ShiftCount: Integer): Cardinal; -{* һ 32 λƣҲDZλơ - - - var V: Cardinal - Ƶ 32 λ - ShiftCount: Integer - Ƶλ - - ֵCardinal - λֵ -} - -function SarInt64(var V: TUInt64; ShiftCount: Integer): TUInt64; -{* һ 64 λƣҲDZλơ - - - var V: TUInt64 - Ƶ 64 λ - ShiftCount: Integer - Ƶλ - - ֵTUInt64 - λֵ -} - -// ================ ִʱ̶ if жϵIJ߼ =============== - -procedure ConstTimeConditionalSwap8(CanSwap: Boolean; var A: Byte; var B: Byte); -{* 8 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B - - - CanSwap: Boolean - Ƿ񽻻 - var A: Byte - 8 λͱһ - var B: Byte - 8 λͱ - - ֵޣ -} - -procedure ConstTimeConditionalSwap16(CanSwap: Boolean; var A: Word; var B: Word); -{* 16 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B - - - CanSwap: Boolean - Ƿ񽻻 - var A: Word - 16 λͱһ - var B: Word - 16 λͱ - - ֵޣ -} - -procedure ConstTimeConditionalSwap32(CanSwap: Boolean; var A: Cardinal; var B: Cardinal); -{* 32 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B - - - CanSwap: Boolean - Ƿ񽻻 - var A: Cardinal - 32 λͱһ - var B: Cardinal - 32 λͱ - - ֵޣ -} - -procedure ConstTimeConditionalSwap64(CanSwap: Boolean; var A: TUInt64; var B: TUInt64); -{* 64 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B - - - CanSwap: Boolean - Ƿ񽻻 - var A: TUInt64 - 64 λͱһ - var B: TUInt64 - 64 λͱ - - ֵޣ -} - -function ConstTimeEqual8(A: Byte; B: Byte): Boolean; -{* ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True - - - A: Byte - Ƚϵ 8 λͱһ - B: Byte - Ƚϵ 8 λͱ - - ֵBoolean - Ƿ -} - -function ConstTimeEqual16(A: Word; B: Word): Boolean; -{* ˫ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True - - - A: Word - Ƚϵ 16 λͱһ - B: Word - Ƚϵ 16 λͱ - - ֵBoolean - Ƿ -} - -function ConstTimeEqual32(A: Cardinal; B: Cardinal): Boolean; -{* ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True - - - A: Cardinal - Ƚϵ 32 λͱһ - B: Cardinal - Ƚϵ 32 λͱ - - ֵBoolean - Ƿ -} - -function ConstTimeEqual64(A: TUInt64; B: TUInt64): Boolean; -{* ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True - - - A: TUInt64 - Ƚϵ 64 λͱһ - B: TUInt64 - Ƚϵ 64 λͱ - - ֵBoolean - Ƿ -} - -function ConstTimeBytesEqual(A: TBytes; B: TBytes): Boolean; -{* ͬȵִֽʱ̶ıȽϣͬʱ True - - - A: TBytes - Ƚϵֽһ - B: TBytes - Ƚϵֽ - - ֵBoolean - Ƿ -} - -function ConstTimeExpandBoolean8(V: Boolean): Byte; -{* V ֵ 8 λȫ 1 ȫ 0 - - - V: Boolean - Ƿ񷵻ȫ 1 - - ֵByte - $FF 0 -} - -function ConstTimeExpandBoolean16(V: Boolean): Word; -{* V ֵ 16 λȫ 1 ȫ 0 - - - V: Boolean - Ƿ񷵻ȫ 1 - - ֵWord - $FFFF 0 -} - -function ConstTimeExpandBoolean32(V: Boolean): Cardinal; -{* V ֵ 32 λȫ 1 ȫ 0 - - - V: Boolean - Ƿ񷵻ȫ 1 - - ֵCardinal - $FFFFFFFF 0 -} - -function ConstTimeExpandBoolean64(V: Boolean): TUInt64; -{* V ֵ 64 λȫ 1 ȫ 0 - - - V: Boolean - Ƿ񷵻ȫ 1 - - ֵTUInt64 - $FFFFFFFFFFFFFFFF 0 -} - -function ConstTimeConditionalSelect8(Condition: Boolean; A: Byte; B: Byte): Byte; -{* ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B - - - Condition: Boolean - Ƿѡ A ҲDzһ - A: Byte - ѡ 8 λһ - B: Byte - ѡ 8 λ - - ֵByte - ѡ 8 λ -} - -function ConstTimeConditionalSelect16(Condition: Boolean; A: Word; B: Word): Word; -{* ˫ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B - - - Condition: Boolean - Ƿѡ A ҲDzһ - A: Word - ѡ 16 λһ - B: Word - ѡ 16 λ - - ֵWord - ѡ 16 λ -} - -function ConstTimeConditionalSelect32(Condition: Boolean; A: Cardinal; B: Cardinal): Cardinal; -{* ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B - - - Condition: Boolean - Ƿѡ A ҲDzһ - A: Cardinal - ѡ 32 λһ - B: Cardinal - ѡ 32 λ - - ֵCardinal - ѡ 32 λ -} - -function ConstTimeConditionalSelect64(Condition: Boolean; A: TUInt64; B: TUInt64): TUInt64; -{* ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B - - - Condition: Boolean - Ƿѡ A ҲDzһ - A: TUInt64 - ѡ 64 λһ - B: TUInt64 - ѡ 64 λ - - ֵTUInt64 - ѡ 64 λ -} - -// ================ ִʱ̶ if жϵIJ߼ =============== - -{$IFDEF MSWINDOWS} - -// ĸΪ Intel ֻ֧࣬ 32 λ 64 λ Intel CPUӦCPUX86 CPUX64 - -procedure Int64DivInt32Mod(A: Int64; B: Integer; - var DivRes: Integer; var ModRes: Integer); -{* 64 λз 32 λз̷ DivRes ModRes - б֤ 32 λΧڣ쳣 - - - A: Int64 - - B: Integer - - var DivRes: Integer - - var ModRes: Integer - - - ֵޣ -} - -procedure UInt64DivUInt32Mod(A: TUInt64; B: Cardinal; - var DivRes: Cardinal; var ModRes: Cardinal); -{* 64 λ޷ 32 λ޷̷ DivRes ModRes - б֤ 32 λΧڣ쳣 - - - A: TUInt64 - - B: Cardinal - - var DivRes: Cardinal - - var ModRes: Cardinal - - - ֵޣ -} - -procedure Int128DivInt64Mod(ALo: Int64; AHi: Int64; B: Int64; - var DivRes: Int64; var ModRes: Int64); -{* 128 λз 64 λз̷ DivRes ModRes - б֤ 64 λΧڣ쳣 - - - ALo: Int64 - 64 λ - AHi: Int64 - 64 λ - B: Int64 - - var DivRes: Int64 - - var ModRes: Int64 - - - ֵޣ -} - -procedure UInt128DivUInt64Mod(ALo: TUInt64; AHi: TUInt64; B: TUInt64; - var DivRes: TUInt64; var ModRes: TUInt64); -{* 128 λ޷ 64 λ޷̷ DivRes ModRes - б֤ 64 λΧڣ쳣 - - - ALo: TUInt64 - 64 λ - AHi: TUInt64 - 64 λ - B: TUInt64 - - var DivRes: TUInt64 - - var ModRes: TUInt64 - - - ֵޣ -} - -{$ENDIF} - -function IsUInt128BitSet(Lo: TUInt64; Hi: TUInt64; N: Integer): Boolean; -{* Int64 ƴɵ 128 λ֣ص N λǷΪ 1N 0 127 - - - Lo: TUInt64 - жϵĵ 64 λ - Hi: TUInt64 - жϵĸ 64 λ - N: Integer - жϵλ - - ֵBoolean - ǷΪ 1 -} - -procedure SetUInt128Bit(var Lo: TUInt64; var Hi: TUInt64; N: Integer); -{* Int64 ƴɵ 128 λ֣õ N λΪ 1N 0 127 - - - var Lo: TUInt64 - õĵ 64 λ - var Hi: TUInt64 - õĸ 64 λ - N: Integer - õλ - - ֵޣ -} - -procedure ClearUInt128Bit(var Lo: TUInt64; var Hi: TUInt64; N: Integer); -{* Int64 ƴɵ 128 λ֣ N λN 0 127 - - - var Lo: TUInt64 - õĵ 64 λ - var Hi: TUInt64 - õĸ 64 λ - N: Integer - õλ - - ֵޣ -} - -function UnsignedAddWithLimitRadix(A: Cardinal; B: Cardinal; C: Cardinal; - var R: Cardinal; L: Cardinal; H: Cardinal): Cardinal; -{* Ƶ޷żӷA + B + C R Уؽλֵ - ȷ L H ıڣûȷ H LΡ - úַӳ䣬 C һǽλ - - - A: Cardinal - һ - B: Cardinal - - C: Cardinal - һǽλ - var R: Cardinal - - L: Cardinal - ͵ - H: Cardinal - ͵ - - ֵCardinal - Ƿнλ -} - -// =========================== ѭλ ==================================== - -// ע N Ӧ (0, A λ) ڣ N Ϊ 0 A λʱֵӦΪ A -// N ʱࣨΪͲȲͬ 32 λ AN Ϊ 33 ʱֵ N Ϊ 1 ʱķֵ - -function RotateLeft16(A: Word; N: Integer): Word; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -{* 16 λѭ N λ - - - A: Word - ѭƵ 16 λ - N: Integer - ѭƵλ - - ֵWord - λֵ -} - -function RotateRight16(A: Word; N: Integer): Word; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -{* 16 λѭ N λ - - - A: Word - ѭƵ 16 λ - N: Integer - ѭƵλ - - ֵWord - λֵ -} - -function RotateLeft32(A: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -{* 32 λѭ N λ - - - A: Cardinal - ѭƵ 32 λ - N: Integer - ѭƵλ - - ֵCardinal - λֵ -} - -function RotateRight32(A: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -{* 32 λѭ N λ - - - A: Cardinal - ѭƵ 32 λ - N: Integer - ѭƵλ - - ֵCardinal - λֵ -} - -function RotateLeft64(A: TUInt64; N: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -{* 64 λѭ N λ - - - A: TUInt64 - ѭƵ 64 λ - N: Integer - ѭƵλ - - ֵTUInt64 - λֵ -} - -function RotateRight64(A: TUInt64; N: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -{* 64 λѭ N λ - - - A: TUInt64 - ѭƵ 64 λ - N: Integer - ѭƵλ - - ֵTUInt64 - λֵ -} - -{$IFDEF COMPILER5} - -function BoolToStr(Value: Boolean; UseBoolStrs: Boolean = False): string; -{* תΪַDelphi 5 ûи BoolToStr ϡ - - - Value: Boolean - תIJֵ - UseBoolStrs: Boolean - Ƿ񷵻Ӣĵ - - ֵstring - UseBoolStrs Ϊ False ʱ -1 0򷵻 True False -} - -{$ENDIF} - -implementation - -uses - CnFloat; - -resourcestring - SCnErrorNotAHexPChar = 'Error: NOT a Hex PChar: %c'; - SCnErrorLengthNotHex = 'Error Length %d: NOT a Hex String'; - SCnErrorLengthNotHexAnsi = 'Error Length %d: NOT a Hex AnsiString'; - -var - FByteOrderIsBigEndian: Boolean = False; - -function CurrentByteOrderIsBigEndian: Boolean; -type - TByteOrder = packed record - case Boolean of - False: (C: array[0..1] of Byte); - True: (W: Word); - end; -var - T: TByteOrder; -begin - T.W := $00CC; - Result := T.C[1] = $CC; -end; - -function CurrentByteOrderIsLittleEndian: Boolean; -begin - Result := not CurrentByteOrderIsBigEndian; -end; - -function ReverseInt64(Value: Int64): Int64; -var - Lo, Hi: Cardinal; - Rec: Int64Rec; -begin - Lo := Int64Rec(Value).Lo; - Hi := Int64Rec(Value).Hi; - Lo := ((Lo and $000000FF) shl 24) or ((Lo and $0000FF00) shl 8) - or ((Lo and $00FF0000) shr 8) or ((Lo and $FF000000) shr 24); - Hi := ((Hi and $000000FF) shl 24) or ((Hi and $0000FF00) shl 8) - or ((Hi and $00FF0000) shr 8) or ((Hi and $FF000000) shr 24); - Rec.Lo := Hi; - Rec.Hi := Lo; - Result := Int64(Rec); -end; - -function ReverseUInt64(Value: TUInt64): TUInt64; -var - Lo, Hi: Cardinal; - Rec: Int64Rec; -begin - Lo := Int64Rec(Value).Lo; - Hi := Int64Rec(Value).Hi; - Lo := ((Lo and $000000FF) shl 24) or ((Lo and $0000FF00) shl 8) - or ((Lo and $00FF0000) shr 8) or ((Lo and $FF000000) shr 24); - Hi := ((Hi and $000000FF) shl 24) or ((Hi and $0000FF00) shl 8) - or ((Hi and $00FF0000) shr 8) or ((Hi and $FF000000) shr 24); - Rec.Lo := Hi; - Rec.Hi := Lo; - Result := TUInt64(Rec); -end; - -function Int64ToBigEndian(Value: Int64): Int64; -begin - if FByteOrderIsBigEndian then - Result := Value - else - Result := ReverseInt64(Value); -end; - -function Int32ToBigEndian(Value: Integer): Integer; -begin - if FByteOrderIsBigEndian then - Result := Value - else - Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) - or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24); -end; - -function Int16ToBigEndian(Value: SmallInt): SmallInt; -begin - if FByteOrderIsBigEndian then - Result := Value - else - Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8); -end; - -function Int64ToLittleEndian(Value: Int64): Int64; -begin - if not FByteOrderIsBigEndian then - Result := Value - else - Result := ReverseInt64(Value); -end; - -function Int32ToLittleEndian(Value: Integer): Integer; -begin - if not FByteOrderIsBigEndian then - Result := Value - else - Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) - or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24); -end; - -function Int16ToLittleEndian(Value: SmallInt): SmallInt; -begin - if not FByteOrderIsBigEndian then - Result := Value - else - Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8); -end; - -function UInt64ToBigEndian(Value: TUInt64): TUInt64; -begin - if FByteOrderIsBigEndian then - Result := Value - else - Result := ReverseUInt64(Value); -end; - -function UInt32ToBigEndian(Value: Cardinal): Cardinal; -begin - if FByteOrderIsBigEndian then - Result := Value - else - Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) - or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24); -end; - -function UInt16ToBigEndian(Value: Word): Word; -begin - if FByteOrderIsBigEndian then - Result := Value - else - Result := Word((Value and $00FF) shl 8) or Word((Value and $FF00) shr 8); -end; - -function UInt64ToLittleEndian(Value: TUInt64): TUInt64; -begin - if not FByteOrderIsBigEndian then - Result := Value - else - Result := ReverseUInt64(Value); -end; - -function UInt32ToLittleEndian(Value: Cardinal): Cardinal; -begin - if not FByteOrderIsBigEndian then - Result := Value - else - Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) - or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24); -end; - -function UInt16ToLittleEndian(Value: Word): Word; -begin - if not FByteOrderIsBigEndian then - Result := Value - else - Result := Word((Value and $00FF) shl 8) or Word((Value and $FF00) shr 8); -end; - -function Int64HostToNetwork(Value: Int64): Int64; -begin - if not FByteOrderIsBigEndian then - Result := ReverseInt64(Value) - else - Result := Value; -end; - -function Int32HostToNetwork(Value: Integer): Integer; -begin - if not FByteOrderIsBigEndian then - Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) - or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24) - else - Result := Value; -end; - -function Int16HostToNetwork(Value: SmallInt): SmallInt; -begin - if not FByteOrderIsBigEndian then - Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8) - else - Result := Value; -end; - -function Int64NetworkToHost(Value: Int64): Int64; -begin - if not FByteOrderIsBigEndian then - REsult := ReverseInt64(Value) - else - Result := Value; -end; - -function Int32NetworkToHost(Value: Integer): Integer; -begin - if not FByteOrderIsBigEndian then - Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) - or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24) - else - Result := Value; -end; - -function Int16NetworkToHost(Value: SmallInt): SmallInt; -begin - if not FByteOrderIsBigEndian then - Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8) - else - Result := Value; -end; - -function UInt64HostToNetwork(Value: TUInt64): TUInt64; -begin - if CurrentByteOrderIsBigEndian then - Result := Value - else - Result := ReverseUInt64(Value); -end; - -function UInt32HostToNetwork(Value: Cardinal): Cardinal; -begin - if not FByteOrderIsBigEndian then - Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) - or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24) - else - Result := Value; -end; - -function UInt16HostToNetwork(Value: Word): Word; -begin - if not FByteOrderIsBigEndian then - Result := ((Value and $00FF) shl 8) or ((Value and $FF00) shr 8) - else - Result := Value; -end; - -function UInt64NetworkToHost(Value: TUInt64): TUInt64; -begin - if CurrentByteOrderIsBigEndian then - Result := Value - else - Result := ReverseUInt64(Value); -end; - -function UInt32NetworkToHost(Value: Cardinal): Cardinal; -begin - if not FByteOrderIsBigEndian then - Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) - or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24) - else - Result := Value; -end; - -function UInt16NetworkToHost(Value: Word): Word; -begin - if not FByteOrderIsBigEndian then - Result := ((Value and $00FF) shl 8) or ((Value and $FF00) shr 8) - else - Result := Value; -end; - -function ReverseBitsInInt8(V: Byte): Byte; -begin - // 0 1 2 3 4 5 6 7 - V := ((V and $AA) shr 1) or ((V and $55) shl 1); - // 01 23 45 67 - V := ((V and $CC) shr 2) or ((V and $33) shl 2); - // 0123 4567 - V := (V shr 4) or (V shl 4); - Result := V; -end; - -function ReverseBitsInInt16(V: Word): Word; -begin - Result := (ReverseBitsInInt8(V and $00FF) shl 8) - or ReverseBitsInInt8((V and $FF00) shr 8); -end; - -function ReverseBitsInInt32(V: Cardinal): Cardinal; -begin - Result := (ReverseBitsInInt16(V and $0000FFFF) shl 16) - or ReverseBitsInInt16((V and $FFFF0000) shr 16); -end; - -function ReverseBitsInInt64(V: Int64): Int64; -begin - Result := (Int64(ReverseBitsInInt32(V and $00000000FFFFFFFF)) shl 32) - or ReverseBitsInInt32((V and $FFFFFFFF00000000) shr 32); -end; - -procedure ReverseMemory(Mem: Pointer; MemByteLen: Integer); -var - I, L: Integer; - P: PByteArray; - T: Byte; -begin - if (Mem = nil) or (MemByteLen < 2) then - Exit; - - L := MemByteLen div 2; - P := PByteArray(Mem); - for I := 0 to L - 1 do - begin - // I ͵ MemLen - I - 1 - T := P^[I]; - P^[I] := P^[MemByteLen - I - 1]; - P^[MemByteLen - I - 1] := T; - end; -end; - -procedure ReverseMemoryWithBits(Mem: Pointer; MemByteLen: Integer); -var - I: Integer; - P: PByteArray; -begin - if (Mem = nil) or (MemByteLen <= 0) then - Exit; - - ReverseMemory(Mem, MemByteLen); - P := PByteArray(Mem); - - for I := 0 to MemByteLen - 1 do - P^[I] := ReverseBitsInInt8(P^[I]); -end; - -procedure MemoryNetworkToHost(Mem: Pointer; MemByteLen: Integer); -begin - if not FByteOrderIsBigEndian then - ReverseMemory(Mem, MemByteLen); -end; - -procedure MemoryHostToNetwork(Mem: Pointer; MemByteLen: Integer); -begin - if not FByteOrderIsBigEndian then - ReverseMemory(Mem, MemByteLen); -end; - -// N ֽڳȵڴλ -procedure MemoryBitOperation(AMem, BMem, RMem: Pointer; N: Integer; Op: TCnBitOperation); -var - A, B, R: PCnLongWord32Array; - BA, BB, BR: PByteArray; -begin - if N <= 0 then - Exit; - - if (AMem = nil) or ((BMem = nil) and (Op <> boNot)) or (RMem = nil) then - Exit; - - A := PCnLongWord32Array(AMem); - B := PCnLongWord32Array(BMem); - R := PCnLongWord32Array(RMem); - - while (N and (not 3)) <> 0 do - begin - case Op of - boAnd: - R^[0] := A^[0] and B^[0]; - boOr: - R^[0] := A^[0] or B^[0]; - boXor: - R^[0] := A^[0] xor B^[0]; - boNot: // ʱ B - R^[0] := not A^[0]; - end; - - A := PCnLongWord32Array(TCnNativeInt(A) + SizeOf(Cardinal)); - B := PCnLongWord32Array(TCnNativeInt(B) + SizeOf(Cardinal)); - R := PCnLongWord32Array(TCnNativeInt(R) + SizeOf(Cardinal)); - - Dec(N, SizeOf(Cardinal)); - end; - - if N > 0 then - begin - BA := PByteArray(A); - BB := PByteArray(B); - BR := PByteArray(R); - - while N <> 0 do - begin - case Op of - boAnd: - BR^[0] := BA^[0] and BB^[0]; - boOr: - BR^[0] := BA^[0] or BB^[0]; - boXor: - BR^[0] := BA^[0] xor BB^[0]; - boNot: - BR^[0] := not BA^[0]; - end; - - BA := PByteArray(TCnNativeInt(BA) + SizeOf(Byte)); - BB := PByteArray(TCnNativeInt(BB) + SizeOf(Byte)); - BR := PByteArray(TCnNativeInt(BR) + SizeOf(Byte)); - Dec(N); - end; - end; -end; - -procedure MemoryAnd(AMem, BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); -begin - MemoryBitOperation(AMem, BMem, ResMem, MemByteLen, boAnd); -end; - -procedure MemoryOr(AMem, BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); -begin - MemoryBitOperation(AMem, BMem, ResMem, MemByteLen, boOr); -end; - -procedure MemoryXor(AMem, BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); -begin - MemoryBitOperation(AMem, BMem, ResMem, MemByteLen, boXor); -end; - -procedure MemoryNot(Mem: Pointer; MemByteLen: Integer; ResMem: Pointer); -begin - MemoryBitOperation(Mem, nil, ResMem, MemByteLen, boNot); -end; - -procedure MemoryShiftLeft(AMem, BMem: Pointer; MemByteLen: Integer; BitCount: Integer); -var - I, L, N, LB, RB: Integer; - PF, PT: PByteArray; -begin - if (AMem = nil) or (MemByteLen <= 0) or (BitCount = 0) then - Exit; - - if BitCount < 0 then - begin - MemoryShiftRight(AMem, BMem, MemByteLen, -BitCount); - Exit; - end; - - if BMem = nil then - BMem := AMem; - - if (MemByteLen * 8) <= BitCount then // ̫಻ȫ 0 - begin - FillChar(BMem^, MemByteLen, 0); - Exit; - end; - - N := BitCount div 8; // λֽ - RB := BitCount mod 8; // ȥֽںʣµλ - LB := 8 - RB; // ʣµλһֽʣµλ - - PF := PByteArray(AMem); - PT := PByteArray(BMem); - - if RB = 0 then // 飬ð죬Ҫλֽ MemLen - NW - begin - Move(PF^[N], PT^[0], MemByteLen - N); - FillChar(PT^[MemByteLen - N], N, 0); - end - else - begin - // PF^[N] PT^[0] MemLen - N ֽڣֽڼн - L := MemByteLen - N; - PF := PByteArray(TCnNativeInt(PF) + N); - - for I := 1 to L do // ӵλƶȴ͵ - begin - PT^[0] := Byte(PF^[0] shl RB); - if I < L then // һֽ PF^[1] ᳬ - PT^[0] := (PF^[1] shr LB) or PT^[0]; - - PF := PByteArray(TCnNativeInt(PF) + 1); - PT := PByteArray(TCnNativeInt(PT) + 1); - end; - - // ʣµҪ 0 - if N > 0 then - FillChar(PT^[0], N, 0); - end; -end; - -procedure MemoryShiftRight(AMem, BMem: Pointer; MemByteLen: Integer; BitCount: Integer); -var - I, L, N, LB, RB: Integer; - PF, PT: PByteArray; -begin - if (AMem = nil) or (MemByteLen <= 0) or (BitCount = 0) then - Exit; - - if BitCount < 0 then - begin - MemoryShiftLeft(AMem, BMem, MemByteLen, -BitCount); - Exit; - end; - - if BMem = nil then - BMem := AMem; - - if (MemByteLen * 8) <= BitCount then // ̫಻ȫ 0 - begin - FillChar(BMem^, MemByteLen, 0); - Exit; - end; - - N := BitCount div 8; // λֽ - RB := BitCount mod 8; // ȥֽںʣµλ - LB := 8 - RB; // ʣµλһֽʣµλ - - if RB = 0 then // 飬ð죬Ҫλֽ MemLen - N - begin - PF := PByteArray(AMem); - PT := PByteArray(BMem); - - Move(PF^[0], PT^[N], MemByteLen - N); - FillChar(PT^[0], N, 0); - end - else - begin - // PF^[0] PT^[N] MemLen - N ֽڣôӸߴʼֽڼн - L := MemByteLen - N; - - PF := PByteArray(TCnNativeInt(AMem) + L - 1); - PT := PByteArray(TCnNativeInt(BMem) + MemByteLen - 1); - - for I := L downto 1 do // Ӹλλƶȴ - begin - PT^[0] := Byte(PF^[0] shr RB); - if I > 1 then // һֽ PF^[-1] ᳬ - begin - PF := PByteArray(TCnNativeInt(PF) - 1); - PT^[0] := (PF^[0] shl LB) or PT^[0]; - end - else - PF := PByteArray(TCnNativeInt(PF) - 1); - - PT := PByteArray(TCnNativeInt(PT) - 1); - end; - - // ʣµǰҪ 0 - if N > 0 then - FillChar(BMem^, N, 0); - end; -end; - -function MemoryIsBitSet(Mem: Pointer; N: Integer): Boolean; -var - P: PByte; - A, B: Integer; - V: Byte; -begin - if (Mem = nil) or (N < 0) then - raise ERangeError.Create(SRangeError); - - A := N div 8; - B := N mod 8; - P := PByte(TCnNativeInt(Mem) + A); - - V := Byte(1 shl B); - Result := (P^ and V) <> 0; -end; - -procedure MemorySetBit(Mem: Pointer; N: Integer); -var - P: PByte; - A, B: Integer; - V: Byte; -begin - if (Mem = nil) or (N < 0) then - raise ERangeError.Create(SRangeError); - - A := N div 8; - B := N mod 8; - P := PByte(TCnNativeInt(Mem) + A); - - V := Byte(1 shl B); - P^ := P^ or V; -end; - -procedure MemoryClearBit(Mem: Pointer; N: Integer); -var - P: PByte; - A, B: Integer; - V: Byte; -begin - if (Mem = nil) or (N < 0) then - raise ERangeError.Create(SRangeError); - - A := N div 8; - B := N mod 8; - P := PByte(TCnNativeInt(Mem) + A); - - V := not Byte(1 shl B); - P^ := P^ and V; -end; - -function MemoryToBinStr(Mem: Pointer; MemByteLen: Integer; Sep: Boolean): string; -var - J, L: Integer; - P: PByteArray; - B: PChar; - - procedure FillAByteToBuf(V: Byte; Buf: PChar); - const - M = $80; - var - I: Integer; - begin - for I := 0 to 7 do - begin - if (V and M) <> 0 then - Buf[I] := '1' - else - Buf[I] := '0'; - V := V shl 1; - end; - end; - -begin - Result := ''; - if (Mem = nil) or (MemByteLen <= 0) then - Exit; - - L := MemByteLen * 8; - if Sep then - L := L + MemByteLen - 1; // мÿոָ - - SetLength(Result, L); - B := PChar(@Result[1]); - P := PByteArray(Mem); - - for J := 0 to MemByteLen - 1 do - begin - FillAByteToBuf(P^[J], B); - if Sep then - begin - B[8] := ' '; - Inc(B, 9); - end - else - Inc(B, 8); - end; -end; - -procedure MemorySwap(AMem, BMem: Pointer; MemByteLen: Integer); -var - A, B: PCnLongWord32Array; - BA, BB: PByteArray; - TC: Cardinal; - TB: Byte; -begin - if (AMem = nil) or (BMem = nil) or (MemByteLen <= 0) then - Exit; - - A := PCnLongWord32Array(AMem); - B := PCnLongWord32Array(BMem); - - if A = B then - Exit; - - while (MemByteLen and (not 3)) <> 0 do - begin - TC := A^[0]; - A^[0] := B^[0]; - B^[0] := TC; - - A := PCnLongWord32Array(TCnNativeInt(A) + SizeOf(Cardinal)); - B := PCnLongWord32Array(TCnNativeInt(B) + SizeOf(Cardinal)); - - Dec(MemByteLen, SizeOf(Cardinal)); - end; - - if MemByteLen > 0 then - begin - BA := PByteArray(A); - BB := PByteArray(B); - - while MemByteLen <> 0 do - begin - TB := BA^[0]; - BA^[0] := BB^[0]; - BB^[0] :=TB; - - BA := PByteArray(TCnNativeInt(BA) + SizeOf(Byte)); - BB := PByteArray(TCnNativeInt(BB) + SizeOf(Byte)); - - Dec(MemByteLen); - end; - end; -end; - -function MemoryCompare(AMem, BMem: Pointer; MemByteLen: Integer): Integer; -var - A, B: PCnLongWord32Array; - BA, BB: PByteArray; -begin - Result := 0; - if ((AMem = nil) and (BMem = nil)) or (AMem = BMem) then // ͬһ - Exit; - - if MemByteLen <= 0 then - Exit; - - if AMem = nil then - begin - Result := -1; - Exit; - end; - if BMem = nil then - begin - Result := 1; - Exit; - end; - - A := PCnLongWord32Array(AMem); - B := PCnLongWord32Array(BMem); - - while (MemByteLen and (not 3)) <> 0 do - begin - if A^[0] > B^[0] then - begin - Result := 1; - Exit; - end - else if A^[0] < B^[0] then - begin - Result := -1; - Exit; - end; - - A := PCnLongWord32Array(TCnNativeInt(A) + SizeOf(Cardinal)); - B := PCnLongWord32Array(TCnNativeInt(B) + SizeOf(Cardinal)); - - Dec(MemByteLen, SizeOf(Cardinal)); - end; - - if MemByteLen > 0 then - begin - BA := PByteArray(A); - BB := PByteArray(B); - - while MemByteLen <> 0 do - begin - if BA^[0] > BB^[0] then - begin - Result := 1; - Exit; - end - else if BA^[0] < BB^[0] then - begin - Result := -1; - Exit; - end; - - BA := PByteArray(TCnNativeInt(BA) + SizeOf(Byte)); - BB := PByteArray(TCnNativeInt(BB) + SizeOf(Byte)); - - Dec(MemByteLen); - end; - end; -end; - -function UInt8ToBinStr(V: Byte): string; -const - M = $80; -var - I: Integer; -begin - SetLength(Result, 8 * SizeOf(V)); - for I := 1 to 8 * SizeOf(V) do - begin - if (V and M) <> 0 then - Result[I] := '1' - else - Result[I] := '0'; - V := V shl 1; - end; -end; - -function UInt16ToBinStr(V: Word): string; -const - M = $8000; -var - I: Integer; -begin - SetLength(Result, 8 * SizeOf(V)); - for I := 1 to 8 * SizeOf(V) do - begin - if (V and M) <> 0 then - Result[I] := '1' - else - Result[I] := '0'; - V := V shl 1; - end; -end; - -function UInt32ToBinStr(V: Cardinal): string; -const - M = $80000000; -var - I: Integer; -begin - SetLength(Result, 8 * SizeOf(V)); - for I := 1 to 8 * SizeOf(V) do - begin - if (V and M) <> 0 then - Result[I] := '1' - else - Result[I] := '0'; - V := V shl 1; - end; -end; - -function UInt32ToStr(V: Cardinal): string; -begin - Result := Format('%u', [V]); -end; - -function UInt64ToBinStr(V: TUInt64): string; -const - M = $8000000000000000; -var - I: Integer; -begin - SetLength(Result, 8 * SizeOf(V)); - - for I := 1 to 8 * SizeOf(V) do - begin - if (V and M) <> 0 then - Result[I] := '1' - else - Result[I] := '0'; - V := V shl 1; - end; -end; - -const - HiDigits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); -const - LoDigits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); - -const - AnsiHiDigits: array[0..15] of AnsiChar = ('0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); -const - AnsiLoDigits: array[0..15] of AnsiChar = ('0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); - -function HexToInt(Hex: PChar; CharLen: Integer): Integer; -var - I, Res: Integer; - C: Char; -begin - Res := 0; - for I := 0 to CharLen - 1 do - begin - C := Hex[I]; - if (C >= '0') and (C <= '9') then - Res := Res * 16 + Ord(C) - Ord('0') - else if (C >= 'A') and (C <= 'F') then - Res := Res * 16 + Ord(C) - Ord('A') + 10 - else if (C >= 'a') and (C <= 'f') then - Res := Res * 16 + Ord(C) - Ord('a') + 10 - else - raise ECnNativeException.CreateFmt(SCnErrorNotAHexPChar, [C]); - end; - Result := Res; -end; - -function HexToInt(const Hex: string): Integer; -begin - Result := HexToInt(PChar(Hex), Length(Hex)); -end; - -{$WARNINGS OFF} - -function IsHexString(const Hex: string): Boolean; -var - I, L: Integer; -begin - Result := False; - L := Length(Hex); - if (L <= 0) or ((L and 1) <> 0) then // ջżȶ - Exit; - - for I := 1 to L do - begin - // ע˴ Unicode Ȼ Warningǽ Hex[I] WideChar ֱӽض AnsiChar - // ٽжϣᵼ¡޻ޡ $66$66$66$66 ַУ - // ֱͨ WideChar ֵ ax ˫ֽڵģӼжϣ - if not (Hex[I] in ['0'..'9', 'A'..'F', 'a'..'f']) then - Exit; - end; - Result := True; -end; - -{$WARNINGS ON} - -function DataToHex(InData: Pointer; ByteLength: Integer; UseUpperCase: Boolean = True): string; -var - I: Integer; - B: Byte; -begin - Result := ''; - if ByteLength <= 0 then - Exit; - - SetLength(Result, ByteLength * 2); - if UseUpperCase then - begin - for I := 0 to ByteLength - 1 do - begin - B := PByte(TCnNativeInt(InData) + I * SizeOf(Byte))^; - Result[I * 2 + 1] := HiDigits[(B shr 4) and $0F]; - Result[I * 2 + 2] := HiDigits[B and $0F]; - end; - end - else - begin - for I := 0 to ByteLength - 1 do - begin - B := PByte(TCnNativeInt(InData) + I * SizeOf(Byte))^; - Result[I * 2 + 1] := LoDigits[(B shr 4) and $0F]; - Result[I * 2 + 2] := LoDigits[B and $0F]; - end; - end; -end; - -function HexToData(const Hex: string; OutData: Pointer): Integer; -var - I, L: Integer; - H: PChar; -begin - L := Length(Hex); - if (L mod 2) <> 0 then - raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); - - if OutData = nil then - begin - Result := L div 2; - Exit; - end; - - Result := 0; - H := PChar(Hex); - for I := 1 to L div 2 do - begin - PByte(TCnNativeInt(OutData) + I - 1)^ := Byte(HexToInt(@H[(I - 1) * 2], 2)); - Inc(Result); - end; -end; - -function StringToHex(const Data: string; UseUpperCase: Boolean): string; -var - I, L: Integer; - B: Byte; - Buffer: PChar; -begin - Result := ''; - L := Length(Data); - if L = 0 then - Exit; - - SetLength(Result, L * 2); - Buffer := @Data[1]; - - if UseUpperCase then - begin - for I := 0 to L - 1 do - begin - B := PByte(TCnNativeInt(Buffer) + I * SizeOf(Char))^; - Result[I * 2 + 1] := HiDigits[(B shr 4) and $0F]; - Result[I * 2 + 2] := HiDigits[B and $0F]; - end; - end - else - begin - for I := 0 to L - 1 do - begin - B := PByte(TCnNativeInt(Buffer) + I * SizeOf(Char))^; - Result[I * 2 + 1] := LoDigits[(B shr 4) and $0F]; - Result[I * 2 + 2] := LoDigits[B and $0F]; - end; - end; -end; - -function HexToString(const Hex: string): string; -var - I, L: Integer; - H: PChar; -begin - L := Length(Hex); - if (L mod 2) <> 0 then - raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); - - SetLength(Result, L div 2); - H := PChar(Hex); - for I := 1 to L div 2 do - Result[I] := Chr(HexToInt(@H[(I - 1) * 2], 2)); -end; - -function HexToAnsiStr(const Hex: AnsiString): AnsiString; -var - I, L: Integer; - S: string; -begin - L := Length(Hex); - if (L mod 2) <> 0 then - raise ECnNativeException.CreateFmt(SCnErrorLengthNotHexAnsi, [L]); - - SetLength(Result, L div 2); - for I := 1 to L div 2 do - begin - S := string(Copy(Hex, I * 2 - 1, 2)); - Result[I] := AnsiChar(Chr(HexToInt(S))); - end; -end; - -function AnsiStrToHex(const Data: AnsiString; UseUpperCase: Boolean): AnsiString; -var - I, L: Integer; - B: Byte; - Buffer: PAnsiChar; -begin - Result := ''; - L := Length(Data); - if L = 0 then - Exit; - - SetLength(Result, L * 2); - Buffer := @Data[1]; - - if UseUpperCase then - begin - for I := 0 to L - 1 do - begin - B := PByte(TCnNativeInt(Buffer) + I)^; - Result[I * 2 + 1] := AnsiHiDigits[(B shr 4) and $0F]; - Result[I * 2 + 2] := AnsiHiDigits[B and $0F]; - end; - end - else - begin - for I := 0 to L - 1 do - begin - B := PByte(TCnNativeInt(Buffer) + I)^; - Result[I * 2 + 1] := AnsiLoDigits[(B shr 4) and $0F]; - Result[I * 2 + 2] := AnsiLoDigits[B and $0F]; - end; - end; -end; - -function BytesToHex(Data: TBytes; UseUpperCase: Boolean): string; -var - I, L: Integer; - B: Byte; - Buffer: PAnsiChar; -begin - Result := ''; - L := Length(Data); - if L = 0 then - Exit; - - SetLength(Result, L * 2); - Buffer := @Data[0]; - - if UseUpperCase then - begin - for I := 0 to L - 1 do - begin - B := PByte(TCnNativeInt(Buffer) + I)^; - Result[I * 2 + 1] := HiDigits[(B shr 4) and $0F]; - Result[I * 2 + 2] := HiDigits[B and $0F]; - end; - end - else - begin - for I := 0 to L - 1 do - begin - B := PByte(TCnNativeInt(Buffer) + I)^; - Result[I * 2 + 1] := LoDigits[(B shr 4) and $0F]; - Result[I * 2 + 2] := LoDigits[B and $0F]; - end; - end; -end; - -function HexToBytes(const Hex: string): TBytes; -var - I, L: Integer; - H: PChar; -begin - L := Length(Hex); - if (L mod 2) <> 0 then - raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); - - SetLength(Result, L div 2); - H := PChar(Hex); - - for I := 1 to L div 2 do - Result[I - 1] := Byte(HexToInt(@H[(I - 1) * 2], 2)); -end; - -function StreamToHex(Stream: TStream; UseUpperCase: Boolean): string; -var - B: Byte; - I: Integer; -begin - Result := ''; - if Stream.Size > 0 then - begin - Stream.Position := 0; - SetLength(Result, Stream.Size * 2); - I := 1; - if UseUpperCase then - begin - while Stream.Read(B, 1) = 1 do - begin - Result[I] := HiDigits[(B shr 4) and $0F]; - Inc(I); - Result[I] := HiDigits[B and $0F]; - Inc(I); - end; - end - else - begin - while Stream.Read(B, 1) = 1 do - begin - Result[I] := LoDigits[(B shr 4) and $0F]; - Inc(I); - Result[I] := LoDigits[B and $0F]; - Inc(I); - end; - end; - end; -end; - -function HexToStream(const Hex: string; Stream: TStream): Integer; -var - I, L: Integer; - H: PChar; - B: Byte; -begin - Result := 0; - L := Length(Hex); - if (L mod 2) <> 0 then - raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); - - H := PChar(Hex); - for I := 1 to L div 2 do - begin - B := Byte(HexToInt(@H[(I - 1) * 2], 2)); - Inc(Result, Stream.Write(B, 1)); - end; -end; - -procedure ReverseBytes(Data: TBytes); -var - I, L, M: Integer; - T: Byte; -begin - if (Data = nil) or (Length(Data) <= 1) then - Exit; - L := Length(Data); - M := L div 2; - for I := 0 to M - 1 do - begin - // I L - I - 1 - T := Data[I]; - Data[I] := Data[L - I - 1]; - Data[L - I - 1] := T; - end; -end; - -function CloneBytes(Data: TBytes): TBytes; -begin - if Length(Data) = 0 then - Result := nil - else - begin - SetLength(Result, Length(Data)); - Move(Data[0], Result[0], Length(Data)); - end; -end; - -function StreamToBytes(Stream: TStream): TBytes; -begin - Result := nil; - if (Stream <> nil) and (Stream.Size > 0) then - begin - SetLength(Result, Stream.Size); - Stream.Position := 0; - Stream.Read(Result[0], Stream.Size); - end; -end; - -function BytesToStream(Data: TBytes; OutStream: TStream): Integer; -begin - Result := 0; - if (Data <> nil) and (Length(Data) > 0) and (OutStream <> nil) then - begin - OutStream.Size := 0; - Result := OutStream.Write(Data[0], Length(Data)); - end; -end; - -function AnsiToBytes(const Str: AnsiString): TBytes; -begin - SetLength(Result, Length(Str)); - if Length(Str) > 0 then - Move(Str[1], Result[0], Length(Str)); -end; - -function BytesToAnsi(Data: TBytes): AnsiString; -begin - SetLength(Result, Length(Data)); - if Length(Data) > 0 then - Move(Data[0], Result[1], Length(Data)); -end; - -function BytesToString(Data: TBytes): string; -var - I: Integer; -begin - SetLength(Result, Length(Data)); - for I := 1 to Length(Data) do - Result[I] := Chr(Data[I - 1]); -end; - -function MemoryToString(Mem: Pointer; MemByteLen: Integer): string; -var - P: PByteArray; - I: Integer; -begin - if (Mem = nil) or (MemByteLen <= 0) then - begin - Result := ''; - Exit; - end; - - P := PByteArray(Mem); - SetLength(Result, MemByteLen); - for I := 1 to MemByteLen do - Result[I] := Chr(P^[I - 1]); -end; - -function BitsToString(Bits: TBits): string; -var - I: Integer; -begin - if (Bits = nil) or (Bits.Size = 0) then - Result := '' - else - begin - SetLength(Result, Bits.Size); - for I := 0 to Bits.Size - 1 do - begin - if Bits.Bits[I] then - Result[I + 1] := '1' - else - Result[I + 1] := '0'; - end; - end; -end; - -function ConcatBytes(A, B: TBytes): TBytes; -begin - // XE7 ҲֱӣΪ A B Ϊʱ᷵һֽ - if (A = nil) or (Length(A) = 0) then - begin - SetLength(Result, Length(B)); - if Length(B) > 0 then - Move(B[0], Result[0], Length(B)); - end - else if (B = nil) or (Length(B) = 0) then - begin - SetLength(Result, Length(A)); - if Length(A) > 0 then - Move(A[0], Result[0], Length(A)); - end - else - begin - SetLength(Result, Length(A) + Length(B)); - Move(A[0], Result[0], Length(A)); - Move(B[0], Result[Length(A)], Length(B)); - end; -end; - -function NewBytesFromMemory(Data: Pointer; DataByteLen: Integer): TBytes; -begin - if (Data = nil) or (DataByteLen <= 0) then - Result := nil - else - begin - SetLength(Result, DataByteLen); - Move(Data^, Result[0], DataByteLen); - end; -end; - -function CompareBytes(A, B: TBytes): Boolean; -var - L: Integer; -begin - Result := False; - - L := Length(A); - if Length(B) <> L then // Ȳ˳ - Exit; - - if L = 0 then // - Result := True // 綼 0 - else - Result := CompareMem(@A[0], @B[0], L); -end; - -function CompareBytes(A, B: TBytes; MaxLength: Integer): Boolean; -var - LA, LB: Integer; -begin - Result := False; - - LA := Length(A); - LB := Length(B); - - if LA > MaxLength then - LA := MaxLength; - if LB > MaxLength then - LB := MaxLength; - - if LA <> LB then - Exit; - - if LA = 0 then - Result := True - else - Result := CompareMem(@A[0], @B[0], LA); -end; - -function MoveMost(const Source; var Dest; ByteLen, MostLen: Integer): Integer; -begin - if (MostLen <= 0) or (ByteLen <= 0) then - begin - Result := 0; - Exit; - end; - - if ByteLen > MostLen then - ByteLen := MostLen - else if ByteLen < MostLen then - begin - FillChar(Dest, MostLen, 0); - - // TODO: ҪΪ FillChar(Dest + ByteLen, MostLen - ByteLen, 0); ֻ䲻IJ - end; - - Move(Source, Dest, ByteLen); - Result := ByteLen; -end; - -// =============================== =================================== - -function SarInt8(var V: Byte; ShiftCount: Integer): Byte; -begin - Result := V shr ShiftCount; - if (V and $80) <> 0 then - Result := Result or $80; -end; - -function SarInt16(var V: Word; ShiftCount: Integer): Word; -begin - Result := V shr ShiftCount; - if (V and $8000) <> 0 then - Result := Result or $8000; -end; - -function SarInt32(var V: Cardinal; ShiftCount: Integer): Cardinal; -begin - Result := V shr ShiftCount; - if (V and $80000000) <> 0 then - Result := Result or $80000000; -end; - -function SarInt64(var V: TUInt64; ShiftCount: Integer): TUInt64; -begin - Result := V shr ShiftCount; - if (V and $8000000000000000) <> 0 then - Result := Result or $8000000000000000; -end; - -procedure ConstTimeConditionalSwap8(CanSwap: Boolean; var A, B: Byte); -var - T, V: Byte; -begin - T := ConstTimeExpandBoolean8(CanSwap); - V := (A xor B) and T; - A := A xor V; - B := B xor V; -end; - -procedure ConstTimeConditionalSwap16(CanSwap: Boolean; var A, B: Word); -var - T, V: Word; -begin - T := ConstTimeExpandBoolean16(CanSwap); - V := (A xor B) and T; - A := A xor V; - B := B xor V; -end; - -procedure ConstTimeConditionalSwap32(CanSwap: Boolean; var A, B: Cardinal); -var - T, V: Cardinal; -begin - T := ConstTimeExpandBoolean32(CanSwap); - V := (A xor B) and T; - A := A xor V; - B := B xor V; -end; - -procedure ConstTimeConditionalSwap64(CanSwap: Boolean; var A, B: TUInt64); -var - T, V: TUInt64; -begin - T := ConstTimeExpandBoolean64(CanSwap); - V := (A xor B) and T; - A := A xor V; - B := B xor V; -end; - -function ConstTimeEqual8(A, B: Byte): Boolean; -var - R: Byte; -begin - R := not (A xor B); // - R := R and (R shr 4); // һһ - R := R and (R shr 2); // һλ 0 - R := R and (R shr 1); // 0 - Result := Boolean(R); // ֻȫ 1 1 -end; - -function ConstTimeEqual16(A, B: Word): Boolean; -begin - Result := ConstTimeEqual8(Byte(A shr 8), Byte(B shr 8)) - and ConstTimeEqual8(Byte(A and $FF), Byte(B and $FF)); -end; - -function ConstTimeEqual32(A, B: Cardinal): Boolean; -begin - Result := ConstTimeEqual16(Word(A shr 16), Word(B shr 16)) - and ConstTimeEqual16(Word(A and $FFFF), Word(B and $FFFF)); -end; - -function ConstTimeEqual64(A, B: TUInt64): Boolean; -begin - Result := ConstTimeEqual32(Cardinal(A shr 32), Cardinal(B shr 32)) - and ConstTimeEqual32(Cardinal(A and $FFFFFFFF), Cardinal(B and $FFFFFFFF)); -end; - -function ConstTimeBytesEqual(A, B: TBytes): Boolean; -var - I: Integer; -begin - Result := False; - if Length(A) <> Length(B) then - Exit; - - Result := True; - for I := 0 to Length(A) - 1 do // ÿֽڶȽϣͬ˳ - Result := Result and (ConstTimeEqual8(A[I], B[I])); -end; - -function ConstTimeExpandBoolean8(V: Boolean): Byte; -begin - Result := Byte(V); - Result := not Result; // V True 0˲ R Ǵ $FFR ͷ 0 - Result := Result and (Result shr 4); // һһ - Result := Result and (Result shr 2); // һλ 0 - Result := Result and (Result shr 1); // 00000000 00000001 - Result := Result or (Result shl 1); // True õ 00000000False õ 00000001λ - Result := Result or (Result shl 2); - Result := Result or (Result shl 4); // ȫ 0 ȫ 1 - Result := not Result; // ȫ 1 ȫ 0 -end; - -function ConstTimeExpandBoolean16(V: Boolean): Word; -var - R: Byte; -begin - R := ConstTimeExpandBoolean8(V); - Result := R; - Result := (Result shl 8) or R; // ֽȫ 1 ȫ 0 ˫ֽ -end; - -function ConstTimeExpandBoolean32(V: Boolean): Cardinal; -var - R: Word; -begin - R := ConstTimeExpandBoolean16(V); - Result := R; - Result := (Result shl 16) or R; // ˫ֽȫ 1 ȫ 0 ֽ -end; - -function ConstTimeExpandBoolean64(V: Boolean): TUInt64; -var - R: Cardinal; -begin - R := ConstTimeExpandBoolean32(V); - Result := R; - Result := (Result shl 32) or R; // ֽȫ 1 ȫ 0 ɰֽ -end; - -function ConstTimeConditionalSelect8(Condition: Boolean; A, B: Byte): Byte; -begin - ConstTimeConditionalSwap8(Condition, A, B); - Result := B; -end; - -function ConstTimeConditionalSelect16(Condition: Boolean; A, B: Word): Word; -begin - ConstTimeConditionalSwap16(Condition, A, B); - Result := B; -end; - -function ConstTimeConditionalSelect32(Condition: Boolean; A, B: Cardinal): Cardinal; -begin - ConstTimeConditionalSwap32(Condition, A, B); - Result := B; -end; - -function ConstTimeConditionalSelect64(Condition: Boolean; A, B: TUInt64): TUInt64; -begin - ConstTimeConditionalSwap64(Condition, A, B); - Result := B; -end; - -{$IFDEF MSWINDOWS} - -{$IFDEF CPUX64} - -// 64 λ IDIV IDIV ָʵ֣ A RCX B EDX/RDX DivRes ַ R8 ModRes ַ R9 -procedure Int64DivInt32Mod(A: Int64; B: Integer; var DivRes, ModRes: Integer); assembler; -asm - PUSH RCX // RCX A - MOV RCX, RDX // B RCX - POP RAX // A RAX - XOR RDX, RDX // 64 λ - IDIV RCX - MOV [R8], EAX // ̷ R8 ָ DivRes - MOV [R9], EDX // R9 ָ ModRes -end; - -procedure UInt64DivUInt32Mod(A: TUInt64; B: Cardinal; var DivRes, ModRes: Cardinal); assembler; -asm - PUSH RCX // RCX A - MOV RCX, RDX // B RCX - POP RAX // A RAX - XOR RDX, RDX // 64 λ - DIV RCX - MOV [R8], EAX // ̷ R8 ָ DivRes - MOV [R9], EDX // R9 ָ ModRes -end; - -// 64 λ IDIV IDIV ָʵ֣ALo RCXAHi RDXB R8DivRes ĵַ R9 -procedure Int128DivInt64Mod(ALo, AHi: Int64; B: Int64; var DivRes, ModRes: Int64); assembler; -asm - MOV RAX, RCX // ALo RAXAHi Ѿ RDX - MOV RCX, R8 // B RCX - IDIV RCX - MOV [R9], RAX // ̷ R9 ָ DivRes - MOV RAX, [RBP + $30] // ModRes ַ RAX - MOV [RAX], RDX // RAX ָ ModRes -end; - -procedure UInt128DivUInt64Mod(ALo, AHi: UInt64; B: UInt64; var DivRes, ModRes: UInt64); assembler; -asm - MOV RAX, RCX // ALo RAXAHi Ѿ RDX - MOV RCX, R8 // B RCX - DIV RCX - MOV [R9], RAX // ̷ R9 ָ DivRes - MOV RAX, [RBP + $30] // ModRes ַ RAX - MOV [RAX], RDX // RAX ָ ModRes -end; - -{$ELSE} - -// 32 λ IDIV IDIV ָʵ֣ A ڶջϣB EAXDivRes ַ EDXModRes ַ ECX -procedure Int64DivInt32Mod(A: Int64; B: Integer; var DivRes, ModRes: Integer); assembler; -asm - PUSH ECX // ECX ModRes ַȱ - MOV ECX, B // B EAX УƵ ECX - PUSH EDX // DivRes ĵַ EDX УҲ - MOV EAX, [EBP + $8] // A Lo - MOV EDX, [EBP + $C] // A Hi - IDIV ECX - POP ECX // ECXõ DivRes ַ - MOV [ECX], EAX - POP ECX // ECXõ ModRes ַ - MOV [ECX], EDX -end; - -procedure UInt64DivUInt32Mod(A: TUInt64; B: Cardinal; var DivRes, ModRes: Cardinal); assembler; -asm - PUSH ECX // ECX ModRes ַȱ - MOV ECX, B // B EAX УƵ ECX - PUSH EDX // DivRes ĵַ EDX УҲ - MOV EAX, [EBP + $8] // A Lo - MOV EDX, [EBP + $C] // A Hi - DIV ECX - POP ECX // ECXõ DivRes ַ - MOV [ECX], EAX - POP ECX // ECXõ ModRes ַ - MOV [ECX], EDX -end; - -// 32 λµʵ -procedure Int128DivInt64Mod(ALo, AHi: Int64; B: Int64; var DivRes, ModRes: Int64); -var - C: Integer; -begin - if B = 0 then - raise EDivByZero.Create(SDivByZero); - - if (AHi = 0) or (AHi = $FFFFFFFFFFFFFFFF) then // 64 λΪ 0 ֵֵ - begin - DivRes := ALo div B; - ModRes := ALo mod B; - end - else - begin - if B < 0 then // Ǹ - begin - Int128DivInt64Mod(ALo, AHi, -B, DivRes, ModRes); - DivRes := -DivRes; - Exit; - end; - - if AHi < 0 then // Ǹ - begin - // AHi, ALo 󷴼 1Եõֵ - AHi := not AHi; - ALo := not ALo; -{$IFDEF SUPPORT_UINT64} - UInt64Add(UInt64(ALo), UInt64(ALo), 1, C); -{$ELSE} - UInt64Add(ALo, ALo, 1, C); -{$ENDIF} - if C > 0 then - AHi := AHi + C; - - // ת - Int128DivInt64Mod(ALo, AHi, B, DivRes, ModRes); - - // ٵ - if ModRes = 0 then - DivRes := -DivRes - else - begin - DivRes := -DivRes - 1; - ModRes := B - ModRes; - end; - Exit; - end; - - // ȫ󣬰޷ -{$IFDEF SUPPORT_UINT64} - UInt128DivUInt64Mod(TUInt64(ALo), TUInt64(AHi), TUInt64(B), TUInt64(DivRes), TUInt64(ModRes)); -{$ELSE} - UInt128DivUInt64Mod(ALo, AHi, B, DivRes, ModRes); -{$ENDIF} - end; -end; - -procedure UInt128DivUInt64Mod(ALo, AHi: TUInt64; B: TUInt64; var DivRes, ModRes: TUInt64); -var - I, Cnt: Integer; - Q, R: TUInt64; -begin - if B = 0 then - raise EDivByZero.Create(SDivByZero); - - if AHi = 0 then - begin - DivRes := UInt64Div(ALo, B); - ModRes := UInt64Mod(ALo, B); - end - else - begin - // иλеλզ죿жǷ AHi >= BʾҪ 64 λ - if UInt64Compare(AHi, B) >= 0 then - raise EIntOverflow.Create(SIntOverflow); - - Q := 0; - R := 0; - Cnt := GetUInt64LowBits(AHi) + 64; - for I := Cnt downto 0 do - begin - R := R shl 1; - if IsUInt128BitSet(ALo, AHi, I) then // ĵ I λǷ 0 - R := R or 1 - else - R := R and TUInt64(not 1); - - if UInt64Compare(R, B) >= 0 then - begin - R := R - B; - Q := Q or (TUInt64(1) shl I); - end; - end; - DivRes := Q; - ModRes := R; - end; -end; - -{$ENDIF} - -{$ENDIF} - -{$IFDEF SUPPORT_UINT64} - -// ֻҪ֧ 64 λ޷ 32/64 λ Intel ARM Delphi FPCʲôϵͳ - -function UInt64Mod(A, B: TUInt64): TUInt64; -begin - Result := A mod B; -end; - -function UInt64Div(A, B: TUInt64): TUInt64; -begin - Result := A div B; -end; - -{$ELSE} -{ - ֧ UInt64 ĵͰ汾 Delphi Int64 A mod/div B - - õջ˳ A ĸλA ĵλB ĸλB ĵλ push ϲ뺯 - ESP ǷصַESP+4 B ĵλESP + 8 B ĸλESP + C A ĵλESP + 10 A ĸλ - push esp ESP 4Ȼ mov ebp esp֮ EBP ѰַȫҪ 4 - - System.@_llumod ҪڸսʱEAX <- A ĵλEDX <- A ĸλSystem Դע EAX/EDX дˣ - [ESP + 8]Ҳ EBP + C<- B ĸλ[ESP + 4] Ҳ EBP + 8<- B ĵλ - - CALL ǰľƴ롣UInt64 Div Ҳ -} -function UInt64Mod(A, B: TUInt64): TUInt64; -asm - // PUSH ESP ESP 4Ҫ - MOV EAX, [EBP + $10] // A Lo - MOV EDX, [EBP + $14] // A Hi - PUSH DWORD PTR[EBP + $C] // B Hi - PUSH DWORD PTR[EBP + $8] // B Lo - CALL System.@_llumod; -end; - -function UInt64Div(A, B: TUInt64): TUInt64; -asm - // PUSH ESP ESP 4Ҫ - MOV EAX, [EBP + $10] // A Lo - MOV EDX, [EBP + $14] // A Hi - PUSH DWORD PTR[EBP + $C] // B Hi - PUSH DWORD PTR[EBP + $8] // B Lo - CALL System.@_lludiv; -end; - -{$ENDIF} - -{$IFDEF SUPPORT_UINT64} - -// ֻҪ֧ 64 λ޷ 32/64 λ Intel ARM Delphi FPCʲôϵͳ - -function UInt64Mul(A, B: Cardinal): TUInt64; -begin - Result := TUInt64(A) * B; -end; - -{$ELSE} // ֻеͰ汾 Delphi Win32 x86 - -{ - ޷ 32 λˣֱʹ Int64 ģ 64 λ޷ - - üĴԼ A -> EAXB -> EDXʹöջ - System.@_llmul ҪڸսʱEAX <- A ĵλEDX <- A ĸλ 0 - [ESP + 8]Ҳ EBP + C<- B ĸλ 0[ESP + 4] Ҳ EBP + 8<- B ĵλ -} -function UInt64Mul(A, B: Cardinal): TUInt64; -asm - PUSH 0 // PUSH B λ 0 - PUSH EDX // PUSH B λ - // EAX A λѾ - XOR EDX, EDX // EDX A λ 0 - CALL System.@_llmul; // EAX 32 λEDX 32 λ -end; - -{$ENDIF} - -// ޷ 64 λӣ ResLo ResHi -procedure UInt64AddUInt64(A, B: TUInt64; var ResLo, ResHi: TUInt64); -var - X, Y, Z, T, R0L, R0H, R1L, R1H: Cardinal; - R0, R1, R01, R12: TUInt64; -begin - // ˼룺2^32 ϵ M (xM+y) + (zM+t) = (x+z) M + (y+t) - // y+t R0 ռ 01x+z R1 ռ 12 R0, R1 ٲӳ R01, R12 - if IsUInt64AddOverflow(A, B) then - begin - X := Int64Rec(A).Hi; - Y := Int64Rec(A).Lo; - Z := Int64Rec(B).Hi; - T := Int64Rec(B).Lo; - - R0 := TUInt64(Y) + TUInt64(T); - R1 := TUInt64(X) + TUInt64(Z); - - R0L := Int64Rec(R0).Lo; - R0H := Int64Rec(R0).Hi; - R1L := Int64Rec(R1).Lo; - R1H := Int64Rec(R1).Hi; - - R01 := TUInt64(R0H) + TUInt64(R1L); - R12 := TUInt64(R1H) + TUInt64(Int64Rec(R01).Hi); - - Int64Rec(ResLo).Lo := R0L; - Int64Rec(ResLo).Hi := Int64Rec(R01).Lo; - Int64Rec(ResHi).Lo := Int64Rec(R12).Lo; - Int64Rec(ResHi).Hi := Int64Rec(R12).Hi; - end - else - begin - ResLo := A + B; - ResHi := 0; - end; -end; - -{$IFDEF WIN64} // ע Linux 64 ²֧ ASMֻ WIN64 - -// 64 λ޷ 64 λˣ ResLo ResHi Уֱûʵ֣һ -procedure UInt64MulUInt64(A, B: UInt64; var ResLo, ResHi: UInt64); assembler; -asm - PUSH RAX - MOV RAX, RCX - MUL RDX // ޷ţзŵ IMUL - MOV [R8], RAX - MOV [R9], RDX - POP RAX -end; - -{$ELSE} - -// ޷ 64 λˣ ResLo ResHi -procedure UInt64MulUInt64(A, B: TUInt64; var ResLo, ResHi: TUInt64); -var - X, Y, Z, T: Cardinal; - YT, XT, ZY, ZX: TUInt64; - P, R1Lo, R1Hi, R2Lo, R2Hi: TUInt64; -begin - // ˼룺2^32 ϵ M (xM+y)*(zM+t) = xzM^2 + (xt+yz)M + yt - // ϵ UInt64xz ռ 234xt+yz ռ 123yt ռ 01Ȼۼ - X := Int64Rec(A).Hi; - Y := Int64Rec(A).Lo; - Z := Int64Rec(B).Hi; - T := Int64Rec(B).Lo; - - YT := UInt64Mul(Y, T); - XT := UInt64Mul(X, T); - ZY := UInt64Mul(Y, Z); - ZX := UInt64Mul(X, Z); - - Int64Rec(ResLo).Lo := Int64Rec(YT).Lo; - - P := Int64Rec(YT).Hi; - UInt64AddUInt64(P, XT, R1Lo, R1Hi); - UInt64AddUInt64(ZY, R1Lo, R2Lo, R2Hi); - - Int64Rec(ResLo).Hi := Int64Rec(R2Lo).Lo; - - P := TUInt64(Int64Rec(R2Lo).Hi) + TUInt64(Int64Rec(ZX).Lo); - - Int64Rec(ResHi).Lo := Int64Rec(P).Lo; - Int64Rec(ResHi).Hi := Int64Rec(R1Hi).Lo + Int64Rec(R2Hi).Lo + Int64Rec(ZX).Hi + Int64Rec(P).Hi; -end; - -{$ENDIF} - -{$HINTS OFF} - -function _ValUInt64(const S: string; var Code: Integer): TUInt64; -const - FirstIndex = 1; -var - I: Integer; - Dig: Integer; - Sign: Boolean; - Empty: Boolean; -begin - I := FirstIndex; - Dig := 0; - Result := 0; - - if S = '' then - begin - Code := 1; - Exit; - end; - - while S[I] = Char(' ') do - Inc(I); - Sign := False; - - if S[I] = Char('-') then - begin - Sign := True; - Inc(I); - end - else if S[I] = Char('+') then - Inc(I); - Empty := True; - - if (S[I] = Char('$')) or (UpCase(S[I]) = Char('X')) - or ((S[I] = Char('0')) and (I < Length(S)) and (UpCase(S[I+1]) = Char('X'))) then - begin - if S[I] = Char('0') then - Inc(I); - Inc(I); - while True do - begin - case Char(S[I]) of - Char('0').. Char('9'): Dig := Ord(S[I]) - Ord('0'); - Char('A').. Char('F'): Dig := Ord(S[I]) - (Ord('A') - 10); - Char('a').. Char('f'): Dig := Ord(S[I]) - (Ord('a') - 10); - else - Break; - end; - - if Result > (CN_MAX_TUINT64 shr 4) then - Break; - if Sign and (Dig <> 0) then - Break; - - Result := Result shl 4 + TUInt64(Dig); - Inc(I); - Empty := False; - end; - end - else - begin - while True do - begin - case Char(S[I]) of - Char('0').. Char('9'): Dig := Ord(S[I]) - Ord('0'); - else - Break; - end; - - if Result > UInt64Div(CN_MAX_TUINT64, 10) then - Break; - if Sign and (Dig <> 0) then - Break; - - Result := Result * 10 + TUInt64(Dig); - Inc(I); - Empty := False; - end; - end; - - if (S[I] <> Char(#0)) or Empty then - Code := I + 1 - FirstIndex - else - Code := 0; -end; - -{$HINTS ON} - -function UInt64ToHex(N: TUInt64): string; -const - Digits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); - - function HC(B: Byte): string; - begin - Result := string(Digits[(B shr 4) and $0F] + Digits[B and $0F]); - end; - -begin - Result := - HC(Byte((N and $FF00000000000000) shr 56)) - + HC(Byte((N and $00FF000000000000) shr 48)) - + HC(Byte((N and $0000FF0000000000) shr 40)) - + HC(Byte((N and $000000FF00000000) shr 32)) - + HC(Byte((N and $00000000FF000000) shr 24)) - + HC(Byte((N and $0000000000FF0000) shr 16)) - + HC(Byte((N and $000000000000FF00) shr 8)) - + HC(Byte((N and $00000000000000FF))); -end; - -function UInt64ToStr(N: TUInt64): string; -begin - Result := Format('%u', [N]); -end; - -function StrToUInt64(const S: string): TUInt64; -{$IFNDEF DELPHIXE6_UP} -var - E: Integer; -{$ENDIF} -begin -{$IFDEF DELPHIXE6_UP} - Result := SysUtils.StrToUInt64(S); // StrToUInt64 only exists under XE6 or above -{$ELSE} - Result := _ValUInt64(S, E); - if E <> 0 then raise EConvertError.CreateResFmt(@SInvalidInteger, [S]); -{$ENDIF} -end; - -function UInt64Compare(A, B: TUInt64): Integer; -{$IFNDEF SUPPORT_UINT64} -var - HiA, HiB, LoA, LoB: Cardinal; -{$ENDIF} -begin -{$IFDEF SUPPORT_UINT64} - if A > B then - Result := 1 - else if A < B then - Result := -1 - else - Result := 0; -{$ELSE} - HiA := (A and $FFFFFFFF00000000) shr 32; - HiB := (B and $FFFFFFFF00000000) shr 32; - if HiA > HiB then - Result := 1 - else if HiA < HiB then - Result := -1 - else - begin - LoA := Cardinal(A and $00000000FFFFFFFF); - LoB := Cardinal(B and $00000000FFFFFFFF); - if LoA > LoB then - Result := 1 - else if LoA < LoB then - Result := -1 - else - Result := 0; - end; -{$ENDIF} -end; - -function UInt64Sqrt(N: TUInt64): TUInt64; -var - Rem, Root: TUInt64; - I: Integer; -begin - Result := 0; - if N = 0 then - Exit; - - if UInt64Compare(N, 4) < 0 then - begin - Result := 1; - Exit; - end; - - Rem := 0; - Root := 0; - - for I := 0 to 31 do - begin - Root := Root shl 1; - Inc(Root); - - Rem := Rem shl 2; - Rem := Rem or (N shr 62); - N := N shl 2; - - if UInt64Compare(Root, Rem) <= 0 then - begin - Rem := Rem - Root; - Inc(Root); - end - else - Dec(Root); - end; - Result := Root shr 1; -end; - -function UInt32IsNegative(N: Cardinal): Boolean; -begin - Result := (N and (1 shl 31)) <> 0; -end; - -function UInt64IsNegative(N: TUInt64): Boolean; -begin -{$IFDEF SUPPORT_UINT64} - Result := (N and (UInt64(1) shl 63)) <> 0; -{$ELSE} - Result := N < 0; -{$ENDIF} -end; - -// UInt64 ijһλ 1λ Index 0 ʼ -procedure UInt64SetBit(var B: TUInt64; Index: Integer); -begin - B := B or (TUInt64(1) shl Index); -end; - -// UInt64 ijһλ 0λ Index 0 ʼ -procedure UInt64ClearBit(var B: TUInt64; Index: Integer); -begin - B := B and not (TUInt64(1) shl Index); -end; - -// UInt64 ĵڼλǷ 10 ʼ -function GetUInt64BitSet(B: TUInt64; Index: Integer): Boolean; -begin - B := B and (TUInt64(1) shl Index); - Result := B <> 0; -end; - -// UInt64 1 ߶λǵڼλλ 0û 1 -1 -function GetUInt64HighBits(B: TUInt64): Integer; -begin - if B = 0 then - begin - Result := -1; - Exit; - end; - - Result := 1; - if B shr 32 = 0 then - begin - Inc(Result, 32); - B := B shl 32; - end; - if B shr 48 = 0 then - begin - Inc(Result, 16); - B := B shl 16; - end; - if B shr 56 = 0 then - begin - Inc(Result, 8); - B := B shl 8; - end; - if B shr 60 = 0 then - begin - Inc(Result, 4); - B := B shl 4; - end; - if B shr 62 = 0 then - begin - Inc(Result, 2); - B := B shl 2; - end; - Result := Result - Integer(B shr 63); // õǰ 0 - Result := 63 - Result; -end; - -// Cardinal 1 ߶λǵڼλλ 0û 1 -1 -function GetUInt32HighBits(B: Cardinal): Integer; -begin - if B = 0 then - begin - Result := -1; - Exit; - end; - - Result := 1; - if B shr 16 = 0 then - begin - Inc(Result, 16); - B := B shl 16; - end; - if B shr 24 = 0 then - begin - Inc(Result, 8); - B := B shl 8; - end; - if B shr 28 = 0 then - begin - Inc(Result, 4); - B := B shl 4; - end; - if B shr 30 = 0 then - begin - Inc(Result, 2); - B := B shl 2; - end; - Result := Result - Integer(B shr 31); // õǰ 0 - Result := 31 - Result; -end; - -function GetUInt16HighBits(B: Word): Integer; -begin - if B = 0 then - begin - Result := -1; - Exit; - end; - - Result := 1; - if B shr 8 = 0 then - begin - Inc(Result, 8); - B := B shl 8; - end; - if B shr 12 = 0 then - begin - Inc(Result, 4); - B := B shl 4; - end; - if B shr 14 = 0 then - begin - Inc(Result, 2); - B := B shl 2; - end; - Result := Result - Integer(B shr 15); // õǰ 0 - Result := 15 - Result; -end; - -function GetUInt8HighBits(B: Byte): Integer; -begin - if B = 0 then - begin - Result := -1; - Exit; - end; - - Result := 1; - if B shr 4 = 0 then - begin - Inc(Result, 4); - B := B shl 4; - end; - if B shr 6 = 0 then - begin - Inc(Result, 2); - B := B shl 2; - end; - Result := Result - Integer(B shr 7); // õǰ 0 - Result := 7 - Result; -end; - -// Int64 1 Ͷλǵڼλλ 0û 1 -1 -function GetUInt64LowBits(B: TUInt64): Integer; -var - Y: TUInt64; - N: Integer; -begin - Result := -1; - if B = 0 then - Exit; - - N := 63; - Y := B shl 32; - if Y <> 0 then - begin - Dec(N, 32); - B := Y; - end; - Y := B shl 16; - if Y <> 0 then - begin - Dec(N, 16); - B := Y; - end; - Y := B shl 8; - if Y <> 0 then - begin - Dec(N, 8); - B := Y; - end; - Y := B shl 4; - if Y <> 0 then - begin - Dec(N, 4); - B := Y; - end; - Y := B shl 2; - if Y <> 0 then - begin - Dec(N, 2); - B := Y; - end; - B := B shl 1; - Result := N - Integer(B shr 63); -end; - -// Cardinal 1 Ͷλǵڼλλ 0û 1 -1 -function GetUInt32LowBits(B: Cardinal): Integer; -var - Y, N: Integer; -begin - Result := -1; - if B = 0 then - Exit; - - N := 31; - Y := B shl 16; - if Y <> 0 then - begin - Dec(N, 16); - B := Y; - end; - Y := B shl 8; - if Y <> 0 then - begin - Dec(N, 8); - B := Y; - end; - Y := B shl 4; - if Y <> 0 then - begin - Dec(N, 4); - B := Y; - end; - Y := B shl 2; - if Y <> 0 then - begin - Dec(N, 2); - B := Y; - end; - B := B shl 1; - Result := N - Integer(B shr 31); -end; - -// Word 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 -function GetUInt16LowBits(B: Word): Integer; -var - Y, N: Integer; -begin - Result := -1; - if B = 0 then - Exit; - - N := 15; - Y := B shl 8; - if Y <> 0 then - begin - Dec(N, 8); - B := Y; - end; - Y := B shl 4; - if Y <> 0 then - begin - Dec(N, 4); - B := Y; - end; - Y := B shl 2; - if Y <> 0 then - begin - Dec(N, 2); - B := Y; - end; - B := B shl 1; - Result := N - Integer(B shr 15); -end; - -// Byte 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 -function GetUInt8LowBits(B: Byte): Integer; -var - N: Integer; -begin - Result := -1; - if B = 0 then - Exit; - - N := 7; - if B shr 4 = 0 then - begin - Dec(N, 4); - B := B shl 4; - end; - if B shr 6 = 0 then - begin - Dec(N, 2); - B := B shl 2; - end; - B := B shl 1; - Result := N - Integer(B shr 7); -end; - -// װ Int64 Modֵʱȡģģ -function Int64Mod(M, N: Int64): Int64; -begin - if M > 0 then - Result := M mod N - else - Result := N - ((-M) mod N); -end; - -// жһ 32 λ޷Ƿ 2 -function IsUInt32PowerOf2(N: Cardinal): Boolean; -begin - Result := (N and (N - 1)) = 0; -end; - -// жһ 64 λ޷Ƿ 2 -function IsUInt64PowerOf2(N: TUInt64): Boolean; -begin - Result := (N and (N - 1)) = 0; -end; - -// õһָ 32 λ޷ȵ 2 ݣ򷵻 0 -function GetUInt32PowerOf2GreaterEqual(N: Cardinal): Cardinal; -begin - Result := N - 1; - Result := Result or (Result shr 1); - Result := Result or (Result shr 2); - Result := Result or (Result shr 4); - Result := Result or (Result shr 8); - Result := Result or (Result shr 16); - Inc(Result); -end; - -// õһָ 64 λ޷ 2 ݣ򷵻 0 -function GetUInt64PowerOf2GreaterEqual(N: TUInt64): TUInt64; -begin - Result := N - 1; - Result := Result or (Result shr 1); - Result := Result or (Result shr 2); - Result := Result or (Result shr 4); - Result := Result or (Result shr 8); - Result := Result or (Result shr 16); - Result := Result or (Result shr 32); - Inc(Result); -end; - -// ж 32 λзǷ 32 λз -function IsInt32AddOverflow(A, B: Integer): Boolean; -var - C: Integer; -begin - C := A + B; - Result := ((A > 0) and (B > 0) and (C < 0)) or // ͬҽ˵ - ((A < 0) and (B < 0) and (C > 0)); -end; - -// ж 32 λ޷Ƿ 32 λ޷ -function IsUInt32AddOverflow(A, B: Cardinal): Boolean; -begin - Result := (A + B) < A; // ޷ӣֻҪСһ˵ -end; - -// ж 64 λзǷ 64 λз -function IsInt64AddOverflow(A, B: Int64): Boolean; -var - C: Int64; -begin - C := A + B; - Result := ((A > 0) and (B > 0) and (C < 0)) or // ͬҽ˵ - ((A < 0) and (B < 0) and (C > 0)); -end; - -// ж 64 λ޷Ƿ 64 λ޷ -function IsUInt64AddOverflow(A, B: TUInt64): Boolean; -begin - Result := UInt64Compare(A + B, A) < 0; // ޷ӣֻҪСһ˵ -end; - -function IsUInt64SubOverflowInt32(A: TUInt64; B: TUInt64): Boolean; -var - GT: Boolean; - R: TUInt64; -begin - GT := UInt64Compare(A, B) >= 0; // GT ʾ A >= B - if GT then - begin - R := A - B; - // ж 64 λ޷ŷΧ R Ƿ񳬹 MaxInt32 - Result := UInt64Compare(R, TUInt64(CN_MAX_INT32)) > 0; - end - else - begin - R := B - A; - // ж 64 λзŷΧ -R ǷС MinInt32Ҳж 64 λ޷ R Ƿ񳬹 MinInt32 ޷ʽ - Result := UInt64Compare(R, CN_MIN_INT32_IN_INT64) > 0; - end; -end; - -// 64 λ޷ӣA + B => R 1 λ -procedure UInt64Add(var R: TUInt64; A, B: TUInt64; out Carry: Integer); -begin - R := A + B; - if UInt64Compare(R, A) < 0 then // ޷ӣֻҪСһ˵ - Carry := 1 - else - Carry := 0; -end; - -// 64 λ޷A - B => Rнλ 1 λ -procedure UInt64Sub(var R: TUInt64; A, B: TUInt64; out Carry: Integer); -begin - R := A - B; - if UInt64Compare(R, A) > 0 then // ޷ֻҪڱ˵λ - Carry := 1 - else - Carry := 0; -end; - -// ж 32 λзǷ 32 λз -function IsInt32MulOverflow(A, B: Integer): Boolean; -var - T: Integer; -begin - T := A * B; - Result := (B <> 0) and ((T div B) <> A); -end; - -// ж 32 λ޷Ƿ 32 λ޷ -function IsUInt32MulOverflow(A, B: Cardinal): Boolean; -var - T: TUInt64; -begin - T := TUInt64(A) * TUInt64(B); - Result := (T = Cardinal(T)); -end; - -// ж 32 λ޷Ƿ 64 λзδҲ False ʱR ֱӷؽ -function IsUInt32MulOverflowInt64(A, B: Cardinal; out R: TUInt64): Boolean; -var - T: Int64; -begin - T := Int64(A) * Int64(B); - Result := T < 0; // Int64 ֵ˵ - if not Result then - R := TUInt64(T); -end; - -// ж 64 λзǷ 64 λз -function IsInt64MulOverflow(A, B: Int64): Boolean; -var - T: Int64; -begin - T := A * B; - Result := (B <> 0) and ((T div B) <> A); -end; - -// ָת֧ͣ 32/64 λ -function PointerToInteger(P: Pointer): Integer; -begin -{$IFDEF CPU64BITS} - // ôд Pointer ĵ 32 λ Integer - Result := Integer(P); -{$ELSE} - Result := Integer(P); -{$ENDIF} -end; - -// תָ֧ͣ 32/64 λ -function IntegerToPointer(I: Integer): Pointer; -begin -{$IFDEF CPU64BITS} - // ôд Pointer ĵ 32 λ Integer - Result := Pointer(I); -{$ELSE} - Result := Pointer(I); -{$ENDIF} -end; - -// Int64 Χĺ࣬Ҫ N 0 -function Int64NonNegativeAddMod(A, B, N: Int64): Int64; -begin - if IsInt64AddOverflow(A, B) then // Int64 - begin - if A > 0 then - begin - // A B 0 UInt64 ȡģδ UInt64 ޣע N δ Int64 ȡģС Int64 ޣɸֵ - Result := UInt64NonNegativeAddMod(A, B, N); - end - else - begin - // A B С 0ȡ UInt64 ȡģĺδ UInt64 ޣģٱһ -{$IFDEF SUPPORT_UINT64} - Result := UInt64(N) - UInt64NonNegativeAddMod(-A, -B, N); -{$ELSE} - Result := N - UInt64NonNegativeAddMod(-A, -B, N); -{$ENDIF} - end; - end - else // ֱӼ - Result := Int64NonNegativeMod(A + B, N); -end; - -// UInt64 Χĺ࣬Ҫ N 0 -function UInt64NonNegativeAddMod(A, B, N: TUInt64): TUInt64; -var - C, D: TUInt64; -begin - if IsUInt64AddOverflow(A, B) then // - begin - C := UInt64Mod(A, N); // ͸ģ - D := UInt64Mod(B, N); - if IsUInt64AddOverflow(C, D) then - begin - // ˵ģ󣬸ģûá - // һڵ 2^63N 2^63 + 1 - // = + 2^64 - // mod N = mod N + (2^64 - 1) mod N) + 1 - // N 2^63 + 1 2^64 - 2ǰӲֱӺһģ - Result := UInt64Mod(UInt64Mod(A + B, N) + UInt64Mod(CN_MAX_TUINT64, N) + 1, N); - end - else - Result := UInt64Mod(C + D, N); - end - else - begin - Result := UInt64Mod(A + B, N); - end; -end; - -function Int64NonNegativeMulMod(A, B, N: Int64): Int64; -var - Neg: Boolean; -begin - if N <= 0 then - raise EDivByZero.Create(SDivByZero); - - // ΧСֱ - if not IsInt64MulOverflow(A, B) then - begin - Result := A * B mod N; - if Result < 0 then - Result := Result + N; - Exit; - end; - - // ŵ - Result := 0; - if (A = 0) or (B = 0) then - Exit; - - Neg := False; - if (A < 0) and (B > 0) then - begin - A := -A; - Neg := True; - end - else if (A > 0) and (B < 0) then - begin - B := -B; - Neg := True; - end - else if (A < 0) and (B < 0) then - begin - A := -A; - B := -B; - end; - - // λѭ - while B <> 0 do - begin - if (B and 1) <> 0 then - Result := ((Result mod N) + (A mod N)) mod N; - - A := A shl 1; - if A >= N then - A := A mod N; - - B := B shr 1; - end; - - if Neg then - Result := N - Result; -end; - -function UInt64NonNegativeMulMod(A, B, N: TUInt64): TUInt64; -begin - Result := 0; - if (UInt64Compare(A, CN_MAX_UINT32) <= 0) and (UInt64Compare(B, CN_MAX_UINT32) <= 0) then - begin - Result := UInt64Mod(A * B, N); // 㹻СĻֱӳ˺ģ - end - else - begin - while B <> 0 do - begin - if (B and 1) <> 0 then - Result := UInt64NonNegativeAddMod(Result, A, N); - - A := UInt64NonNegativeAddMod(A, A, N); - // ôͳ㷨 A := A shl 1 N mod NΪ - - B := B shr 1; - end; - end; -end; - -// װķǸຯҲΪʱӸ豣֤ P 0 -function Int64NonNegativeMod(N: Int64; P: Int64): Int64; -begin - if P <= 0 then - raise EDivByZero.Create(SDivByZero); - - Result := N mod P; - if Result < 0 then - Inc(Result, P); -end; - -// Int64 ķǸָ -function Int64NonNegativPower(N: Int64; Exp: Integer): Int64; -var - T: Int64; -begin - if Exp < 0 then - raise ERangeError.Create(SRangeError) - else if Exp = 0 then - begin - if N <> 0 then - Result := 1 - else - raise EDivByZero.Create(SDivByZero); - end - else if Exp = 1 then - Result := N - else - begin - Result := 1; - T := N; - - while Exp > 0 do - begin - if (Exp and 1) <> 0 then - Result := Result * T; - - Exp := Exp shr 1; - T := T * T; - end; - end; -end; - -function Int64NonNegativeRoot(N: Int64; Exp: Integer): Int64; -var - I: Integer; - X: Int64; - X0, X1: Extended; -begin - if (Exp < 0) or (N < 0) then - raise ERangeError.Create(SRangeError) - else if Exp = 0 then - raise EDivByZero.Create(SDivByZero) - else if (N = 0) or (N = 1) then - Result := N - else if Exp = 2 then - Result := UInt64Sqrt(N) - else - begin - // ţٵ - I := GetUInt64HighBits(N) + 1; // õԼ Log2 N ֵ - I := (I div Exp) + 1; - X := 1 shl I; // õһϴ X0 ֵΪʼֵ - - X0 := X; - X1 := X0 - (Power(X0, Exp) - N) / (Exp * Power(X0, Exp - 1)); - - while True do - begin - if (Trunc(X0) = Trunc(X1)) and (Abs(X0 - X1) < 0.001) then - begin - Result := Trunc(X1); // Trunc ֻ֧ Int64˻ - Exit; - end; - - X0 := X1; - X1 := X0 - (Power(X0, Exp) - N) / (Exp * Power(X0, Exp - 1)); - end; - end; -end; - -function UInt64NonNegativPower(N: TUInt64; Exp: Integer): TUInt64; -var - T, RL, RH: TUInt64; -begin - if Exp < 0 then - raise ERangeError.Create(SRangeError) - else if Exp = 0 then - begin - if N <> 0 then - Result := 1 - else - raise EDivByZero.Create(SDivByZero); - end - else if Exp = 1 then - Result := N - else - begin - Result := 1; - T := N; - - while Exp > 0 do - begin - if (Exp and 1) <> 0 then - begin - UInt64MulUInt64(Result, T, RL, RH); - Result := RL; - end; - - Exp := Exp shr 1; - UInt64MulUInt64(T, T, RL, RH); - T := RL; - end; - end; -end; - -function UInt64NonNegativeRoot(N: TUInt64; Exp: Integer): TUInt64; -var - I: Integer; - X: TUInt64; - XN, X0, X1: Extended; -begin - if Exp < 0 then - raise ERangeError.Create(SRangeError) - else if Exp = 0 then - raise EDivByZero.Create(SDivByZero) - else if (N = 0) or (N = 1) then - Result := N - else if Exp = 2 then - Result := UInt64Sqrt(N) - else - begin - // ţٵ - I := GetUInt64HighBits(N) + 1; // õԼ Log2 N ֵ - I := (I div Exp) + 1; - X := 1 shl I; // õһϴ X0 ֵΪʼֵ - - X0 := UInt64ToExtended(X); - XN := UInt64ToExtended(N); - X1 := X0 - (Power(X0, Exp) - XN) / (Exp * Power(X0, Exp - 1)); - - while True do - begin - if (ExtendedToUInt64(X0) = ExtendedToUInt64(X1)) and (Abs(X0 - X1) < 0.001) then - begin - Result := ExtendedToUInt64(X1); - Exit; - end; - - X0 := X1; - X1 := X0 - (Power(X0, Exp) - XN) / (Exp * Power(X0, Exp - 1)); - end; - end; -end; - -function IsUInt128BitSet(Lo, Hi: TUInt64; N: Integer): Boolean; -begin - if N < 64 then - Result := (Lo and (TUInt64(1) shl N)) <> 0 - else - begin - Dec(N, 64); - Result := (Hi and (TUInt64(1) shl N)) <> 0; - end; -end; - -procedure SetUInt128Bit(var Lo, Hi: TUInt64; N: Integer); -begin - if N < 64 then - Lo := Lo or (TUInt64(1) shl N) - else - begin - Dec(N, 64); - Hi := Hi or (TUInt64(1) shl N); - end; -end; - -procedure ClearUInt128Bit(var Lo, Hi: TUInt64; N: Integer); -begin - if N < 64 then - Lo := Lo and not (TUInt64(1) shl N) - else - begin - Dec(N, 64); - Hi := Hi and not (TUInt64(1) shl N); - end; -end; - -function UnsignedAddWithLimitRadix(A, B, C: Cardinal; var R: Cardinal; - L, H: Cardinal): Cardinal; -begin - R := A + B + C; - if R > H then // нλ - begin - A := H - L + 1; // õ - B := R - L; // õ L ֵ - - Result := B div A; // Ƶĵڼͽ - R := L + (B mod A); // ȥƺ - end - else - Result := 0; -end; - -procedure InternalQuickSort(Mem: Pointer; L, R: Integer; ElementByteSize: Integer; - CompareProc: TCnMemSortCompareProc); -var - I, J, P: Integer; -begin - repeat - I := L; - J := R; - P := (L + R) shr 1; - repeat - while CompareProc(Pointer(TCnNativeInt(Mem) + I * ElementByteSize), - Pointer(TCnNativeInt(Mem) + P * ElementByteSize), ElementByteSize) < 0 do - Inc(I); - while CompareProc(Pointer(TCnNativeInt(Mem) + J * ElementByteSize), - Pointer(TCnNativeInt(Mem) + P * ElementByteSize), ElementByteSize) > 0 do - Dec(J); - - if I <= J then - begin - MemorySwap(Pointer(TCnNativeInt(Mem) + I * ElementByteSize), - Pointer(TCnNativeInt(Mem) + J * ElementByteSize), ElementByteSize); - - if P = I then - P := J - else if P = J then - P := I; - Inc(I); - Dec(J); - end; - until I > J; - - if L < J then - InternalQuickSort(Mem, L, J, ElementByteSize, CompareProc); - L := I; - until I >= R; -end; - -function DefaultCompareProc(P1, P2: Pointer; ElementByteSize: Integer): Integer; -begin - Result := MemoryCompare(P1, P2, ElementByteSize); -end; - -procedure MemoryQuickSort(Mem: Pointer; ElementByteSize: Integer; - ElementCount: Integer; CompareProc: TCnMemSortCompareProc); -begin - if (Mem <> nil) and (ElementCount > 0) and (ElementCount > 0) then - begin - if Assigned(CompareProc) then - InternalQuickSort(Mem, 0, ElementCount - 1, ElementByteSize, CompareProc) - else - InternalQuickSort(Mem, 0, ElementCount - 1, ElementByteSize, DefaultCompareProc); - end; -end; - -{$IFDEF COMPILER5} - -function BoolToStr(Value: Boolean; UseBoolStrs: Boolean): string; -begin - if UseBoolStrs then - begin - if Value then - Result := 'True' - else - Result := 'False'; - end - else - begin - if Value then - Result := '-1' - else - Result := '0'; - end; -end; - -{$ENDIF} - -// =========================== ѭλ ==================================== - -function RotateLeft16(A: Word; N: Integer): Word; -begin - Result := (A shl N) or (A shr (16 - N)); -end; - -function RotateRight16(A: Word; N: Integer): Word; -begin - Result := (A shr N) or (A shl (16 - N)); -end; - -function RotateLeft32(A: Cardinal; N: Integer): Cardinal; -begin - Result := (A shl N) or (A shr (32 - N)); -end; - -function RotateRight32(A: Cardinal; N: Integer): Cardinal; -begin - Result := (A shr N) or (A shl (32 - N)); -end; - -function RotateLeft64(A: TUInt64; N: Integer): TUInt64; -begin - Result := (A shl N) or (A shr (64 - N)); -end; -function RotateRight64(A: TUInt64; N: Integer): TUInt64; -begin - Result := (A shr N) or (A shl (64 - N)); -end; - -initialization - FByteOrderIsBigEndian := CurrentByteOrderIsBigEndian; - -end. +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnNative; +{* |
+================================================================================
+* ƣCnPack 
+* Ԫƣ32 λ 64 λƽ̨һЩͳһԼһʵֵԪ
+* ԪߣCnPack  (master@cnpack.org)
+*     עԪһ 32 λ 64 λƽ̨һЩͳһʵ֡
+*           Delphi XE 2 ֧ 32  64 ų NativeInt  NativeUInt 
+*           ǰ 32 λ 64 ̬仯Ӱ쵽 PointerReferenceȶ
+*           ǵԣ̶ȵ 32 λ Cardinal/Integer Ⱥ Pointer Щ
+*           ͨˣʹ 32 λҲֹ˱Ԫ˼ͣ
+*           ͬʱڵͰ汾͸߰汾 Delphi ʹá
+*
+*           ԪҲڲ֧ UInt64 ı Delphi 5/6/7  Int64 ģ UInt64
+*           ĸ㣬ӼȻ֧֣˳Ҫģ div  mod
+*           ַ Integer(APtr)  64 λ MacOS ׳ֽضϣҪ NativeInt
+*
+*           ʵ˴Сءֽת̶ʱȷĴײ㺯빤ࡣ
+*
+* ƽ̨PWin2000 + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6/7 XE 2
+*   õԪеַϱػʽ
+* ޸ļ¼2023.08.14 V2.4
+*               ϼʱ̶ĺ
+*           2022.11.11 V2.3
+*               ϼ޷ֽ˳
+*           2022.07.23 V2.2
+*               Ӽڴλ㺯תַΪ CnNative
+*           2022.06.08 V2.1
+*               ĸʱ̶ĽԼڴ浹ź
+*           2022.03.14 V2.0
+*               Ӽʮת
+*           2022.02.17 V1.9
+*                FPC ı֧
+*           2022.02.09 V1.8
+*               ڵĴСжϺ
+*           2021.09.05 V1.7
+*                Int64/UInt64 㺯
+*           2020.10.28 V1.6
+*                UInt64 صж㺯
+*           2020.09.06 V1.5
+*                UInt64 ƽĺ
+*           2020.07.01 V1.5
+*               ж 32 λ 64 λ޷Ƿĺ
+*           2020.06.20 V1.4
+*                32 λ 64 λȡ͵ 1 λλõĺ
+*           2020.01.01 V1.3
+*                32 λ޷͵ mul 㣬ڲ֧ UInt64 ϵͳ Int64 Ա
+*           2018.06.05 V1.2
+*                64 λ͵ div/mod 㣬ڲ֧ UInt64 ϵͳ Int64  
+*           2016.09.27 V1.1
+*                64 λ͵һЩ
+*           2011.07.06 V1.0
+*               Ԫʵֹ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + Classes, SysUtils, SysConst, Math {$IFDEF COMPILER5}, Windows {$ENDIF}; + // D5 Ҫ Windows е PByte +type + ECnNativeException = class(Exception); + {* Native 쳣} + +{$IFDEF COMPILER5} + PCardinal = ^Cardinal; + {* D5 System Ԫδ壬} + PByte = Windows.PByte; + {* D5 PByte Windows У汾 System У + ͳһһ¹ʹ PByte ʱ uses Windowsڿƽ̨} +{$ENDIF} + +{$IFDEF BCB5OR6} + PInt64 = ^Int64; + {* C++Builder 5/6 sysmac.h û PInt64 Ķ壨е PUINT64 Сдͬ㣩} +{$ENDIF} + +{$IFDEF SUPPORT_32_AND_64} + TCnNativeInt = NativeInt; + TCnNativeUInt = NativeUInt; + TCnNativePointer = NativeInt; + TCnNativeIntPtr = PNativeInt; + TCnNativeUIntPtr = PNativeUInt; +{$ELSE} + TCnNativeInt = Integer; + TCnNativeUInt = Cardinal; + TCnNativePointer = Integer; + TCnNativeIntPtr = PInteger; + TCnNativeUIntPtr = PCardinal; +{$ENDIF} + +{$IFDEF CPU64BITS} + TCnUInt64 = NativeUInt; + TCnInt64 = NativeInt; +{$ELSE} + {$IFDEF SUPPORT_UINT64} + TCnUInt64 = UInt64; + {$ELSE} + TCnUInt64 = packed record // ֻĽṹ + case Boolean of + True: (Value: Int64); + False: (Lo32, Hi32: Cardinal); + end; + {$ENDIF} + TCnInt64 = Int64; +{$ENDIF} + +// TUInt64 cnvcl в֧ UInt64 div mod +{$IFDEF SUPPORT_UINT64} + TUInt64 = UInt64; + {$IFNDEF SUPPORT_PUINT64} + PUInt64 = ^UInt64; + {$ENDIF} +{$ELSE} + TUInt64 = Int64; + PUInt64 = ^TUInt64; +{$ENDIF} + +{$IFNDEF SUPPORT_INT64ARRAY} + // ϵͳûж Int64Array + Int64Array = array[0..$0FFFFFFE] of Int64; + PInt64Array = ^Int64Array; +{$ENDIF} + + TUInt64Array = array of TUInt64; // ̬ƺ׺;̬гͻ + + ExtendedArray = array[0..65537] of Extended; + PExtendedArray = ^ExtendedArray; + + PCnWord16Array = ^TCnWord16Array; + TCnWord16Array = array [0..0] of Word; + +{$IFDEF POSIX64} + TCnLongWord32 = Cardinal; // Linux64/MacOS64 (or POSIX64?) LongWord is 64 Bits +{$ELSE} + TCnLongWord32 = LongWord; +{$ENDIF} + PCnLongWord32 = ^TCnLongWord32; + + TCnLongWord32Array = array [0..MaxInt div SizeOf(Integer) - 1] of TCnLongWord32; + + PCnLongWord32Array = ^TCnLongWord32Array; + +{$IFNDEF TBYTES_DEFINED} + TBytes = array of Byte; + {* ޷ֽڶ̬飬δʱ} +{$ENDIF} + + TShortInts = array of ShortInt; + {* зֽڶ̬} + + TSmallInts = array of SmallInt; + {* з˫ֽڶ̬} + + TWords = array of Word; + {* ޷˫ֽڶ̬} + + TIntegers = array of Integer; + {* зֽڶ̬} + + TCardinals = array of Cardinal; + {* ޷ֽڶ̬} + + PCnByte = ^Byte; + PCnWord = ^Word; + + TCnBitOperation = (boAnd, boOr, boXor, boNot); + {* λ} + +type + TCnMemSortCompareProc = function (P1, P2: Pointer; ElementByteSize: Integer): Integer; + {* ڴ̶ߴȽϺԭ} + +const + CN_MAX_SQRT_INT64: Cardinal = 3037000499; + CN_MAX_INT8: ShortInt = $7F; + CN_MIN_INT8: ShortInt = -128; + CN_MAX_INT16: SmallInt = $7FFF; + CN_MIN_INT16: SmallInt = -32768; + CN_MAX_INT32: Integer = $7FFFFFFF; + CN_MIN_INT32: Integer = $80000000; // 뾯棬 -2147483648 + CN_MIN_INT32_IN_INT64: Int64 = $0000000080000000; + CN_MAX_INT64: Int64 = $7FFFFFFFFFFFFFFF; + CN_MIN_INT64: Int64 = $8000000000000000; + CN_MAX_UINT8: Byte = $FF; + CN_MAX_UINT16: Word = $FFFF; + CN_MAX_UINT32: Cardinal = $FFFFFFFF; + CN_MAX_TUINT64: TUInt64 = $FFFFFFFFFFFFFFFF; + CN_MAX_SIGNED_INT64_IN_TUINT64: TUInt64 = $7FFFFFFFFFFFFFFF; + +{* + D567 Ȳ֧ UInt64 ıȻ Int64 UInt64 мӼ洢 + ˳޷ֱɣװ System е _lludiv _llumod + ʵ Int64 ʾ UInt64 ݵ div mod ܡ +} +function UInt64Mod(A: TUInt64; B: TUInt64): TUInt64; +{* 64 λ޷ࡣ + + + A: TUInt64 - + B: TUInt64 - + + ֵTUInt64 - +} + +function UInt64Div(A: TUInt64; B: TUInt64): TUInt64; +{* 64 λ޷ + + + A: TUInt64 - + B: TUInt64 - + + ֵTUInt64 - +} + +function UInt64Mul(A: Cardinal; B: Cardinal): TUInt64; +{* 32 λ޷ˡڲ֧ UInt64 ƽ̨ϣ UInt64 ʽ Int64  + ֱʹ Int64 п + + + A: Cardinal - һ + B: Cardinal - + + ֵTUInt64 - +} + +procedure UInt64AddUInt64(A: TUInt64; B: TUInt64; var ResLo: TUInt64; var ResHi: TUInt64); +{* 64 λ޷ӣ ResLo ResHi С + עڲʵְ㷨ΪӣʵResHi Ȼ 1ֱж 1 + + + A: TUInt64 - һ + B: TUInt64 - + var ResLo: TUInt64 - ͵λ + var ResHi: TUInt64 - ͸λ + + ֵޣ +} + +procedure UInt64MulUInt64(A: TUInt64; B: TUInt64; var ResLo: TUInt64; var ResHi: TUInt64); +{* 64 λ޷ˣ ResLo ResHi СWin 64 λûʵ֣Լһϡ + + + A: TUInt64 - һ + B: TUInt64 - + var ResLo: TUInt64 - λ + var ResHi: TUInt64 - λ + + ֵޣ +} + +function UInt64ToHex(N: TUInt64): string; +{* 64 λ޷תΪʮַ + + + N: TUInt64 - תֵ + + ֵstring - ʮַ +} + +function UInt64ToStr(N: TUInt64): string; +{* 64 λ޷תΪʮַ + + + N: TUInt64 - תֵ + + ֵstring - ʮַ +} + +function StrToUInt64(const S: string): TUInt64; +{* ַתΪ 64 λ޷ + + + const S: string - תַ + + ֵTUInt64 - ת +} + +function UInt64Compare(A: TUInt64; B: TUInt64): Integer; +{* Ƚ 64 λ޷ֱֵݱȽϵĽǴڡڻС 10-1 + + + A: TUInt64 - Ƚϵһ + B: TUInt64 - Ƚϵ + + ֵInteger - رȽϽ +} + +function UInt64Sqrt(N: TUInt64): TUInt64; +{* 64 λ޷ƽ֡ + + + N: TUInt64 - ƽ + + ֵTUInt64 - ƽ +} + +function UInt32IsNegative(N: Cardinal): Boolean; +{* ж 32 λ޷ 32 λзʱǷС 0 + + + N: Cardinal - жϵֵ + + ֵBoolean - ǷС 0 +} + +function UInt64IsNegative(N: TUInt64): Boolean; +{* ж 64 λ޷ 64 λзʱǷС 0 + + + N: TUInt64 - жϵֵ + + ֵBoolean - ǷС 0 +} + +procedure UInt64SetBit(var B: TUInt64; Index: Integer); +{* 64 λijһλ 1λ Index 0 ʼ 63 + + + var B: TUInt64 - λֵ + Index: Integer - 1 λ + + ֵޣ +} + +procedure UInt64ClearBit(var B: TUInt64; Index: Integer); +{* 64 λijһλ 0λ Index 0 ʼ 63 + + + var B: TUInt64 - λֵ + Index: Integer - 0 λ + + ֵޣ +} + +function GetUInt64BitSet(B: TUInt64; Index: Integer): Boolean; +{* 64 λijһλǷ 1λ Index 0 ʼ 63 + + + B: TUInt64 - жϵֵ + Index: Integer - жϵλ + + ֵBoolean - ظλǷ 1 +} + +function GetUInt64HighBits(B: TUInt64): Integer; +{* 64 λ 1 ߶λǵڼλλ 0û 1 -1 + + + B: TUInt64 - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt32HighBits(B: Cardinal): Integer; +{* 32 λ 1 ߶λǵڼλλ 0û 1 -1 + + + B: Cardinal - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt16HighBits(B: Word): Integer; +{* 16 λ 1 ߶λǵڼλλ 0û 1 -1 + + + B: Word - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt8HighBits(B: Byte): Integer; +{* 8 λ 1 ߶λǵڼλλ 0û 1 -1 + + + B: Byte - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt64LowBits(B: TUInt64): Integer; +{* 64 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 + + + B: TUInt64 - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt32LowBits(B: Cardinal): Integer; +{* 32 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 + + + B: Cardinal - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt16LowBits(B: Word): Integer; +{* 16 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 + + + B: Word - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt8LowBits(B: Byte): Integer; +{* 8 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 + + + B: Byte - жϵֵ + + ֵInteger - 1 λ +} + +function Int64Mod(M: Int64; N: Int64): Int64; +{* װ Int64 ModM ֵʱȡģģ N Ҫס + + + M: Int64 - + N: Int64 - + + ֵInt64 - +} + +function IsUInt32PowerOf2(N: Cardinal): Boolean; +{* жһ 32 λ޷Ƿ 2 ݡ + + + N: Cardinal - жϵֵ + + ֵBoolean - Ƿ 2 +} + +function IsUInt64PowerOf2(N: TUInt64): Boolean; +{* жһ 64 λ޷Ƿ 2 ݡ + + + N: TUInt64 - жϵֵ + + ֵBoolean - Ƿ 2 +} + +function GetUInt32PowerOf2GreaterEqual(N: Cardinal): Cardinal; +{* õһָ 32 λ޷ȵ 2 ݣ򷵻 0 + + + N: Cardinal - ֵ + + ֵCardinal - ط 2 ݻ 0 +} + +function GetUInt64PowerOf2GreaterEqual(N: TUInt64): TUInt64; +{* õһָ 64 λ޷ȵ 2 ݣ򷵻 0 + + + N: TUInt64 - ֵ + + ֵTUInt64 - ط 2 ݻ 0 +} + +function IsInt32AddOverflow(A: Integer; B: Integer): Boolean; +{* ж 32 λзǷ 32 λзޡ + + + A: Integer - һ + B: Integer - + + ֵBoolean - Ƿ +} + +function IsUInt32AddOverflow(A: Cardinal; B: Cardinal): Boolean; +{* ж 32 λ޷Ƿ 32 λ޷ޡ + + + A: Cardinal - һ + B: Cardinal - + + ֵBoolean - Ƿ +} + +function IsInt64AddOverflow(A: Int64; B: Int64): Boolean; +{* ж 64 λзǷ 64 λзޡ + + + A: Int64 - һ + B: Int64 - + + ֵBoolean - Ƿ +} + +function IsUInt64AddOverflow(A: TUInt64; B: TUInt64): Boolean; +{* ж 64 λ޷Ƿ 64 λ޷ޡ + + + A: TUInt64 - һ + B: TUInt64 - + + ֵBoolean - Ƿ +} + +function IsUInt64SubOverflowInt32(A: TUInt64; B: TUInt64): Boolean; +{* жһ 64 λ޷ȥһ 64 λ޷ĽǷ񳬳 32 λзΧ + 64 λе JMP תжϡ + + + A: TUInt64 - + B: TUInt64 - + + ֵBoolean - Ƿ񳬳 32 λзΧ +} + +procedure UInt64Add(var R: TUInt64; A: TUInt64; B: TUInt64; out Carry: Integer); +{* 64 λ޷ӣA + B => R 1 ýλλ㡣 + + + var R: TUInt64 - + A: TUInt64 - һ + B: TUInt64 - + out Carry: Integer - λ + + ֵޣ +} + +procedure UInt64Sub(var R: TUInt64; A: TUInt64; B: TUInt64; out Carry: Integer); +{* 64 λ޷A - B => Rнλ 1 ýλλ㡣 + + + var R: TUInt64 - + A: TUInt64 - + B: TUInt64 - + out Carry: Integer - λ + + ֵޣ +} + +function IsInt32MulOverflow(A: Integer; B: Integer): Boolean; +{* ж 32 λзǷ 32 λзޡ + + + A: Integer - һ + B: Integer - + + ֵBoolean - Ƿ +} + +function IsUInt32MulOverflow(A: Cardinal; B: Cardinal): Boolean; +{* ж 32 λ޷Ƿ 32 λ޷ + + + A: Cardinal - һ + B: Cardinal - + + ֵBoolean - Ƿ +} + +function IsUInt32MulOverflowInt64(A: Cardinal; B: Cardinal; out R: TUInt64): Boolean; +{* ж 32 λ޷Ƿ 64 λзޣδҲ False ʱR ֱӷؽ + Ҳ TrueҪµ UInt64Mul ʵʩˡ + + + A: Cardinal - һ + B: Cardinal - + out R: TUInt64 - δʱػ + + ֵBoolean - Ƿ +} + +function IsInt64MulOverflow(A: Int64; B: Int64): Boolean; +{* ж 64 λзǷ 64 λзޡ + + + A: Int64 - һ + B: Int64 - + + ֵBoolean - Ƿ +} + +function PointerToInteger(P: Pointer): Integer; +{* ָת֧ͣ 32/64 λע 64 λ¿ܻᶪ 32 λݡ + + + P: Pointer - תָ + + ֵInteger - ת +} + +function IntegerToPointer(I: Integer): Pointer; +{* תָ֧ͣ 32/64 λ + + + I: Integer - ת + + ֵPointer - תָ +} + +function Int64NonNegativeAddMod(A: Int64; B: Int64; N: Int64): Int64; +{* 64 λзΧĺ࣬Ҫ N 0 + + + A: Int64 - һ + B: Int64 - һ + N: Int64 - ģ + + ֵInt64 - Ľ +} + +function UInt64NonNegativeAddMod(A: TUInt64; B: TUInt64; N: TUInt64): TUInt64; +{* 64 λ޷Χĺ࣬Ҫ N 0 + + + A: TUInt64 - һ + B: TUInt64 - + N: TUInt64 - ģ + + ֵTUInt64 - Ľ +} + +function Int64NonNegativeMulMod(A: Int64; B: Int64; N: Int64): Int64; +{* 64 λзΧڵֱ࣬Ӽ㣬Ҫ N 0 + + + A: Int64 - һ + B: Int64 - + N: Int64 - ģ + + ֵInt64 - Ľ +} + +function UInt64NonNegativeMulMod(A: TUInt64; B: TUInt64; N: TUInt64): TUInt64; +{* 64 λ޷Χڵֱ࣬Ӽ㣬 + + + A: TUInt64 - һ + B: TUInt64 - + N: TUInt64 - ģ + + ֵTUInt64 - Ľ +} + +function Int64NonNegativeMod(N: Int64; P: Int64): Int64; +{* װ 64 λзķǸຯҲΪʱӸ豣֤ P 0 + + + N: Int64 - + P: Int64 - + + ֵInt64 - طǸĽ +} + +function Int64NonNegativPower(N: Int64; Exp: Integer): Int64; +{* 64 λзķǸָݣ + + + N: Int64 - + Exp: Integer - ָҪ 0 + + ֵInt64 - ݵĽ +} + +function Int64NonNegativeRoot(N: Int64; Exp: Integer): Int64; +{* 64 λзķǸη֣ + + + N: Int64 - + Exp: Integer - + + ֵInt64 - ؿֽ +} + +function UInt64NonNegativPower(N: TUInt64; Exp: Integer): TUInt64; +{* 64 λ޷ķǸָݣ + + + N: TUInt64 - + Exp: Integer - ָҪ 0 + + ֵTUInt64 - ݵĽ +} + +function UInt64NonNegativeRoot(N: TUInt64; Exp: Integer): TUInt64; +{* 64 λ޷ķǸη֣ + + + N: TUInt64 - + Exp: Integer - + + ֵTUInt64 - ؿֽ +} + +function CurrentByteOrderIsBigEndian: Boolean; +{* صǰڻǷǴˣҲǷеĸֽڴ洢ڽϵ͵ʼַ + ϴҵĶϰߣ粿ָ ARM MIPS + + + ޣ + + ֵBoolean - صǰڻǷǴ +} + +function CurrentByteOrderIsLittleEndian: Boolean; +{* صǰڻǷСˣҲǷеĸֽڴ洢ڽϸߵʼַ x86 벿Ĭ ARM + + + ޣ + + ֵBoolean - صǰڻǷС +} + +function Int64ToBigEndian(Value: Int64): Int64; +{* ȷ 64 λзֵΪˣС˻лת + + + Value: Int64 - ת 64 λз + + ֵInt64 - شֵ +} + +function Int32ToBigEndian(Value: Integer): Integer; +{* ȷ 32 λзֵΪˣС˻лת + + + Value: Integer - ת 32 λз + + ֵInteger - شֵ +} + +function Int16ToBigEndian(Value: SmallInt): SmallInt; +{* ȷ 16 λзֵΪˣС˻лת + + + Value: SmallInt - ת 16 λз + + ֵSmallInt - شֵ +} + +function Int64ToLittleEndian(Value: Int64): Int64; +{* ȷ 64 λзֵΪСˣڴ˻лת + + + Value: Int64 - ת 64 λз + + ֵInt64 - شֵ +} + +function Int32ToLittleEndian(Value: Integer): Integer; +{* ȷ 32 λзֵΪСˣڴ˻лת + + + Value: Integer - ת 32 λз + + ֵInteger - Сֵ +} + +function Int16ToLittleEndian(Value: SmallInt): SmallInt; +{* ȷ 16 λзֵΪСˣڴ˻лת + + + Value: SmallInt - ת 16 λз + + ֵSmallInt - Сֵ +} + +function UInt64ToBigEndian(Value: TUInt64): TUInt64; +{* ȷ 64 λ޷ֵΪˣС˻лת + + + Value: TUInt64 - ת 64 λ޷ + + ֵTUInt64 - شֵ +} + +function UInt32ToBigEndian(Value: Cardinal): Cardinal; +{* ȷ 32 λ޷ֵΪˣС˻лת + + + Value: Cardinal - ת 32 λ޷ + + ֵCardinal - شֵ +} + +function UInt16ToBigEndian(Value: Word): Word; +{* ȷ 16 λ޷ֵΪˣС˻лת + + + Value: Word - ת 16 λ޷ + + ֵWord - شֵ +} + +function UInt64ToLittleEndian(Value: TUInt64): TUInt64; +{* ȷ 64 λ޷ֵΪСˣڴ˻лת + + + Value: TUInt64 - ת 64 λ޷ + + ֵTUInt64 - شֵ +} + +function UInt32ToLittleEndian(Value: Cardinal): Cardinal; +{* ȷ 32 λ޷ֵΪСˣڴ˻лת + + + Value: Cardinal - ת 32 λ޷ + + ֵCardinal - Сֵ +} + +function UInt16ToLittleEndian(Value: Word): Word; +{* ȷ 16 λ޷ֵΪСˣڴ˻лת + + + Value: Word - ת 16 λ޷ + + ֵWord - Сֵ +} + +function Int64HostToNetwork(Value: Int64): Int64; +{* 64 λзֵֽ˳תΪֽ˳С˻лת + + + Value: Int64 - ת 64 λз + + ֵInt64 - ֽ˳ֵ +} + +function Int32HostToNetwork(Value: Integer): Integer; +{* 32 λзֵֽ˳תΪֽ˳С˻лת + + + Value: Integer - ת 32 λз + + ֵInteger - ֽ˳ֵ +} + +function Int16HostToNetwork(Value: SmallInt): SmallInt; +{* 16 λзֵֽ˳תΪֽ˳С˻лת + + + Value: SmallInt - ת 16 λз + + ֵSmallInt - ֽ˳ֵ +} + +function Int64NetworkToHost(Value: Int64): Int64; +{* 64 λзֵֽ˳תΪֽ˳С˻лת + + + Value: Int64 - ת 64 λз + + ֵInt64 - ֽ˳ֵ +} + +function Int32NetworkToHost(Value: Integer): Integer; +{* 32 λзֵֽ˳תΪֽ˳С˻лת + + + Value: Integer - ת 32 λз + + ֵInteger - ֽ˳ֵ +} + +function Int16NetworkToHost(Value: SmallInt): SmallInt; +{* 16 λзֵֽ˳תΪֽ˳С˻лת + + + Value: SmallInt - ת 16 λз + + ֵSmallInt - ֽ˳ֵ +} + +function UInt64HostToNetwork(Value: TUInt64): TUInt64; +{* 64 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: TUInt64 - ת 64 λ޷ + + ֵTUInt64 - ֽ˳ֵ +} + +function UInt32HostToNetwork(Value: Cardinal): Cardinal; +{* 32 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: Cardinal - ת 32 λ޷ + + ֵCardinal - ֽ˳ֵ +} + +function UInt16HostToNetwork(Value: Word): Word; +{* 16 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: Word - ת 16 λ޷ + + ֵWord - ֽ˳ֵ +} + +function UInt64NetworkToHost(Value: TUInt64): TUInt64; +{* 64 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: TUInt64 - ת 64 λ޷ + + ֵTUInt64 - ֽ˳ֵ +} + +function UInt32NetworkToHost(Value: Cardinal): Cardinal; +{* 32 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: Cardinal - ת 32 λ޷ + + ֵCardinal - ֽ˳ֵ +} + +function UInt16NetworkToHost(Value: Word): Word; +{* 16 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: Word - ת 16 λ޷ + + ֵWord - ֽ˳ֵ +} + +procedure MemoryNetworkToHost(Mem: Pointer; MemByteLen: Integer); +{* һƬڴֽ˳תΪֽ˳С˻лת + ÷ӦóϽ٣¶ġֽתѾ㹻 + + + Mem: Pointer - תݿַ + MemByteLen: Integer - תݿֽڳ + + ֵޣ +} + +procedure MemoryHostToNetwork(Mem: Pointer; MemByteLen: Integer); +{* һƬڴֽ˳תΪֽ˳С˻лת + ÷ӦóϽ٣¶ġֽתѾ㹻 + + + Mem: Pointer - תݿַ + MemByteLen: Integer - תݿֽڳ + + ֵޣ +} + +procedure ReverseMemory(Mem: Pointer; MemByteLen: Integer); +{* ֽ˳һڴ飬ֽڲ䡣 + + + Mem: Pointer - õݿַ + MemByteLen: Integer - õݿֽڳ + + ֵޣ +} + +function ReverseBitsInInt8(V: Byte): Byte; +{* һֽڲλݡ + + + V: Byte - õһֽ + + ֵByte - صֵ +} + +function ReverseBitsInInt16(V: Word): Word; +{* öֽڼڲλݡ + + + V: Word - õĶֽ + + ֵWord - صֵ +} + +function ReverseBitsInInt32(V: Cardinal): Cardinal; +{* ֽڼڲλݡ + + + V: Cardinal - õֽ + + ֵCardinal - صֵ +} + +function ReverseBitsInInt64(V: Int64): Int64; +{* ðֽڼڲλݡ + + + V: Int64 - õİֽ + + ֵInt64 - صֵ +} + +procedure ReverseMemoryWithBits(Mem: Pointer; MemByteLen: Integer); +{* ֽ˳һڴ飬ÿֽҲ + + + Mem: Pointer - õݿַ + MemByteLen: Integer - õݿֽڳ + + ֵޣ +} + +procedure MemoryAnd(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +{* 鳤ͬڴ AMem BMem λ룬 ResMem У߿ͬ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + ResMem: Pointer - ݿַ + + ֵޣ +} + +procedure MemoryOr(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +{* 鳤ͬڴ AMem BMem λ򣬽 ResMem У߿ͬ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + ResMem: Pointer - ݿַ + + ֵޣ +} + +procedure MemoryXor(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +{* 鳤ͬڴ AMem BMem λ򣬽 ResMem У߿ͬ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + ResMem: Pointer - ݿַ + + ֵޣ +} + +procedure MemoryNot(Mem: Pointer; MemByteLen: Integer; ResMem: Pointer); +{* һڴ AMem ȡ ResMem У߿ͬ + + + Mem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + ResMem: Pointer - ݿַ + + ֵޣ +} + +procedure MemoryShiftLeft(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; BitCount: Integer); +{* AMem ڴ BitCount λ BMemڴַλƣλ 0߿ȡ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + BitCount: Integer - Ƶλ + + ֵޣ +} + +procedure MemoryShiftRight(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; BitCount: Integer); +{* AMem ڴ BitCount λ BMemڴַλƣλ 0߿ȡ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + BitCount: Integer - Ƶλ + + ֵޣ +} + +function MemoryIsBitSet(Mem: Pointer; N: Integer): Boolean; +{* ڴij Bit λǷ 1ڴַλ 0ֽڻұΪ 0 + + + Mem: Pointer - ݿַ + N: Integer - λ + + ֵBoolean - Ƿ 1 +} + +procedure MemorySetBit(Mem: Pointer; N: Integer); +{* ڴij Bit λ 1ڴַλ 0ֽڻұΪ 0 + + + Mem: Pointer - ݿַ + N: Integer - λ + + ֵޣ +} + +procedure MemoryClearBit(Mem: Pointer; N: Integer); +{* ڴij Bit λ 0ڴַλ 0ֽڻұΪ 0 + + + Mem: Pointer - ݿַ + N: Integer - λ + + ֵޣ +} + +function MemoryToBinStr(Mem: Pointer; MemByteLen: Integer; Sep: Boolean = False): string; +{* һڴݴӵ͵ֽ˳ΪַSep ʾֽ֮Ƿոָ + + + Mem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + Sep: Boolean - ֽ֮Ƿÿոָ + + ֵstring - ضַ +} + +procedure MemorySwap(AMem: Pointer; BMem: Pointer; MemByteLen: Integer); +{* ͬȵڴݣͬڴʲô + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + + ֵޣ +} + +function MemoryCompare(AMem: Pointer; BMem: Pointer; MemByteLen: Integer): Integer; +{* ޷ķʽȽڴ棬 10-1ͬڴֱӷ 0 + + + AMem: Pointer - Ƚϵݿַһ + BMem: Pointer - Ƚϵݿַ + MemByteLen: Integer - Ƚϵݿֽڳ + + ֵInteger - رȽϵĽ +} + +procedure MemoryQuickSort(Mem: Pointer; ElementByteSize: Integer; + ElementCount: Integer; CompareProc: TCnMemSortCompareProc = nil); +{* Թ̶СԪص + + + Mem: Pointer - ݿַ + ElementByteSize: Integer - Ԫֽڳ + ElementCount: Integer - ݿԪصĸ + CompareProc: TCnMemSortCompareProc - ԪرȽϵĻص + + ֵޣ +} + +function UInt8ToBinStr(V: Byte): string; +{* һ 8 λ޷תΪַ + + + V: Byte - ת 8 λ޷ + + ֵstring - ضַ +} + +function UInt16ToBinStr(V: Word): string; +{* һ 16 λ޷תΪַ + + + V: Word - ת 16 λ޷ + + ֵstring - ضַ +} + +function UInt32ToBinStr(V: Cardinal): string; +{* һ 32 λ޷תΪַ + + + V: Cardinal - ת 32 λ޷ + + ֵstring - ضַ +} + +function UInt32ToStr(V: Cardinal): string; +{* һ 32 λ޷תΪʮַ + + + V: Cardinal - ת 32 λ޷ + + ֵstring - ʮַ +} + +function UInt64ToBinStr(V: TUInt64): string; +{* һ 64 λ޷תΪַ + + + V: TUInt64 - ת 64 λ޷ + + ֵstring - ضַ +} + +function HexToInt(const Hex: string): Integer; overload; +{* һʮַתΪͣʺϽ϶ 2 ַַ + + + const Hex: string - תʮַ + + ֵInteger - +} + +function HexToInt(Hex: PChar; CharLen: Integer): Integer; overload; +{* һʮַָָתΪͣʺϽ϶ 2 ַַ + + + Hex: PChar - תʮַַ + CharLen: Integer - ַ + + ֵInteger - +} + +function IsHexString(const Hex: string): Boolean; +{* жһַǷϷʮִַСд + + + const Hex: string - жϵʮַ + + ֵBoolean - ǷǺϷʮַ +} + +function DataToHex(InData: Pointer; ByteLength: Integer; UseUpperCase: Boolean = True): string; +{* ڴתΪʮַڴλݳַ󷽣൱ֽ˳ + UseUpperCase ݵĴСд + + + InData: Pointer - תݿַ + ByteLength: Integer - תݿֽڳ + UseUpperCase: Boolean - ʮַڲǷд + + ֵstring - ʮַ +} + +function HexToData(const Hex: string; OutData: Pointer = nil): Integer; +{* ʮַתΪڴ飬ַ󷽵ݳڴλ൱ֽ˳ + ʮַΪתʧʱ׳쳣תɹֽ + ע OutData Ӧָ㹻תݵֽڳΪ Length(Hex) div 2 + nilֻֽڳȣʽת + + + const Hex: string - תʮַ + OutData: Pointer - ֽڳӦΪ Length(Hex) div 2 + + ֵInteger - תֽڳ +} + +function StringToHex(const Data: string; UseUpperCase: Boolean = True): string; +{* ַתΪʮַUseUpperCase ݵĴСд + + + const Data: string - תַ + UseUpperCase: Boolean - ʮַڲǷд + + ֵstring - תʮַ +} + +function HexToString(const Hex: string): string; +{* ʮַתΪַʮַΪתʧʱ׳쳣 + + + const Hex: string - תʮַ + + ֵstring - תַ +} + +function HexToAnsiStr(const Hex: AnsiString): AnsiString; +{* ʮַתΪַʮַΪתʧʱ׳쳣 + + + const Hex: AnsiString - תʮַ + + ֵAnsiString - תַ +} + +function AnsiStrToHex(const Data: AnsiString; UseUpperCase: Boolean = True): AnsiString; +{* AnsiString תΪʮַUseUpperCase ݵĴСд + + + const Data: AnsiString - תַ + UseUpperCase: Boolean - ʮַڲǷд + + ֵAnsiString - ʮַ +} + +function BytesToHex(Data: TBytes; UseUpperCase: Boolean = True): string; +{* ֽתΪʮַ±λݳַ󷽣൱ֽ˳ + UseUpperCase ݵĴСд + + + Data: TBytes - תֽ + UseUpperCase: Boolean - ʮַڲǷд + + ֵstring - ʮַ +} + +function HexToBytes(const Hex: string): TBytes; +{* ʮַתΪֽ飬ַߵݳ±λ൱ֽ˳ + ַΪתʧʱ׳쳣 + + + const Hex: string - תʮַ + + ֵTBytes - ½ֽ +} + +function StreamToHex(Stream: TStream; UseUpperCase: Boolean = True): string; +{* еȫݴͷתΪʮַ + + + Stream: TStream - + UseUpperCase: Boolean - ʮַڲǷд + + ֵstring - ʮַ +} + +function HexToStream(const Hex: string; Stream: TStream): Integer; +{* ʮַתдУдֽ + + + const Hex: string - תʮַ + Stream: TStream - д + + ֵInteger - дֽ +} + +procedure ReverseBytes(Data: TBytes); +{* ֽ˳һֽ顣 + + + Data: TBytes - õֽ + + ֵޣ +} + +function CloneBytes(Data: TBytes): TBytes; +{* һµֽ + + + Data: TBytes - Ƶֽ + + ֵTBytes - ½ֽ +} + +function StreamToBytes(Stream: TStream): TBytes; +{* ͷȫֽ飬½ֽ顣 + + + Stream: TStream - + + ֵTBytes - ½ֽ +} + +function BytesToStream(Data: TBytes; OutStream: TStream): Integer; +{* ֽдԭʼдֽ + + + Data: TBytes - дֽ + OutStream: TStream - д + + ֵInteger - дֽ +} + +function AnsiToBytes(const Str: AnsiString): TBytes; +{* AnsiString ֱתΪֽ飬롣 + + + const Str: AnsiString - תַ + + ֵTBytes - תֽ +} + +function BytesToAnsi(Data: TBytes): AnsiString; +{* ֱֽתΪ AnsiString롣 + + + Data: TBytes - תֽ + + ֵAnsiString - תַ +} + +function BytesToString(Data: TBytes): string; +{* ֽתΪ stringڲ Byte ֵΪ Char롣 + + + Data: TBytes - תֽ + + ֵstring - תַ +} + +function MemoryToString(Mem: Pointer; MemByteLen: Integer): string; +{* ڴתΪ stringڲֽڸֵ롣 + + + Mem: Pointer - תݿַ + MemByteLen: Integer - תݿֽڳ + + ֵstring - תַ +} + +function BitsToString(Bits: TBits): string; +{* λתΪ 0 1 ַ + + + Bits: TBits - תλ + + ֵstring - תַ +} + +function ConcatBytes(A: TBytes; B: TBytes): TBytes; +{* A B ֽ˳ƴ÷һֽ飬A B ֲ䡣 + + + A: TBytes - ƴӵֽһ + B: TBytes - ƴӵֽ + + ֵTBytes - ƴӵֽ +} + +function NewBytesFromMemory(Data: Pointer; DataByteLen: Integer): TBytes; +{* ½һֽ飬һƬڴݹ + + + Data: Pointer - ݿַ + DataByteLen: Integer - ݿֽڳ + + ֵTBytes - ½ֽ +} + +function CompareBytes(A: TBytes; B: TBytes): Boolean; overload; +{* ȽֽǷͬ + + + A: TBytes - Ƚϵֽһ + B: TBytes - Ƚϵֽ + + ֵBoolean - رȽϽǷͬ +} + +function CompareBytes(A: TBytes; B: TBytes; MaxLength: Integer): Boolean; overload; +{* Ƚֽǰ MaxLength ֽڵǷͬ + + + A: TBytes - Ƚϵֽһ + B: TBytes - Ƚϵֽ + MaxLength: Integer - Ƚϵֽ + + ֵBoolean - رȽϽǷͬ +} + +function MoveMost(const Source; var Dest; ByteLen: Integer; MostLen: Integer): Integer; +{* Source ƶ ByteLen Ҳ MostLen ֽڵ Dest Уʵƶֽ + ByteLen С MostLen Dest 0Ҫ Dest MostLen + + + const Source - ƶԴλáַ + var Dest - ƶĿλáַҪ MostLen ֽ + ByteLen: Integer - ƶֽ + MostLen: Integer - ƶֽ + + ֵInteger - ʵƶֽ +} + +// =============================== =================================== + +function SarInt8(var V: Byte; ShiftCount: Integer): Byte; +{* һ 8 λƣҲDZλơ + + + var V: Byte - Ƶ 8 λ + ShiftCount: Integer - Ƶλ + + ֵByte - λֵ +} + +function SarInt16(var V: Word; ShiftCount: Integer): Word; +{* һ 16 λƣҲDZλơ + + + var V: Word - Ƶ 16 λ + ShiftCount: Integer - Ƶλ + + ֵWord - λֵ +} + +function SarInt32(var V: Cardinal; ShiftCount: Integer): Cardinal; +{* һ 32 λƣҲDZλơ + + + var V: Cardinal - Ƶ 32 λ + ShiftCount: Integer - Ƶλ + + ֵCardinal - λֵ +} + +function SarInt64(var V: TUInt64; ShiftCount: Integer): TUInt64; +{* һ 64 λƣҲDZλơ + + + var V: TUInt64 - Ƶ 64 λ + ShiftCount: Integer - Ƶλ + + ֵTUInt64 - λֵ +} + +// ================ ִʱ̶ if жϵIJ߼ =============== + +procedure ConstTimeConditionalSwap8(CanSwap: Boolean; var A: Byte; var B: Byte); +{* 8 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B + + + CanSwap: Boolean - Ƿ񽻻 + var A: Byte - 8 λͱһ + var B: Byte - 8 λͱ + + ֵޣ +} + +procedure ConstTimeConditionalSwap16(CanSwap: Boolean; var A: Word; var B: Word); +{* 16 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B + + + CanSwap: Boolean - Ƿ񽻻 + var A: Word - 16 λͱһ + var B: Word - 16 λͱ + + ֵޣ +} + +procedure ConstTimeConditionalSwap32(CanSwap: Boolean; var A: Cardinal; var B: Cardinal); +{* 32 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B + + + CanSwap: Boolean - Ƿ񽻻 + var A: Cardinal - 32 λͱһ + var B: Cardinal - 32 λͱ + + ֵޣ +} + +procedure ConstTimeConditionalSwap64(CanSwap: Boolean; var A: TUInt64; var B: TUInt64); +{* 64 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B + + + CanSwap: Boolean - Ƿ񽻻 + var A: TUInt64 - 64 λͱһ + var B: TUInt64 - 64 λͱ + + ֵޣ +} + +function ConstTimeEqual8(A: Byte; B: Byte): Boolean; +{* ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True + + + A: Byte - Ƚϵ 8 λͱһ + B: Byte - Ƚϵ 8 λͱ + + ֵBoolean - Ƿ +} + +function ConstTimeEqual16(A: Word; B: Word): Boolean; +{* ˫ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True + + + A: Word - Ƚϵ 16 λͱһ + B: Word - Ƚϵ 16 λͱ + + ֵBoolean - Ƿ +} + +function ConstTimeEqual32(A: Cardinal; B: Cardinal): Boolean; +{* ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True + + + A: Cardinal - Ƚϵ 32 λͱһ + B: Cardinal - Ƚϵ 32 λͱ + + ֵBoolean - Ƿ +} + +function ConstTimeEqual64(A: TUInt64; B: TUInt64): Boolean; +{* ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True + + + A: TUInt64 - Ƚϵ 64 λͱһ + B: TUInt64 - Ƚϵ 64 λͱ + + ֵBoolean - Ƿ +} + +function ConstTimeBytesEqual(A: TBytes; B: TBytes): Boolean; +{* ͬȵִֽʱ̶ıȽϣͬʱ True + + + A: TBytes - Ƚϵֽһ + B: TBytes - Ƚϵֽ + + ֵBoolean - Ƿ +} + +function ConstTimeExpandBoolean8(V: Boolean): Byte; +{* V ֵ 8 λȫ 1 ȫ 0 + + + V: Boolean - Ƿ񷵻ȫ 1 + + ֵByte - $FF 0 +} + +function ConstTimeExpandBoolean16(V: Boolean): Word; +{* V ֵ 16 λȫ 1 ȫ 0 + + + V: Boolean - Ƿ񷵻ȫ 1 + + ֵWord - $FFFF 0 +} + +function ConstTimeExpandBoolean32(V: Boolean): Cardinal; +{* V ֵ 32 λȫ 1 ȫ 0 + + + V: Boolean - Ƿ񷵻ȫ 1 + + ֵCardinal - $FFFFFFFF 0 +} + +function ConstTimeExpandBoolean64(V: Boolean): TUInt64; +{* V ֵ 64 λȫ 1 ȫ 0 + + + V: Boolean - Ƿ񷵻ȫ 1 + + ֵTUInt64 - $FFFFFFFFFFFFFFFF 0 +} + +function ConstTimeConditionalSelect8(Condition: Boolean; A: Byte; B: Byte): Byte; +{* ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B + + + Condition: Boolean - Ƿѡ A ҲDzһ + A: Byte - ѡ 8 λһ + B: Byte - ѡ 8 λ + + ֵByte - ѡ 8 λ +} + +function ConstTimeConditionalSelect16(Condition: Boolean; A: Word; B: Word): Word; +{* ˫ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B + + + Condition: Boolean - Ƿѡ A ҲDzһ + A: Word - ѡ 16 λһ + B: Word - ѡ 16 λ + + ֵWord - ѡ 16 λ +} + +function ConstTimeConditionalSelect32(Condition: Boolean; A: Cardinal; B: Cardinal): Cardinal; +{* ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B + + + Condition: Boolean - Ƿѡ A ҲDzһ + A: Cardinal - ѡ 32 λһ + B: Cardinal - ѡ 32 λ + + ֵCardinal - ѡ 32 λ +} + +function ConstTimeConditionalSelect64(Condition: Boolean; A: TUInt64; B: TUInt64): TUInt64; +{* ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B + + + Condition: Boolean - Ƿѡ A ҲDzһ + A: TUInt64 - ѡ 64 λһ + B: TUInt64 - ѡ 64 λ + + ֵTUInt64 - ѡ 64 λ +} + +// ================ ִʱ̶ if жϵIJ߼ =============== + +{$IFDEF MSWINDOWS} + +// ĸΪ Intel ֻ֧࣬ 32 λ 64 λ Intel CPUӦCPUX86 CPUX64 + +procedure Int64DivInt32Mod(A: Int64; B: Integer; + var DivRes: Integer; var ModRes: Integer); +{* 64 λз 32 λз̷ DivRes ModRes + б֤ 32 λΧڣ쳣 + + + A: Int64 - + B: Integer - + var DivRes: Integer - + var ModRes: Integer - + + ֵޣ +} + +procedure UInt64DivUInt32Mod(A: TUInt64; B: Cardinal; + var DivRes: Cardinal; var ModRes: Cardinal); +{* 64 λ޷ 32 λ޷̷ DivRes ModRes + б֤ 32 λΧڣ쳣 + + + A: TUInt64 - + B: Cardinal - + var DivRes: Cardinal - + var ModRes: Cardinal - + + ֵޣ +} + +procedure Int128DivInt64Mod(ALo: Int64; AHi: Int64; B: Int64; + var DivRes: Int64; var ModRes: Int64); +{* 128 λз 64 λз̷ DivRes ModRes + б֤ 64 λΧڣ쳣 + + + ALo: Int64 - 64 λ + AHi: Int64 - 64 λ + B: Int64 - + var DivRes: Int64 - + var ModRes: Int64 - + + ֵޣ +} + +procedure UInt128DivUInt64Mod(ALo: TUInt64; AHi: TUInt64; B: TUInt64; + var DivRes: TUInt64; var ModRes: TUInt64); +{* 128 λ޷ 64 λ޷̷ DivRes ModRes + б֤ 64 λΧڣ쳣 + + + ALo: TUInt64 - 64 λ + AHi: TUInt64 - 64 λ + B: TUInt64 - + var DivRes: TUInt64 - + var ModRes: TUInt64 - + + ֵޣ +} + +{$ENDIF} + +function IsUInt128BitSet(Lo: TUInt64; Hi: TUInt64; N: Integer): Boolean; +{* Int64 ƴɵ 128 λ֣ص N λǷΪ 1N 0 127 + + + Lo: TUInt64 - жϵĵ 64 λ + Hi: TUInt64 - жϵĸ 64 λ + N: Integer - жϵλ + + ֵBoolean - ǷΪ 1 +} + +procedure SetUInt128Bit(var Lo: TUInt64; var Hi: TUInt64; N: Integer); +{* Int64 ƴɵ 128 λ֣õ N λΪ 1N 0 127 + + + var Lo: TUInt64 - õĵ 64 λ + var Hi: TUInt64 - õĸ 64 λ + N: Integer - õλ + + ֵޣ +} + +procedure ClearUInt128Bit(var Lo: TUInt64; var Hi: TUInt64; N: Integer); +{* Int64 ƴɵ 128 λ֣ N λN 0 127 + + + var Lo: TUInt64 - õĵ 64 λ + var Hi: TUInt64 - õĸ 64 λ + N: Integer - õλ + + ֵޣ +} + +function UnsignedAddWithLimitRadix(A: Cardinal; B: Cardinal; C: Cardinal; + var R: Cardinal; L: Cardinal; H: Cardinal): Cardinal; +{* Ƶ޷żӷA + B + C R Уؽλֵ + ȷ L H ıڣûȷ H LΡ + úַӳ䣬 C һǽλ + + + A: Cardinal - һ + B: Cardinal - + C: Cardinal - һǽλ + var R: Cardinal - + L: Cardinal - ͵ + H: Cardinal - ͵ + + ֵCardinal - Ƿнλ +} + +// =========================== ѭλ ==================================== + +// ע N Ӧ (0, A λ) ڣ N Ϊ 0 A λʱֵӦΪ A +// N ʱࣨΪͲȲͬ 32 λ AN Ϊ 33 ʱֵ N Ϊ 1 ʱķֵ + +function RotateLeft16(A: Word; N: Integer): Word; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 16 λѭ N λ + + + A: Word - ѭƵ 16 λ + N: Integer - ѭƵλ + + ֵWord - λֵ +} + +function RotateRight16(A: Word; N: Integer): Word; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 16 λѭ N λ + + + A: Word - ѭƵ 16 λ + N: Integer - ѭƵλ + + ֵWord - λֵ +} + +function RotateLeft32(A: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 32 λѭ N λ + + + A: Cardinal - ѭƵ 32 λ + N: Integer - ѭƵλ + + ֵCardinal - λֵ +} + +function RotateRight32(A: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 32 λѭ N λ + + + A: Cardinal - ѭƵ 32 λ + N: Integer - ѭƵλ + + ֵCardinal - λֵ +} + +function RotateLeft64(A: TUInt64; N: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 64 λѭ N λ + + + A: TUInt64 - ѭƵ 64 λ + N: Integer - ѭƵλ + + ֵTUInt64 - λֵ +} + +function RotateRight64(A: TUInt64; N: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 64 λѭ N λ + + + A: TUInt64 - ѭƵ 64 λ + N: Integer - ѭƵλ + + ֵTUInt64 - λֵ +} + +{$IFDEF COMPILER5} + +function BoolToStr(Value: Boolean; UseBoolStrs: Boolean = False): string; +{* תΪַDelphi 5 ûи BoolToStr ϡ + + + Value: Boolean - תIJֵ + UseBoolStrs: Boolean - Ƿ񷵻Ӣĵ + + ֵstring - UseBoolStrs Ϊ False ʱ -1 0򷵻 True False +} + +{$ENDIF} + +implementation + +uses + CnFloat; + +resourcestring + SCnErrorNotAHexPChar = 'Error: NOT a Hex PChar: %c'; + SCnErrorLengthNotHex = 'Error Length %d: NOT a Hex String'; + SCnErrorLengthNotHexAnsi = 'Error Length %d: NOT a Hex AnsiString'; + +var + FByteOrderIsBigEndian: Boolean = False; + +function CurrentByteOrderIsBigEndian: Boolean; +type + TByteOrder = packed record + case Boolean of + False: (C: array[0..1] of Byte); + True: (W: Word); + end; +var + T: TByteOrder; +begin + T.W := $00CC; + Result := T.C[1] = $CC; +end; + +function CurrentByteOrderIsLittleEndian: Boolean; +begin + Result := not CurrentByteOrderIsBigEndian; +end; + +function ReverseInt64(Value: Int64): Int64; +var + Lo, Hi: Cardinal; + Rec: Int64Rec; +begin + Lo := Int64Rec(Value).Lo; + Hi := Int64Rec(Value).Hi; + Lo := ((Lo and $000000FF) shl 24) or ((Lo and $0000FF00) shl 8) + or ((Lo and $00FF0000) shr 8) or ((Lo and $FF000000) shr 24); + Hi := ((Hi and $000000FF) shl 24) or ((Hi and $0000FF00) shl 8) + or ((Hi and $00FF0000) shr 8) or ((Hi and $FF000000) shr 24); + Rec.Lo := Hi; + Rec.Hi := Lo; + Result := Int64(Rec); +end; + +function ReverseUInt64(Value: TUInt64): TUInt64; +var + Lo, Hi: Cardinal; + Rec: Int64Rec; +begin + Lo := Int64Rec(Value).Lo; + Hi := Int64Rec(Value).Hi; + Lo := ((Lo and $000000FF) shl 24) or ((Lo and $0000FF00) shl 8) + or ((Lo and $00FF0000) shr 8) or ((Lo and $FF000000) shr 24); + Hi := ((Hi and $000000FF) shl 24) or ((Hi and $0000FF00) shl 8) + or ((Hi and $00FF0000) shr 8) or ((Hi and $FF000000) shr 24); + Rec.Lo := Hi; + Rec.Hi := Lo; + Result := TUInt64(Rec); +end; + +function Int64ToBigEndian(Value: Int64): Int64; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := ReverseInt64(Value); +end; + +function Int32ToBigEndian(Value: Integer): Integer; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) + or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24); +end; + +function Int16ToBigEndian(Value: SmallInt): SmallInt; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8); +end; + +function Int64ToLittleEndian(Value: Int64): Int64; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := ReverseInt64(Value); +end; + +function Int32ToLittleEndian(Value: Integer): Integer; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) + or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24); +end; + +function Int16ToLittleEndian(Value: SmallInt): SmallInt; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8); +end; + +function UInt64ToBigEndian(Value: TUInt64): TUInt64; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := ReverseUInt64(Value); +end; + +function UInt32ToBigEndian(Value: Cardinal): Cardinal; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) + or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24); +end; + +function UInt16ToBigEndian(Value: Word): Word; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := Word((Value and $00FF) shl 8) or Word((Value and $FF00) shr 8); +end; + +function UInt64ToLittleEndian(Value: TUInt64): TUInt64; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := ReverseUInt64(Value); +end; + +function UInt32ToLittleEndian(Value: Cardinal): Cardinal; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) + or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24); +end; + +function UInt16ToLittleEndian(Value: Word): Word; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := Word((Value and $00FF) shl 8) or Word((Value and $FF00) shr 8); +end; + +function Int64HostToNetwork(Value: Int64): Int64; +begin + if not FByteOrderIsBigEndian then + Result := ReverseInt64(Value) + else + Result := Value; +end; + +function Int32HostToNetwork(Value: Integer): Integer; +begin + if not FByteOrderIsBigEndian then + Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) + or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24) + else + Result := Value; +end; + +function Int16HostToNetwork(Value: SmallInt): SmallInt; +begin + if not FByteOrderIsBigEndian then + Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8) + else + Result := Value; +end; + +function Int64NetworkToHost(Value: Int64): Int64; +begin + if not FByteOrderIsBigEndian then + REsult := ReverseInt64(Value) + else + Result := Value; +end; + +function Int32NetworkToHost(Value: Integer): Integer; +begin + if not FByteOrderIsBigEndian then + Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) + or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24) + else + Result := Value; +end; + +function Int16NetworkToHost(Value: SmallInt): SmallInt; +begin + if not FByteOrderIsBigEndian then + Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8) + else + Result := Value; +end; + +function UInt64HostToNetwork(Value: TUInt64): TUInt64; +begin + if CurrentByteOrderIsBigEndian then + Result := Value + else + Result := ReverseUInt64(Value); +end; + +function UInt32HostToNetwork(Value: Cardinal): Cardinal; +begin + if not FByteOrderIsBigEndian then + Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) + or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24) + else + Result := Value; +end; + +function UInt16HostToNetwork(Value: Word): Word; +begin + if not FByteOrderIsBigEndian then + Result := ((Value and $00FF) shl 8) or ((Value and $FF00) shr 8) + else + Result := Value; +end; + +function UInt64NetworkToHost(Value: TUInt64): TUInt64; +begin + if CurrentByteOrderIsBigEndian then + Result := Value + else + Result := ReverseUInt64(Value); +end; + +function UInt32NetworkToHost(Value: Cardinal): Cardinal; +begin + if not FByteOrderIsBigEndian then + Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) + or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24) + else + Result := Value; +end; + +function UInt16NetworkToHost(Value: Word): Word; +begin + if not FByteOrderIsBigEndian then + Result := ((Value and $00FF) shl 8) or ((Value and $FF00) shr 8) + else + Result := Value; +end; + +function ReverseBitsInInt8(V: Byte): Byte; +begin + // 0 1 2 3 4 5 6 7 + V := ((V and $AA) shr 1) or ((V and $55) shl 1); + // 01 23 45 67 + V := ((V and $CC) shr 2) or ((V and $33) shl 2); + // 0123 4567 + V := (V shr 4) or (V shl 4); + Result := V; +end; + +function ReverseBitsInInt16(V: Word): Word; +begin + Result := (ReverseBitsInInt8(V and $00FF) shl 8) + or ReverseBitsInInt8((V and $FF00) shr 8); +end; + +function ReverseBitsInInt32(V: Cardinal): Cardinal; +begin + Result := (ReverseBitsInInt16(V and $0000FFFF) shl 16) + or ReverseBitsInInt16((V and $FFFF0000) shr 16); +end; + +function ReverseBitsInInt64(V: Int64): Int64; +begin + Result := (Int64(ReverseBitsInInt32(V and $00000000FFFFFFFF)) shl 32) + or ReverseBitsInInt32((V and $FFFFFFFF00000000) shr 32); +end; + +procedure ReverseMemory(Mem: Pointer; MemByteLen: Integer); +var + I, L: Integer; + P: PByteArray; + T: Byte; +begin + if (Mem = nil) or (MemByteLen < 2) then + Exit; + + L := MemByteLen div 2; + P := PByteArray(Mem); + for I := 0 to L - 1 do + begin + // I ͵ MemLen - I - 1 + T := P^[I]; + P^[I] := P^[MemByteLen - I - 1]; + P^[MemByteLen - I - 1] := T; + end; +end; + +procedure ReverseMemoryWithBits(Mem: Pointer; MemByteLen: Integer); +var + I: Integer; + P: PByteArray; +begin + if (Mem = nil) or (MemByteLen <= 0) then + Exit; + + ReverseMemory(Mem, MemByteLen); + P := PByteArray(Mem); + + for I := 0 to MemByteLen - 1 do + P^[I] := ReverseBitsInInt8(P^[I]); +end; + +procedure MemoryNetworkToHost(Mem: Pointer; MemByteLen: Integer); +begin + if not FByteOrderIsBigEndian then + ReverseMemory(Mem, MemByteLen); +end; + +procedure MemoryHostToNetwork(Mem: Pointer; MemByteLen: Integer); +begin + if not FByteOrderIsBigEndian then + ReverseMemory(Mem, MemByteLen); +end; + +// N ֽڳȵڴλ +procedure MemoryBitOperation(AMem, BMem, RMem: Pointer; N: Integer; Op: TCnBitOperation); +var + A, B, R: PCnLongWord32Array; + BA, BB, BR: PByteArray; +begin + if N <= 0 then + Exit; + + if (AMem = nil) or ((BMem = nil) and (Op <> boNot)) or (RMem = nil) then + Exit; + + A := PCnLongWord32Array(AMem); + B := PCnLongWord32Array(BMem); + R := PCnLongWord32Array(RMem); + + while (N and (not 3)) <> 0 do + begin + case Op of + boAnd: + R^[0] := A^[0] and B^[0]; + boOr: + R^[0] := A^[0] or B^[0]; + boXor: + R^[0] := A^[0] xor B^[0]; + boNot: // ʱ B + R^[0] := not A^[0]; + end; + + A := PCnLongWord32Array(TCnNativeInt(A) + SizeOf(Cardinal)); + B := PCnLongWord32Array(TCnNativeInt(B) + SizeOf(Cardinal)); + R := PCnLongWord32Array(TCnNativeInt(R) + SizeOf(Cardinal)); + + Dec(N, SizeOf(Cardinal)); + end; + + if N > 0 then + begin + BA := PByteArray(A); + BB := PByteArray(B); + BR := PByteArray(R); + + while N <> 0 do + begin + case Op of + boAnd: + BR^[0] := BA^[0] and BB^[0]; + boOr: + BR^[0] := BA^[0] or BB^[0]; + boXor: + BR^[0] := BA^[0] xor BB^[0]; + boNot: + BR^[0] := not BA^[0]; + end; + + BA := PByteArray(TCnNativeInt(BA) + SizeOf(Byte)); + BB := PByteArray(TCnNativeInt(BB) + SizeOf(Byte)); + BR := PByteArray(TCnNativeInt(BR) + SizeOf(Byte)); + Dec(N); + end; + end; +end; + +procedure MemoryAnd(AMem, BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +begin + MemoryBitOperation(AMem, BMem, ResMem, MemByteLen, boAnd); +end; + +procedure MemoryOr(AMem, BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +begin + MemoryBitOperation(AMem, BMem, ResMem, MemByteLen, boOr); +end; + +procedure MemoryXor(AMem, BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +begin + MemoryBitOperation(AMem, BMem, ResMem, MemByteLen, boXor); +end; + +procedure MemoryNot(Mem: Pointer; MemByteLen: Integer; ResMem: Pointer); +begin + MemoryBitOperation(Mem, nil, ResMem, MemByteLen, boNot); +end; + +procedure MemoryShiftLeft(AMem, BMem: Pointer; MemByteLen: Integer; BitCount: Integer); +var + I, L, N, LB, RB: Integer; + PF, PT: PByteArray; +begin + if (AMem = nil) or (MemByteLen <= 0) or (BitCount = 0) then + Exit; + + if BitCount < 0 then + begin + MemoryShiftRight(AMem, BMem, MemByteLen, -BitCount); + Exit; + end; + + if BMem = nil then + BMem := AMem; + + if (MemByteLen * 8) <= BitCount then // ̫಻ȫ 0 + begin + FillChar(BMem^, MemByteLen, 0); + Exit; + end; + + N := BitCount div 8; // λֽ + RB := BitCount mod 8; // ȥֽںʣµλ + LB := 8 - RB; // ʣµλһֽʣµλ + + PF := PByteArray(AMem); + PT := PByteArray(BMem); + + if RB = 0 then // 飬ð죬Ҫλֽ MemLen - NW + begin + Move(PF^[N], PT^[0], MemByteLen - N); + FillChar(PT^[MemByteLen - N], N, 0); + end + else + begin + // PF^[N] PT^[0] MemLen - N ֽڣֽڼн + L := MemByteLen - N; + PF := PByteArray(TCnNativeInt(PF) + N); + + for I := 1 to L do // ӵλƶȴ͵ + begin + PT^[0] := Byte(PF^[0] shl RB); + if I < L then // һֽ PF^[1] ᳬ + PT^[0] := (PF^[1] shr LB) or PT^[0]; + + PF := PByteArray(TCnNativeInt(PF) + 1); + PT := PByteArray(TCnNativeInt(PT) + 1); + end; + + // ʣµҪ 0 + if N > 0 then + FillChar(PT^[0], N, 0); + end; +end; + +procedure MemoryShiftRight(AMem, BMem: Pointer; MemByteLen: Integer; BitCount: Integer); +var + I, L, N, LB, RB: Integer; + PF, PT: PByteArray; +begin + if (AMem = nil) or (MemByteLen <= 0) or (BitCount = 0) then + Exit; + + if BitCount < 0 then + begin + MemoryShiftLeft(AMem, BMem, MemByteLen, -BitCount); + Exit; + end; + + if BMem = nil then + BMem := AMem; + + if (MemByteLen * 8) <= BitCount then // ̫಻ȫ 0 + begin + FillChar(BMem^, MemByteLen, 0); + Exit; + end; + + N := BitCount div 8; // λֽ + RB := BitCount mod 8; // ȥֽںʣµλ + LB := 8 - RB; // ʣµλһֽʣµλ + + if RB = 0 then // 飬ð죬Ҫλֽ MemLen - N + begin + PF := PByteArray(AMem); + PT := PByteArray(BMem); + + Move(PF^[0], PT^[N], MemByteLen - N); + FillChar(PT^[0], N, 0); + end + else + begin + // PF^[0] PT^[N] MemLen - N ֽڣôӸߴʼֽڼн + L := MemByteLen - N; + + PF := PByteArray(TCnNativeInt(AMem) + L - 1); + PT := PByteArray(TCnNativeInt(BMem) + MemByteLen - 1); + + for I := L downto 1 do // Ӹλλƶȴ + begin + PT^[0] := Byte(PF^[0] shr RB); + if I > 1 then // һֽ PF^[-1] ᳬ + begin + PF := PByteArray(TCnNativeInt(PF) - 1); + PT^[0] := (PF^[0] shl LB) or PT^[0]; + end + else + PF := PByteArray(TCnNativeInt(PF) - 1); + + PT := PByteArray(TCnNativeInt(PT) - 1); + end; + + // ʣµǰҪ 0 + if N > 0 then + FillChar(BMem^, N, 0); + end; +end; + +function MemoryIsBitSet(Mem: Pointer; N: Integer): Boolean; +var + P: PByte; + A, B: Integer; + V: Byte; +begin + if (Mem = nil) or (N < 0) then + raise ERangeError.Create(SRangeError); + + A := N div 8; + B := N mod 8; + P := PByte(TCnNativeInt(Mem) + A); + + V := Byte(1 shl B); + Result := (P^ and V) <> 0; +end; + +procedure MemorySetBit(Mem: Pointer; N: Integer); +var + P: PByte; + A, B: Integer; + V: Byte; +begin + if (Mem = nil) or (N < 0) then + raise ERangeError.Create(SRangeError); + + A := N div 8; + B := N mod 8; + P := PByte(TCnNativeInt(Mem) + A); + + V := Byte(1 shl B); + P^ := P^ or V; +end; + +procedure MemoryClearBit(Mem: Pointer; N: Integer); +var + P: PByte; + A, B: Integer; + V: Byte; +begin + if (Mem = nil) or (N < 0) then + raise ERangeError.Create(SRangeError); + + A := N div 8; + B := N mod 8; + P := PByte(TCnNativeInt(Mem) + A); + + V := not Byte(1 shl B); + P^ := P^ and V; +end; + +function MemoryToBinStr(Mem: Pointer; MemByteLen: Integer; Sep: Boolean): string; +var + J, L: Integer; + P: PByteArray; + B: PChar; + + procedure FillAByteToBuf(V: Byte; Buf: PChar); + const + M = $80; + var + I: Integer; + begin + for I := 0 to 7 do + begin + if (V and M) <> 0 then + Buf[I] := '1' + else + Buf[I] := '0'; + V := V shl 1; + end; + end; + +begin + Result := ''; + if (Mem = nil) or (MemByteLen <= 0) then + Exit; + + L := MemByteLen * 8; + if Sep then + L := L + MemByteLen - 1; // мÿոָ + + SetLength(Result, L); + B := PChar(@Result[1]); + P := PByteArray(Mem); + + for J := 0 to MemByteLen - 1 do + begin + FillAByteToBuf(P^[J], B); + if Sep then + begin + B[8] := ' '; + Inc(B, 9); + end + else + Inc(B, 8); + end; +end; + +procedure MemorySwap(AMem, BMem: Pointer; MemByteLen: Integer); +var + A, B: PCnLongWord32Array; + BA, BB: PByteArray; + TC: Cardinal; + TB: Byte; +begin + if (AMem = nil) or (BMem = nil) or (MemByteLen <= 0) then + Exit; + + A := PCnLongWord32Array(AMem); + B := PCnLongWord32Array(BMem); + + if A = B then + Exit; + + while (MemByteLen and (not 3)) <> 0 do + begin + TC := A^[0]; + A^[0] := B^[0]; + B^[0] := TC; + + A := PCnLongWord32Array(TCnNativeInt(A) + SizeOf(Cardinal)); + B := PCnLongWord32Array(TCnNativeInt(B) + SizeOf(Cardinal)); + + Dec(MemByteLen, SizeOf(Cardinal)); + end; + + if MemByteLen > 0 then + begin + BA := PByteArray(A); + BB := PByteArray(B); + + while MemByteLen <> 0 do + begin + TB := BA^[0]; + BA^[0] := BB^[0]; + BB^[0] :=TB; + + BA := PByteArray(TCnNativeInt(BA) + SizeOf(Byte)); + BB := PByteArray(TCnNativeInt(BB) + SizeOf(Byte)); + + Dec(MemByteLen); + end; + end; +end; + +function MemoryCompare(AMem, BMem: Pointer; MemByteLen: Integer): Integer; +var + A, B: PCnLongWord32Array; + BA, BB: PByteArray; +begin + Result := 0; + if ((AMem = nil) and (BMem = nil)) or (AMem = BMem) then // ͬһ + Exit; + + if MemByteLen <= 0 then + Exit; + + if AMem = nil then + begin + Result := -1; + Exit; + end; + if BMem = nil then + begin + Result := 1; + Exit; + end; + + A := PCnLongWord32Array(AMem); + B := PCnLongWord32Array(BMem); + + while (MemByteLen and (not 3)) <> 0 do + begin + if A^[0] > B^[0] then + begin + Result := 1; + Exit; + end + else if A^[0] < B^[0] then + begin + Result := -1; + Exit; + end; + + A := PCnLongWord32Array(TCnNativeInt(A) + SizeOf(Cardinal)); + B := PCnLongWord32Array(TCnNativeInt(B) + SizeOf(Cardinal)); + + Dec(MemByteLen, SizeOf(Cardinal)); + end; + + if MemByteLen > 0 then + begin + BA := PByteArray(A); + BB := PByteArray(B); + + while MemByteLen <> 0 do + begin + if BA^[0] > BB^[0] then + begin + Result := 1; + Exit; + end + else if BA^[0] < BB^[0] then + begin + Result := -1; + Exit; + end; + + BA := PByteArray(TCnNativeInt(BA) + SizeOf(Byte)); + BB := PByteArray(TCnNativeInt(BB) + SizeOf(Byte)); + + Dec(MemByteLen); + end; + end; +end; + +function UInt8ToBinStr(V: Byte): string; +const + M = $80; +var + I: Integer; +begin + SetLength(Result, 8 * SizeOf(V)); + for I := 1 to 8 * SizeOf(V) do + begin + if (V and M) <> 0 then + Result[I] := '1' + else + Result[I] := '0'; + V := V shl 1; + end; +end; + +function UInt16ToBinStr(V: Word): string; +const + M = $8000; +var + I: Integer; +begin + SetLength(Result, 8 * SizeOf(V)); + for I := 1 to 8 * SizeOf(V) do + begin + if (V and M) <> 0 then + Result[I] := '1' + else + Result[I] := '0'; + V := V shl 1; + end; +end; + +function UInt32ToBinStr(V: Cardinal): string; +const + M = $80000000; +var + I: Integer; +begin + SetLength(Result, 8 * SizeOf(V)); + for I := 1 to 8 * SizeOf(V) do + begin + if (V and M) <> 0 then + Result[I] := '1' + else + Result[I] := '0'; + V := V shl 1; + end; +end; + +function UInt32ToStr(V: Cardinal): string; +begin + Result := Format('%u', [V]); +end; + +function UInt64ToBinStr(V: TUInt64): string; +const + M = $8000000000000000; +var + I: Integer; +begin + SetLength(Result, 8 * SizeOf(V)); + + for I := 1 to 8 * SizeOf(V) do + begin + if (V and M) <> 0 then + Result[I] := '1' + else + Result[I] := '0'; + V := V shl 1; + end; +end; + +const + HiDigits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); +const + LoDigits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); + +const + AnsiHiDigits: array[0..15] of AnsiChar = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); +const + AnsiLoDigits: array[0..15] of AnsiChar = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); + +function HexToInt(Hex: PChar; CharLen: Integer): Integer; +var + I, Res: Integer; + C: Char; +begin + Res := 0; + for I := 0 to CharLen - 1 do + begin + C := Hex[I]; + if (C >= '0') and (C <= '9') then + Res := Res * 16 + Ord(C) - Ord('0') + else if (C >= 'A') and (C <= 'F') then + Res := Res * 16 + Ord(C) - Ord('A') + 10 + else if (C >= 'a') and (C <= 'f') then + Res := Res * 16 + Ord(C) - Ord('a') + 10 + else + raise ECnNativeException.CreateFmt(SCnErrorNotAHexPChar, [C]); + end; + Result := Res; +end; + +function HexToInt(const Hex: string): Integer; +begin + Result := HexToInt(PChar(Hex), Length(Hex)); +end; + +{$WARNINGS OFF} + +function IsHexString(const Hex: string): Boolean; +var + I, L: Integer; +begin + Result := False; + L := Length(Hex); + if (L <= 0) or ((L and 1) <> 0) then // ջżȶ + Exit; + + for I := 1 to L do + begin + // ע˴ Unicode Ȼ Warningǽ Hex[I] WideChar ֱӽض AnsiChar + // ٽжϣᵼ¡޻ޡ $66$66$66$66 ַУ + // ֱͨ WideChar ֵ ax ˫ֽڵģӼжϣ + if not (Hex[I] in ['0'..'9', 'A'..'F', 'a'..'f']) then + Exit; + end; + Result := True; +end; + +{$WARNINGS ON} + +function DataToHex(InData: Pointer; ByteLength: Integer; UseUpperCase: Boolean = True): string; +var + I: Integer; + B: Byte; +begin + Result := ''; + if ByteLength <= 0 then + Exit; + + SetLength(Result, ByteLength * 2); + if UseUpperCase then + begin + for I := 0 to ByteLength - 1 do + begin + B := PByte(TCnNativeInt(InData) + I * SizeOf(Byte))^; + Result[I * 2 + 1] := HiDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := HiDigits[B and $0F]; + end; + end + else + begin + for I := 0 to ByteLength - 1 do + begin + B := PByte(TCnNativeInt(InData) + I * SizeOf(Byte))^; + Result[I * 2 + 1] := LoDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := LoDigits[B and $0F]; + end; + end; +end; + +function HexToData(const Hex: string; OutData: Pointer): Integer; +var + I, L: Integer; + H: PChar; +begin + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); + + if OutData = nil then + begin + Result := L div 2; + Exit; + end; + + Result := 0; + H := PChar(Hex); + for I := 1 to L div 2 do + begin + PByte(TCnNativeInt(OutData) + I - 1)^ := Byte(HexToInt(@H[(I - 1) * 2], 2)); + Inc(Result); + end; +end; + +function StringToHex(const Data: string; UseUpperCase: Boolean): string; +var + I, L: Integer; + B: Byte; + Buffer: PChar; +begin + Result := ''; + L := Length(Data); + if L = 0 then + Exit; + + SetLength(Result, L * 2); + Buffer := @Data[1]; + + if UseUpperCase then + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I * SizeOf(Char))^; + Result[I * 2 + 1] := HiDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := HiDigits[B and $0F]; + end; + end + else + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I * SizeOf(Char))^; + Result[I * 2 + 1] := LoDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := LoDigits[B and $0F]; + end; + end; +end; + +function HexToString(const Hex: string): string; +var + I, L: Integer; + H: PChar; +begin + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); + + SetLength(Result, L div 2); + H := PChar(Hex); + for I := 1 to L div 2 do + Result[I] := Chr(HexToInt(@H[(I - 1) * 2], 2)); +end; + +function HexToAnsiStr(const Hex: AnsiString): AnsiString; +var + I, L: Integer; + S: string; +begin + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHexAnsi, [L]); + + SetLength(Result, L div 2); + for I := 1 to L div 2 do + begin + S := string(Copy(Hex, I * 2 - 1, 2)); + Result[I] := AnsiChar(Chr(HexToInt(S))); + end; +end; + +function AnsiStrToHex(const Data: AnsiString; UseUpperCase: Boolean): AnsiString; +var + I, L: Integer; + B: Byte; + Buffer: PAnsiChar; +begin + Result := ''; + L := Length(Data); + if L = 0 then + Exit; + + SetLength(Result, L * 2); + Buffer := @Data[1]; + + if UseUpperCase then + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I)^; + Result[I * 2 + 1] := AnsiHiDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := AnsiHiDigits[B and $0F]; + end; + end + else + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I)^; + Result[I * 2 + 1] := AnsiLoDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := AnsiLoDigits[B and $0F]; + end; + end; +end; + +function BytesToHex(Data: TBytes; UseUpperCase: Boolean): string; +var + I, L: Integer; + B: Byte; + Buffer: PAnsiChar; +begin + Result := ''; + L := Length(Data); + if L = 0 then + Exit; + + SetLength(Result, L * 2); + Buffer := @Data[0]; + + if UseUpperCase then + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I)^; + Result[I * 2 + 1] := HiDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := HiDigits[B and $0F]; + end; + end + else + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I)^; + Result[I * 2 + 1] := LoDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := LoDigits[B and $0F]; + end; + end; +end; + +function HexToBytes(const Hex: string): TBytes; +var + I, L: Integer; + H: PChar; +begin + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); + + SetLength(Result, L div 2); + H := PChar(Hex); + + for I := 1 to L div 2 do + Result[I - 1] := Byte(HexToInt(@H[(I - 1) * 2], 2)); +end; + +function StreamToHex(Stream: TStream; UseUpperCase: Boolean): string; +var + B: Byte; + I: Integer; +begin + Result := ''; + if Stream.Size > 0 then + begin + Stream.Position := 0; + SetLength(Result, Stream.Size * 2); + I := 1; + if UseUpperCase then + begin + while Stream.Read(B, 1) = 1 do + begin + Result[I] := HiDigits[(B shr 4) and $0F]; + Inc(I); + Result[I] := HiDigits[B and $0F]; + Inc(I); + end; + end + else + begin + while Stream.Read(B, 1) = 1 do + begin + Result[I] := LoDigits[(B shr 4) and $0F]; + Inc(I); + Result[I] := LoDigits[B and $0F]; + Inc(I); + end; + end; + end; +end; + +function HexToStream(const Hex: string; Stream: TStream): Integer; +var + I, L: Integer; + H: PChar; + B: Byte; +begin + Result := 0; + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); + + H := PChar(Hex); + for I := 1 to L div 2 do + begin + B := Byte(HexToInt(@H[(I - 1) * 2], 2)); + Inc(Result, Stream.Write(B, 1)); + end; +end; + +procedure ReverseBytes(Data: TBytes); +var + I, L, M: Integer; + T: Byte; +begin + if (Data = nil) or (Length(Data) <= 1) then + Exit; + L := Length(Data); + M := L div 2; + for I := 0 to M - 1 do + begin + // I L - I - 1 + T := Data[I]; + Data[I] := Data[L - I - 1]; + Data[L - I - 1] := T; + end; +end; + +function CloneBytes(Data: TBytes): TBytes; +begin + if Length(Data) = 0 then + Result := nil + else + begin + SetLength(Result, Length(Data)); + Move(Data[0], Result[0], Length(Data)); + end; +end; + +function StreamToBytes(Stream: TStream): TBytes; +begin + Result := nil; + if (Stream <> nil) and (Stream.Size > 0) then + begin + SetLength(Result, Stream.Size); + Stream.Position := 0; + Stream.Read(Result[0], Stream.Size); + end; +end; + +function BytesToStream(Data: TBytes; OutStream: TStream): Integer; +begin + Result := 0; + if (Data <> nil) and (Length(Data) > 0) and (OutStream <> nil) then + begin + OutStream.Size := 0; + Result := OutStream.Write(Data[0], Length(Data)); + end; +end; + +function AnsiToBytes(const Str: AnsiString): TBytes; +begin + SetLength(Result, Length(Str)); + if Length(Str) > 0 then + Move(Str[1], Result[0], Length(Str)); +end; + +function BytesToAnsi(Data: TBytes): AnsiString; +begin + SetLength(Result, Length(Data)); + if Length(Data) > 0 then + Move(Data[0], Result[1], Length(Data)); +end; + +function BytesToString(Data: TBytes): string; +var + I: Integer; +begin + SetLength(Result, Length(Data)); + for I := 1 to Length(Data) do + Result[I] := Chr(Data[I - 1]); +end; + +function MemoryToString(Mem: Pointer; MemByteLen: Integer): string; +var + P: PByteArray; + I: Integer; +begin + if (Mem = nil) or (MemByteLen <= 0) then + begin + Result := ''; + Exit; + end; + + P := PByteArray(Mem); + SetLength(Result, MemByteLen); + for I := 1 to MemByteLen do + Result[I] := Chr(P^[I - 1]); +end; + +function BitsToString(Bits: TBits): string; +var + I: Integer; +begin + if (Bits = nil) or (Bits.Size = 0) then + Result := '' + else + begin + SetLength(Result, Bits.Size); + for I := 0 to Bits.Size - 1 do + begin + if Bits.Bits[I] then + Result[I + 1] := '1' + else + Result[I + 1] := '0'; + end; + end; +end; + +function ConcatBytes(A, B: TBytes): TBytes; +begin + // XE7 ҲֱӣΪ A B Ϊʱ᷵һֽ + if (A = nil) or (Length(A) = 0) then + begin + SetLength(Result, Length(B)); + if Length(B) > 0 then + Move(B[0], Result[0], Length(B)); + end + else if (B = nil) or (Length(B) = 0) then + begin + SetLength(Result, Length(A)); + if Length(A) > 0 then + Move(A[0], Result[0], Length(A)); + end + else + begin + SetLength(Result, Length(A) + Length(B)); + Move(A[0], Result[0], Length(A)); + Move(B[0], Result[Length(A)], Length(B)); + end; +end; + +function NewBytesFromMemory(Data: Pointer; DataByteLen: Integer): TBytes; +begin + if (Data = nil) or (DataByteLen <= 0) then + Result := nil + else + begin + SetLength(Result, DataByteLen); + Move(Data^, Result[0], DataByteLen); + end; +end; + +function CompareBytes(A, B: TBytes): Boolean; +var + L: Integer; +begin + Result := False; + + L := Length(A); + if Length(B) <> L then // Ȳ˳ + Exit; + + if L = 0 then // + Result := True // 綼 0 + else + Result := CompareMem(@A[0], @B[0], L); +end; + +function CompareBytes(A, B: TBytes; MaxLength: Integer): Boolean; +var + LA, LB: Integer; +begin + Result := False; + + LA := Length(A); + LB := Length(B); + + if LA > MaxLength then + LA := MaxLength; + if LB > MaxLength then + LB := MaxLength; + + if LA <> LB then + Exit; + + if LA = 0 then + Result := True + else + Result := CompareMem(@A[0], @B[0], LA); +end; + +function MoveMost(const Source; var Dest; ByteLen, MostLen: Integer): Integer; +begin + if (MostLen <= 0) or (ByteLen <= 0) then + begin + Result := 0; + Exit; + end; + + if ByteLen > MostLen then + ByteLen := MostLen + else if ByteLen < MostLen then + begin + FillChar(Dest, MostLen, 0); + + // TODO: ҪΪ FillChar(Dest + ByteLen, MostLen - ByteLen, 0); ֻ䲻IJ + end; + + Move(Source, Dest, ByteLen); + Result := ByteLen; +end; + +// =============================== =================================== + +function SarInt8(var V: Byte; ShiftCount: Integer): Byte; +begin + Result := V shr ShiftCount; + if (V and $80) <> 0 then + Result := Result or $80; +end; + +function SarInt16(var V: Word; ShiftCount: Integer): Word; +begin + Result := V shr ShiftCount; + if (V and $8000) <> 0 then + Result := Result or $8000; +end; + +function SarInt32(var V: Cardinal; ShiftCount: Integer): Cardinal; +begin + Result := V shr ShiftCount; + if (V and $80000000) <> 0 then + Result := Result or $80000000; +end; + +function SarInt64(var V: TUInt64; ShiftCount: Integer): TUInt64; +begin + Result := V shr ShiftCount; + if (V and $8000000000000000) <> 0 then + Result := Result or $8000000000000000; +end; + +procedure ConstTimeConditionalSwap8(CanSwap: Boolean; var A, B: Byte); +var + T, V: Byte; +begin + T := ConstTimeExpandBoolean8(CanSwap); + V := (A xor B) and T; + A := A xor V; + B := B xor V; +end; + +procedure ConstTimeConditionalSwap16(CanSwap: Boolean; var A, B: Word); +var + T, V: Word; +begin + T := ConstTimeExpandBoolean16(CanSwap); + V := (A xor B) and T; + A := A xor V; + B := B xor V; +end; + +procedure ConstTimeConditionalSwap32(CanSwap: Boolean; var A, B: Cardinal); +var + T, V: Cardinal; +begin + T := ConstTimeExpandBoolean32(CanSwap); + V := (A xor B) and T; + A := A xor V; + B := B xor V; +end; + +procedure ConstTimeConditionalSwap64(CanSwap: Boolean; var A, B: TUInt64); +var + T, V: TUInt64; +begin + T := ConstTimeExpandBoolean64(CanSwap); + V := (A xor B) and T; + A := A xor V; + B := B xor V; +end; + +function ConstTimeEqual8(A, B: Byte): Boolean; +var + R: Byte; +begin + R := not (A xor B); // + R := R and (R shr 4); // һһ + R := R and (R shr 2); // һλ 0 + R := R and (R shr 1); // 0 + Result := Boolean(R); // ֻȫ 1 1 +end; + +function ConstTimeEqual16(A, B: Word): Boolean; +begin + Result := ConstTimeEqual8(Byte(A shr 8), Byte(B shr 8)) + and ConstTimeEqual8(Byte(A and $FF), Byte(B and $FF)); +end; + +function ConstTimeEqual32(A, B: Cardinal): Boolean; +begin + Result := ConstTimeEqual16(Word(A shr 16), Word(B shr 16)) + and ConstTimeEqual16(Word(A and $FFFF), Word(B and $FFFF)); +end; + +function ConstTimeEqual64(A, B: TUInt64): Boolean; +begin + Result := ConstTimeEqual32(Cardinal(A shr 32), Cardinal(B shr 32)) + and ConstTimeEqual32(Cardinal(A and $FFFFFFFF), Cardinal(B and $FFFFFFFF)); +end; + +function ConstTimeBytesEqual(A, B: TBytes): Boolean; +var + I: Integer; +begin + Result := False; + if Length(A) <> Length(B) then + Exit; + + Result := True; + for I := 0 to Length(A) - 1 do // ÿֽڶȽϣͬ˳ + Result := Result and (ConstTimeEqual8(A[I], B[I])); +end; + +function ConstTimeExpandBoolean8(V: Boolean): Byte; +begin + Result := Byte(V); + Result := not Result; // V True 0˲ R Ǵ $FFR ͷ 0 + Result := Result and (Result shr 4); // һһ + Result := Result and (Result shr 2); // һλ 0 + Result := Result and (Result shr 1); // 00000000 00000001 + Result := Result or (Result shl 1); // True õ 00000000False õ 00000001λ + Result := Result or (Result shl 2); + Result := Result or (Result shl 4); // ȫ 0 ȫ 1 + Result := not Result; // ȫ 1 ȫ 0 +end; + +function ConstTimeExpandBoolean16(V: Boolean): Word; +var + R: Byte; +begin + R := ConstTimeExpandBoolean8(V); + Result := R; + Result := (Result shl 8) or R; // ֽȫ 1 ȫ 0 ˫ֽ +end; + +function ConstTimeExpandBoolean32(V: Boolean): Cardinal; +var + R: Word; +begin + R := ConstTimeExpandBoolean16(V); + Result := R; + Result := (Result shl 16) or R; // ˫ֽȫ 1 ȫ 0 ֽ +end; + +function ConstTimeExpandBoolean64(V: Boolean): TUInt64; +var + R: Cardinal; +begin + R := ConstTimeExpandBoolean32(V); + Result := R; + Result := (Result shl 32) or R; // ֽȫ 1 ȫ 0 ɰֽ +end; + +function ConstTimeConditionalSelect8(Condition: Boolean; A, B: Byte): Byte; +begin + ConstTimeConditionalSwap8(Condition, A, B); + Result := B; +end; + +function ConstTimeConditionalSelect16(Condition: Boolean; A, B: Word): Word; +begin + ConstTimeConditionalSwap16(Condition, A, B); + Result := B; +end; + +function ConstTimeConditionalSelect32(Condition: Boolean; A, B: Cardinal): Cardinal; +begin + ConstTimeConditionalSwap32(Condition, A, B); + Result := B; +end; + +function ConstTimeConditionalSelect64(Condition: Boolean; A, B: TUInt64): TUInt64; +begin + ConstTimeConditionalSwap64(Condition, A, B); + Result := B; +end; + +{$IFDEF MSWINDOWS} + +{$IFDEF CPUX64} + +// 64 λ IDIV IDIV ָʵ֣ A RCX B EDX/RDX DivRes ַ R8 ModRes ַ R9 +procedure Int64DivInt32Mod(A: Int64; B: Integer; var DivRes, ModRes: Integer); assembler; +asm + PUSH RCX // RCX A + MOV RCX, RDX // B RCX + POP RAX // A RAX + XOR RDX, RDX // 64 λ + IDIV RCX + MOV [R8], EAX // ̷ R8 ָ DivRes + MOV [R9], EDX // R9 ָ ModRes +end; + +procedure UInt64DivUInt32Mod(A: TUInt64; B: Cardinal; var DivRes, ModRes: Cardinal); assembler; +asm + PUSH RCX // RCX A + MOV RCX, RDX // B RCX + POP RAX // A RAX + XOR RDX, RDX // 64 λ + DIV RCX + MOV [R8], EAX // ̷ R8 ָ DivRes + MOV [R9], EDX // R9 ָ ModRes +end; + +// 64 λ IDIV IDIV ָʵ֣ALo RCXAHi RDXB R8DivRes ĵַ R9 +procedure Int128DivInt64Mod(ALo, AHi: Int64; B: Int64; var DivRes, ModRes: Int64); assembler; +asm + MOV RAX, RCX // ALo RAXAHi Ѿ RDX + MOV RCX, R8 // B RCX + IDIV RCX + MOV [R9], RAX // ̷ R9 ָ DivRes + MOV RAX, [RBP + $30] // ModRes ַ RAX + MOV [RAX], RDX // RAX ָ ModRes +end; + +procedure UInt128DivUInt64Mod(ALo, AHi: UInt64; B: UInt64; var DivRes, ModRes: UInt64); assembler; +asm + MOV RAX, RCX // ALo RAXAHi Ѿ RDX + MOV RCX, R8 // B RCX + DIV RCX + MOV [R9], RAX // ̷ R9 ָ DivRes + MOV RAX, [RBP + $30] // ModRes ַ RAX + MOV [RAX], RDX // RAX ָ ModRes +end; + +{$ELSE} + +// 32 λ IDIV IDIV ָʵ֣ A ڶջϣB EAXDivRes ַ EDXModRes ַ ECX +procedure Int64DivInt32Mod(A: Int64; B: Integer; var DivRes, ModRes: Integer); assembler; +asm + PUSH ECX // ECX ModRes ַȱ + MOV ECX, B // B EAX УƵ ECX + PUSH EDX // DivRes ĵַ EDX УҲ + MOV EAX, [EBP + $8] // A Lo + MOV EDX, [EBP + $C] // A Hi + IDIV ECX + POP ECX // ECXõ DivRes ַ + MOV [ECX], EAX + POP ECX // ECXõ ModRes ַ + MOV [ECX], EDX +end; + +procedure UInt64DivUInt32Mod(A: TUInt64; B: Cardinal; var DivRes, ModRes: Cardinal); assembler; +asm + PUSH ECX // ECX ModRes ַȱ + MOV ECX, B // B EAX УƵ ECX + PUSH EDX // DivRes ĵַ EDX УҲ + MOV EAX, [EBP + $8] // A Lo + MOV EDX, [EBP + $C] // A Hi + DIV ECX + POP ECX // ECXõ DivRes ַ + MOV [ECX], EAX + POP ECX // ECXõ ModRes ַ + MOV [ECX], EDX +end; + +// 32 λµʵ +procedure Int128DivInt64Mod(ALo, AHi: Int64; B: Int64; var DivRes, ModRes: Int64); +var + C: Integer; +begin + if B = 0 then + raise EDivByZero.Create(SDivByZero); + + if (AHi = 0) or (AHi = $FFFFFFFFFFFFFFFF) then // 64 λΪ 0 ֵֵ + begin + DivRes := ALo div B; + ModRes := ALo mod B; + end + else + begin + if B < 0 then // Ǹ + begin + Int128DivInt64Mod(ALo, AHi, -B, DivRes, ModRes); + DivRes := -DivRes; + Exit; + end; + + if AHi < 0 then // Ǹ + begin + // AHi, ALo 󷴼 1Եõֵ + AHi := not AHi; + ALo := not ALo; +{$IFDEF SUPPORT_UINT64} + UInt64Add(UInt64(ALo), UInt64(ALo), 1, C); +{$ELSE} + UInt64Add(ALo, ALo, 1, C); +{$ENDIF} + if C > 0 then + AHi := AHi + C; + + // ת + Int128DivInt64Mod(ALo, AHi, B, DivRes, ModRes); + + // ٵ + if ModRes = 0 then + DivRes := -DivRes + else + begin + DivRes := -DivRes - 1; + ModRes := B - ModRes; + end; + Exit; + end; + + // ȫ󣬰޷ +{$IFDEF SUPPORT_UINT64} + UInt128DivUInt64Mod(TUInt64(ALo), TUInt64(AHi), TUInt64(B), TUInt64(DivRes), TUInt64(ModRes)); +{$ELSE} + UInt128DivUInt64Mod(ALo, AHi, B, DivRes, ModRes); +{$ENDIF} + end; +end; + +procedure UInt128DivUInt64Mod(ALo, AHi: TUInt64; B: TUInt64; var DivRes, ModRes: TUInt64); +var + I, Cnt: Integer; + Q, R: TUInt64; +begin + if B = 0 then + raise EDivByZero.Create(SDivByZero); + + if AHi = 0 then + begin + DivRes := UInt64Div(ALo, B); + ModRes := UInt64Mod(ALo, B); + end + else + begin + // иλеλզ죿жǷ AHi >= BʾҪ 64 λ + if UInt64Compare(AHi, B) >= 0 then + raise EIntOverflow.Create(SIntOverflow); + + Q := 0; + R := 0; + Cnt := GetUInt64LowBits(AHi) + 64; + for I := Cnt downto 0 do + begin + R := R shl 1; + if IsUInt128BitSet(ALo, AHi, I) then // ĵ I λǷ 0 + R := R or 1 + else + R := R and TUInt64(not 1); + + if UInt64Compare(R, B) >= 0 then + begin + R := R - B; + Q := Q or (TUInt64(1) shl I); + end; + end; + DivRes := Q; + ModRes := R; + end; +end; + +{$ENDIF} + +{$ENDIF} + +{$IFDEF SUPPORT_UINT64} + +// ֻҪ֧ 64 λ޷ 32/64 λ Intel ARM Delphi FPCʲôϵͳ + +function UInt64Mod(A, B: TUInt64): TUInt64; +begin + Result := A mod B; +end; + +function UInt64Div(A, B: TUInt64): TUInt64; +begin + Result := A div B; +end; + +{$ELSE} +{ + ֧ UInt64 ĵͰ汾 Delphi Int64 A mod/div B + + õջ˳ A ĸλA ĵλB ĸλB ĵλ push ϲ뺯 + ESP ǷصַESP+4 B ĵλESP + 8 B ĸλESP + C A ĵλESP + 10 A ĸλ + push esp ESP 4Ȼ mov ebp esp֮ EBP ѰַȫҪ 4 + + System.@_llumod ҪڸսʱEAX <- A ĵλEDX <- A ĸλSystem Դע EAX/EDX дˣ + [ESP + 8]Ҳ EBP + C<- B ĸλ[ESP + 4] Ҳ EBP + 8<- B ĵλ + + CALL ǰľƴ롣UInt64 Div Ҳ +} +function UInt64Mod(A, B: TUInt64): TUInt64; +asm + // PUSH ESP ESP 4Ҫ + MOV EAX, [EBP + $10] // A Lo + MOV EDX, [EBP + $14] // A Hi + PUSH DWORD PTR[EBP + $C] // B Hi + PUSH DWORD PTR[EBP + $8] // B Lo + CALL System.@_llumod; +end; + +function UInt64Div(A, B: TUInt64): TUInt64; +asm + // PUSH ESP ESP 4Ҫ + MOV EAX, [EBP + $10] // A Lo + MOV EDX, [EBP + $14] // A Hi + PUSH DWORD PTR[EBP + $C] // B Hi + PUSH DWORD PTR[EBP + $8] // B Lo + CALL System.@_lludiv; +end; + +{$ENDIF} + +{$IFDEF SUPPORT_UINT64} + +// ֻҪ֧ 64 λ޷ 32/64 λ Intel ARM Delphi FPCʲôϵͳ + +function UInt64Mul(A, B: Cardinal): TUInt64; +begin + Result := TUInt64(A) * B; +end; + +{$ELSE} // ֻеͰ汾 Delphi Win32 x86 + +{ + ޷ 32 λˣֱʹ Int64 ģ 64 λ޷ + + üĴԼ A -> EAXB -> EDXʹöջ + System.@_llmul ҪڸսʱEAX <- A ĵλEDX <- A ĸλ 0 + [ESP + 8]Ҳ EBP + C<- B ĸλ 0[ESP + 4] Ҳ EBP + 8<- B ĵλ +} +function UInt64Mul(A, B: Cardinal): TUInt64; +asm + PUSH 0 // PUSH B λ 0 + PUSH EDX // PUSH B λ + // EAX A λѾ + XOR EDX, EDX // EDX A λ 0 + CALL System.@_llmul; // EAX 32 λEDX 32 λ +end; + +{$ENDIF} + +// ޷ 64 λӣ ResLo ResHi +procedure UInt64AddUInt64(A, B: TUInt64; var ResLo, ResHi: TUInt64); +var + X, Y, Z, T, R0L, R0H, R1L, R1H: Cardinal; + R0, R1, R01, R12: TUInt64; +begin + // ˼룺2^32 ϵ M (xM+y) + (zM+t) = (x+z) M + (y+t) + // y+t R0 ռ 01x+z R1 ռ 12 R0, R1 ٲӳ R01, R12 + if IsUInt64AddOverflow(A, B) then + begin + X := Int64Rec(A).Hi; + Y := Int64Rec(A).Lo; + Z := Int64Rec(B).Hi; + T := Int64Rec(B).Lo; + + R0 := TUInt64(Y) + TUInt64(T); + R1 := TUInt64(X) + TUInt64(Z); + + R0L := Int64Rec(R0).Lo; + R0H := Int64Rec(R0).Hi; + R1L := Int64Rec(R1).Lo; + R1H := Int64Rec(R1).Hi; + + R01 := TUInt64(R0H) + TUInt64(R1L); + R12 := TUInt64(R1H) + TUInt64(Int64Rec(R01).Hi); + + Int64Rec(ResLo).Lo := R0L; + Int64Rec(ResLo).Hi := Int64Rec(R01).Lo; + Int64Rec(ResHi).Lo := Int64Rec(R12).Lo; + Int64Rec(ResHi).Hi := Int64Rec(R12).Hi; + end + else + begin + ResLo := A + B; + ResHi := 0; + end; +end; + +{$IFDEF WIN64} // ע Linux 64 ²֧ ASMֻ WIN64 + +// 64 λ޷ 64 λˣ ResLo ResHi Уֱûʵ֣һ +procedure UInt64MulUInt64(A, B: UInt64; var ResLo, ResHi: UInt64); assembler; +asm + PUSH RAX + MOV RAX, RCX + MUL RDX // ޷ţзŵ IMUL + MOV [R8], RAX + MOV [R9], RDX + POP RAX +end; + +{$ELSE} + +// ޷ 64 λˣ ResLo ResHi +procedure UInt64MulUInt64(A, B: TUInt64; var ResLo, ResHi: TUInt64); +var + X, Y, Z, T: Cardinal; + YT, XT, ZY, ZX: TUInt64; + P, R1Lo, R1Hi, R2Lo, R2Hi: TUInt64; +begin + // ˼룺2^32 ϵ M (xM+y)*(zM+t) = xzM^2 + (xt+yz)M + yt + // ϵ UInt64xz ռ 234xt+yz ռ 123yt ռ 01Ȼۼ + X := Int64Rec(A).Hi; + Y := Int64Rec(A).Lo; + Z := Int64Rec(B).Hi; + T := Int64Rec(B).Lo; + + YT := UInt64Mul(Y, T); + XT := UInt64Mul(X, T); + ZY := UInt64Mul(Y, Z); + ZX := UInt64Mul(X, Z); + + Int64Rec(ResLo).Lo := Int64Rec(YT).Lo; + + P := Int64Rec(YT).Hi; + UInt64AddUInt64(P, XT, R1Lo, R1Hi); + UInt64AddUInt64(ZY, R1Lo, R2Lo, R2Hi); + + Int64Rec(ResLo).Hi := Int64Rec(R2Lo).Lo; + + P := TUInt64(Int64Rec(R2Lo).Hi) + TUInt64(Int64Rec(ZX).Lo); + + Int64Rec(ResHi).Lo := Int64Rec(P).Lo; + Int64Rec(ResHi).Hi := Int64Rec(R1Hi).Lo + Int64Rec(R2Hi).Lo + Int64Rec(ZX).Hi + Int64Rec(P).Hi; +end; + +{$ENDIF} + +{$HINTS OFF} + +function _ValUInt64(const S: string; var Code: Integer): TUInt64; +const + FirstIndex = 1; +var + I: Integer; + Dig: Integer; + Sign: Boolean; + Empty: Boolean; +begin + I := FirstIndex; + Dig := 0; + Result := 0; + + if S = '' then + begin + Code := 1; + Exit; + end; + + while S[I] = Char(' ') do + Inc(I); + Sign := False; + + if S[I] = Char('-') then + begin + Sign := True; + Inc(I); + end + else if S[I] = Char('+') then + Inc(I); + Empty := True; + + if (S[I] = Char('$')) or (UpCase(S[I]) = Char('X')) + or ((S[I] = Char('0')) and (I < Length(S)) and (UpCase(S[I+1]) = Char('X'))) then + begin + if S[I] = Char('0') then + Inc(I); + Inc(I); + while True do + begin + case Char(S[I]) of + Char('0').. Char('9'): Dig := Ord(S[I]) - Ord('0'); + Char('A').. Char('F'): Dig := Ord(S[I]) - (Ord('A') - 10); + Char('a').. Char('f'): Dig := Ord(S[I]) - (Ord('a') - 10); + else + Break; + end; + + if Result > (CN_MAX_TUINT64 shr 4) then + Break; + if Sign and (Dig <> 0) then + Break; + + Result := Result shl 4 + TUInt64(Dig); + Inc(I); + Empty := False; + end; + end + else + begin + while True do + begin + case Char(S[I]) of + Char('0').. Char('9'): Dig := Ord(S[I]) - Ord('0'); + else + Break; + end; + + if Result > UInt64Div(CN_MAX_TUINT64, 10) then + Break; + if Sign and (Dig <> 0) then + Break; + + Result := Result * 10 + TUInt64(Dig); + Inc(I); + Empty := False; + end; + end; + + if (S[I] <> Char(#0)) or Empty then + Code := I + 1 - FirstIndex + else + Code := 0; +end; + +{$HINTS ON} + +function UInt64ToHex(N: TUInt64): string; +const + Digits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); + + function HC(B: Byte): string; + begin + Result := string(Digits[(B shr 4) and $0F] + Digits[B and $0F]); + end; + +begin + Result := + HC(Byte((N and $FF00000000000000) shr 56)) + + HC(Byte((N and $00FF000000000000) shr 48)) + + HC(Byte((N and $0000FF0000000000) shr 40)) + + HC(Byte((N and $000000FF00000000) shr 32)) + + HC(Byte((N and $00000000FF000000) shr 24)) + + HC(Byte((N and $0000000000FF0000) shr 16)) + + HC(Byte((N and $000000000000FF00) shr 8)) + + HC(Byte((N and $00000000000000FF))); +end; + +function UInt64ToStr(N: TUInt64): string; +begin + Result := Format('%u', [N]); +end; + +function StrToUInt64(const S: string): TUInt64; +{$IFNDEF DELPHIXE6_UP} +var + E: Integer; +{$ENDIF} +begin +{$IFDEF DELPHIXE6_UP} + Result := SysUtils.StrToUInt64(S); // StrToUInt64 only exists under XE6 or above +{$ELSE} + Result := _ValUInt64(S, E); + if E <> 0 then raise EConvertError.CreateResFmt(@SInvalidInteger, [S]); +{$ENDIF} +end; + +function UInt64Compare(A, B: TUInt64): Integer; +{$IFNDEF SUPPORT_UINT64} +var + HiA, HiB, LoA, LoB: Cardinal; +{$ENDIF} +begin +{$IFDEF SUPPORT_UINT64} + if A > B then + Result := 1 + else if A < B then + Result := -1 + else + Result := 0; +{$ELSE} + HiA := (A and $FFFFFFFF00000000) shr 32; + HiB := (B and $FFFFFFFF00000000) shr 32; + if HiA > HiB then + Result := 1 + else if HiA < HiB then + Result := -1 + else + begin + LoA := Cardinal(A and $00000000FFFFFFFF); + LoB := Cardinal(B and $00000000FFFFFFFF); + if LoA > LoB then + Result := 1 + else if LoA < LoB then + Result := -1 + else + Result := 0; + end; +{$ENDIF} +end; + +function UInt64Sqrt(N: TUInt64): TUInt64; +var + Rem, Root: TUInt64; + I: Integer; +begin + Result := 0; + if N = 0 then + Exit; + + if UInt64Compare(N, 4) < 0 then + begin + Result := 1; + Exit; + end; + + Rem := 0; + Root := 0; + + for I := 0 to 31 do + begin + Root := Root shl 1; + Inc(Root); + + Rem := Rem shl 2; + Rem := Rem or (N shr 62); + N := N shl 2; + + if UInt64Compare(Root, Rem) <= 0 then + begin + Rem := Rem - Root; + Inc(Root); + end + else + Dec(Root); + end; + Result := Root shr 1; +end; + +function UInt32IsNegative(N: Cardinal): Boolean; +begin + Result := (N and (1 shl 31)) <> 0; +end; + +function UInt64IsNegative(N: TUInt64): Boolean; +begin +{$IFDEF SUPPORT_UINT64} + Result := (N and (UInt64(1) shl 63)) <> 0; +{$ELSE} + Result := N < 0; +{$ENDIF} +end; + +// UInt64 ijһλ 1λ Index 0 ʼ +procedure UInt64SetBit(var B: TUInt64; Index: Integer); +begin + B := B or (TUInt64(1) shl Index); +end; + +// UInt64 ijһλ 0λ Index 0 ʼ +procedure UInt64ClearBit(var B: TUInt64; Index: Integer); +begin + B := B and not (TUInt64(1) shl Index); +end; + +// UInt64 ĵڼλǷ 10 ʼ +function GetUInt64BitSet(B: TUInt64; Index: Integer): Boolean; +begin + B := B and (TUInt64(1) shl Index); + Result := B <> 0; +end; + +// UInt64 1 ߶λǵڼλλ 0û 1 -1 +function GetUInt64HighBits(B: TUInt64): Integer; +begin + if B = 0 then + begin + Result := -1; + Exit; + end; + + Result := 1; + if B shr 32 = 0 then + begin + Inc(Result, 32); + B := B shl 32; + end; + if B shr 48 = 0 then + begin + Inc(Result, 16); + B := B shl 16; + end; + if B shr 56 = 0 then + begin + Inc(Result, 8); + B := B shl 8; + end; + if B shr 60 = 0 then + begin + Inc(Result, 4); + B := B shl 4; + end; + if B shr 62 = 0 then + begin + Inc(Result, 2); + B := B shl 2; + end; + Result := Result - Integer(B shr 63); // õǰ 0 + Result := 63 - Result; +end; + +// Cardinal 1 ߶λǵڼλλ 0û 1 -1 +function GetUInt32HighBits(B: Cardinal): Integer; +begin + if B = 0 then + begin + Result := -1; + Exit; + end; + + Result := 1; + if B shr 16 = 0 then + begin + Inc(Result, 16); + B := B shl 16; + end; + if B shr 24 = 0 then + begin + Inc(Result, 8); + B := B shl 8; + end; + if B shr 28 = 0 then + begin + Inc(Result, 4); + B := B shl 4; + end; + if B shr 30 = 0 then + begin + Inc(Result, 2); + B := B shl 2; + end; + Result := Result - Integer(B shr 31); // õǰ 0 + Result := 31 - Result; +end; + +function GetUInt16HighBits(B: Word): Integer; +begin + if B = 0 then + begin + Result := -1; + Exit; + end; + + Result := 1; + if B shr 8 = 0 then + begin + Inc(Result, 8); + B := B shl 8; + end; + if B shr 12 = 0 then + begin + Inc(Result, 4); + B := B shl 4; + end; + if B shr 14 = 0 then + begin + Inc(Result, 2); + B := B shl 2; + end; + Result := Result - Integer(B shr 15); // õǰ 0 + Result := 15 - Result; +end; + +function GetUInt8HighBits(B: Byte): Integer; +begin + if B = 0 then + begin + Result := -1; + Exit; + end; + + Result := 1; + if B shr 4 = 0 then + begin + Inc(Result, 4); + B := B shl 4; + end; + if B shr 6 = 0 then + begin + Inc(Result, 2); + B := B shl 2; + end; + Result := Result - Integer(B shr 7); // õǰ 0 + Result := 7 - Result; +end; + +// Int64 1 Ͷλǵڼλλ 0û 1 -1 +function GetUInt64LowBits(B: TUInt64): Integer; +var + Y: TUInt64; + N: Integer; +begin + Result := -1; + if B = 0 then + Exit; + + N := 63; + Y := B shl 32; + if Y <> 0 then + begin + Dec(N, 32); + B := Y; + end; + Y := B shl 16; + if Y <> 0 then + begin + Dec(N, 16); + B := Y; + end; + Y := B shl 8; + if Y <> 0 then + begin + Dec(N, 8); + B := Y; + end; + Y := B shl 4; + if Y <> 0 then + begin + Dec(N, 4); + B := Y; + end; + Y := B shl 2; + if Y <> 0 then + begin + Dec(N, 2); + B := Y; + end; + B := B shl 1; + Result := N - Integer(B shr 63); +end; + +// Cardinal 1 Ͷλǵڼλλ 0û 1 -1 +function GetUInt32LowBits(B: Cardinal): Integer; +var + Y, N: Integer; +begin + Result := -1; + if B = 0 then + Exit; + + N := 31; + Y := B shl 16; + if Y <> 0 then + begin + Dec(N, 16); + B := Y; + end; + Y := B shl 8; + if Y <> 0 then + begin + Dec(N, 8); + B := Y; + end; + Y := B shl 4; + if Y <> 0 then + begin + Dec(N, 4); + B := Y; + end; + Y := B shl 2; + if Y <> 0 then + begin + Dec(N, 2); + B := Y; + end; + B := B shl 1; + Result := N - Integer(B shr 31); +end; + +// Word 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 +function GetUInt16LowBits(B: Word): Integer; +var + Y, N: Integer; +begin + Result := -1; + if B = 0 then + Exit; + + N := 15; + Y := B shl 8; + if Y <> 0 then + begin + Dec(N, 8); + B := Y; + end; + Y := B shl 4; + if Y <> 0 then + begin + Dec(N, 4); + B := Y; + end; + Y := B shl 2; + if Y <> 0 then + begin + Dec(N, 2); + B := Y; + end; + B := B shl 1; + Result := N - Integer(B shr 15); +end; + +// Byte 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 +function GetUInt8LowBits(B: Byte): Integer; +var + N: Integer; +begin + Result := -1; + if B = 0 then + Exit; + + N := 7; + if B shr 4 = 0 then + begin + Dec(N, 4); + B := B shl 4; + end; + if B shr 6 = 0 then + begin + Dec(N, 2); + B := B shl 2; + end; + B := B shl 1; + Result := N - Integer(B shr 7); +end; + +// װ Int64 Modֵʱȡģģ +function Int64Mod(M, N: Int64): Int64; +begin + if M > 0 then + Result := M mod N + else + Result := N - ((-M) mod N); +end; + +// жһ 32 λ޷Ƿ 2 +function IsUInt32PowerOf2(N: Cardinal): Boolean; +begin + Result := (N and (N - 1)) = 0; +end; + +// жһ 64 λ޷Ƿ 2 +function IsUInt64PowerOf2(N: TUInt64): Boolean; +begin + Result := (N and (N - 1)) = 0; +end; + +// õһָ 32 λ޷ȵ 2 ݣ򷵻 0 +function GetUInt32PowerOf2GreaterEqual(N: Cardinal): Cardinal; +begin + Result := N - 1; + Result := Result or (Result shr 1); + Result := Result or (Result shr 2); + Result := Result or (Result shr 4); + Result := Result or (Result shr 8); + Result := Result or (Result shr 16); + Inc(Result); +end; + +// õһָ 64 λ޷ 2 ݣ򷵻 0 +function GetUInt64PowerOf2GreaterEqual(N: TUInt64): TUInt64; +begin + Result := N - 1; + Result := Result or (Result shr 1); + Result := Result or (Result shr 2); + Result := Result or (Result shr 4); + Result := Result or (Result shr 8); + Result := Result or (Result shr 16); + Result := Result or (Result shr 32); + Inc(Result); +end; + +// ж 32 λзǷ 32 λз +function IsInt32AddOverflow(A, B: Integer): Boolean; +var + C: Integer; +begin + C := A + B; + Result := ((A > 0) and (B > 0) and (C < 0)) or // ͬҽ˵ + ((A < 0) and (B < 0) and (C > 0)); +end; + +// ж 32 λ޷Ƿ 32 λ޷ +function IsUInt32AddOverflow(A, B: Cardinal): Boolean; +begin + Result := (A + B) < A; // ޷ӣֻҪСһ˵ +end; + +// ж 64 λзǷ 64 λз +function IsInt64AddOverflow(A, B: Int64): Boolean; +var + C: Int64; +begin + C := A + B; + Result := ((A > 0) and (B > 0) and (C < 0)) or // ͬҽ˵ + ((A < 0) and (B < 0) and (C > 0)); +end; + +// ж 64 λ޷Ƿ 64 λ޷ +function IsUInt64AddOverflow(A, B: TUInt64): Boolean; +begin + Result := UInt64Compare(A + B, A) < 0; // ޷ӣֻҪСһ˵ +end; + +function IsUInt64SubOverflowInt32(A: TUInt64; B: TUInt64): Boolean; +var + GT: Boolean; + R: TUInt64; +begin + GT := UInt64Compare(A, B) >= 0; // GT ʾ A >= B + if GT then + begin + R := A - B; + // ж 64 λ޷ŷΧ R Ƿ񳬹 MaxInt32 + Result := UInt64Compare(R, TUInt64(CN_MAX_INT32)) > 0; + end + else + begin + R := B - A; + // ж 64 λзŷΧ -R ǷС MinInt32Ҳж 64 λ޷ R Ƿ񳬹 MinInt32 ޷ʽ + Result := UInt64Compare(R, CN_MIN_INT32_IN_INT64) > 0; + end; +end; + +// 64 λ޷ӣA + B => R 1 λ +procedure UInt64Add(var R: TUInt64; A, B: TUInt64; out Carry: Integer); +begin + R := A + B; + if UInt64Compare(R, A) < 0 then // ޷ӣֻҪСһ˵ + Carry := 1 + else + Carry := 0; +end; + +// 64 λ޷A - B => Rнλ 1 λ +procedure UInt64Sub(var R: TUInt64; A, B: TUInt64; out Carry: Integer); +begin + R := A - B; + if UInt64Compare(R, A) > 0 then // ޷ֻҪڱ˵λ + Carry := 1 + else + Carry := 0; +end; + +// ж 32 λзǷ 32 λз +function IsInt32MulOverflow(A, B: Integer): Boolean; +var + T: Integer; +begin + T := A * B; + Result := (B <> 0) and ((T div B) <> A); +end; + +// ж 32 λ޷Ƿ 32 λ޷ +function IsUInt32MulOverflow(A, B: Cardinal): Boolean; +var + T: TUInt64; +begin + T := TUInt64(A) * TUInt64(B); + Result := (T = Cardinal(T)); +end; + +// ж 32 λ޷Ƿ 64 λзδҲ False ʱR ֱӷؽ +function IsUInt32MulOverflowInt64(A, B: Cardinal; out R: TUInt64): Boolean; +var + T: Int64; +begin + T := Int64(A) * Int64(B); + Result := T < 0; // Int64 ֵ˵ + if not Result then + R := TUInt64(T); +end; + +// ж 64 λзǷ 64 λз +function IsInt64MulOverflow(A, B: Int64): Boolean; +var + T: Int64; +begin + T := A * B; + Result := (B <> 0) and ((T div B) <> A); +end; + +// ָת֧ͣ 32/64 λ +function PointerToInteger(P: Pointer): Integer; +begin +{$IFDEF CPU64BITS} + // ôд Pointer ĵ 32 λ Integer + Result := Integer(P); +{$ELSE} + Result := Integer(P); +{$ENDIF} +end; + +// תָ֧ͣ 32/64 λ +function IntegerToPointer(I: Integer): Pointer; +begin +{$IFDEF CPU64BITS} + // ôд Pointer ĵ 32 λ Integer + Result := Pointer(I); +{$ELSE} + Result := Pointer(I); +{$ENDIF} +end; + +// Int64 Χĺ࣬Ҫ N 0 +function Int64NonNegativeAddMod(A, B, N: Int64): Int64; +begin + if IsInt64AddOverflow(A, B) then // Int64 + begin + if A > 0 then + begin + // A B 0 UInt64 ȡģδ UInt64 ޣע N δ Int64 ȡģС Int64 ޣɸֵ + Result := UInt64NonNegativeAddMod(A, B, N); + end + else + begin + // A B С 0ȡ UInt64 ȡģĺδ UInt64 ޣģٱһ +{$IFDEF SUPPORT_UINT64} + Result := UInt64(N) - UInt64NonNegativeAddMod(-A, -B, N); +{$ELSE} + Result := N - UInt64NonNegativeAddMod(-A, -B, N); +{$ENDIF} + end; + end + else // ֱӼ + Result := Int64NonNegativeMod(A + B, N); +end; + +// UInt64 Χĺ࣬Ҫ N 0 +function UInt64NonNegativeAddMod(A, B, N: TUInt64): TUInt64; +var + C, D: TUInt64; +begin + if IsUInt64AddOverflow(A, B) then // + begin + C := UInt64Mod(A, N); // ͸ģ + D := UInt64Mod(B, N); + if IsUInt64AddOverflow(C, D) then + begin + // ˵ģ󣬸ģûá + // һڵ 2^63N 2^63 + 1 + // = + 2^64 + // mod N = mod N + (2^64 - 1) mod N) + 1 + // N 2^63 + 1 2^64 - 2ǰӲֱӺһģ + Result := UInt64Mod(UInt64Mod(A + B, N) + UInt64Mod(CN_MAX_TUINT64, N) + 1, N); + end + else + Result := UInt64Mod(C + D, N); + end + else + begin + Result := UInt64Mod(A + B, N); + end; +end; + +function Int64NonNegativeMulMod(A, B, N: Int64): Int64; +var + Neg: Boolean; +begin + if N <= 0 then + raise EDivByZero.Create(SDivByZero); + + // ΧСֱ + if not IsInt64MulOverflow(A, B) then + begin + Result := A * B mod N; + if Result < 0 then + Result := Result + N; + Exit; + end; + + // ŵ + Result := 0; + if (A = 0) or (B = 0) then + Exit; + + Neg := False; + if (A < 0) and (B > 0) then + begin + A := -A; + Neg := True; + end + else if (A > 0) and (B < 0) then + begin + B := -B; + Neg := True; + end + else if (A < 0) and (B < 0) then + begin + A := -A; + B := -B; + end; + + // λѭ + while B <> 0 do + begin + if (B and 1) <> 0 then + Result := ((Result mod N) + (A mod N)) mod N; + + A := A shl 1; + if A >= N then + A := A mod N; + + B := B shr 1; + end; + + if Neg then + Result := N - Result; +end; + +function UInt64NonNegativeMulMod(A, B, N: TUInt64): TUInt64; +begin + Result := 0; + if (UInt64Compare(A, CN_MAX_UINT32) <= 0) and (UInt64Compare(B, CN_MAX_UINT32) <= 0) then + begin + Result := UInt64Mod(A * B, N); // 㹻СĻֱӳ˺ģ + end + else + begin + while B <> 0 do + begin + if (B and 1) <> 0 then + Result := UInt64NonNegativeAddMod(Result, A, N); + + A := UInt64NonNegativeAddMod(A, A, N); + // ôͳ㷨 A := A shl 1 N mod NΪ + + B := B shr 1; + end; + end; +end; + +// װķǸຯҲΪʱӸ豣֤ P 0 +function Int64NonNegativeMod(N: Int64; P: Int64): Int64; +begin + if P <= 0 then + raise EDivByZero.Create(SDivByZero); + + Result := N mod P; + if Result < 0 then + Inc(Result, P); +end; + +// Int64 ķǸָ +function Int64NonNegativPower(N: Int64; Exp: Integer): Int64; +var + T: Int64; +begin + if Exp < 0 then + raise ERangeError.Create(SRangeError) + else if Exp = 0 then + begin + if N <> 0 then + Result := 1 + else + raise EDivByZero.Create(SDivByZero); + end + else if Exp = 1 then + Result := N + else + begin + Result := 1; + T := N; + + while Exp > 0 do + begin + if (Exp and 1) <> 0 then + Result := Result * T; + + Exp := Exp shr 1; + T := T * T; + end; + end; +end; + +function Int64NonNegativeRoot(N: Int64; Exp: Integer): Int64; +var + I: Integer; + X: Int64; + X0, X1: Extended; +begin + if (Exp < 0) or (N < 0) then + raise ERangeError.Create(SRangeError) + else if Exp = 0 then + raise EDivByZero.Create(SDivByZero) + else if (N = 0) or (N = 1) then + Result := N + else if Exp = 2 then + Result := UInt64Sqrt(N) + else + begin + // ţٵ + I := GetUInt64HighBits(N) + 1; // õԼ Log2 N ֵ + I := (I div Exp) + 1; + X := 1 shl I; // õһϴ X0 ֵΪʼֵ + + X0 := X; + X1 := X0 - (Power(X0, Exp) - N) / (Exp * Power(X0, Exp - 1)); + + while True do + begin + if (Trunc(X0) = Trunc(X1)) and (Abs(X0 - X1) < 0.001) then + begin + Result := Trunc(X1); // Trunc ֻ֧ Int64˻ + Exit; + end; + + X0 := X1; + X1 := X0 - (Power(X0, Exp) - N) / (Exp * Power(X0, Exp - 1)); + end; + end; +end; + +function UInt64NonNegativPower(N: TUInt64; Exp: Integer): TUInt64; +var + T, RL, RH: TUInt64; +begin + if Exp < 0 then + raise ERangeError.Create(SRangeError) + else if Exp = 0 then + begin + if N <> 0 then + Result := 1 + else + raise EDivByZero.Create(SDivByZero); + end + else if Exp = 1 then + Result := N + else + begin + Result := 1; + T := N; + + while Exp > 0 do + begin + if (Exp and 1) <> 0 then + begin + UInt64MulUInt64(Result, T, RL, RH); + Result := RL; + end; + + Exp := Exp shr 1; + UInt64MulUInt64(T, T, RL, RH); + T := RL; + end; + end; +end; + +function UInt64NonNegativeRoot(N: TUInt64; Exp: Integer): TUInt64; +var + I: Integer; + X: TUInt64; + XN, X0, X1: Extended; +begin + if Exp < 0 then + raise ERangeError.Create(SRangeError) + else if Exp = 0 then + raise EDivByZero.Create(SDivByZero) + else if (N = 0) or (N = 1) then + Result := N + else if Exp = 2 then + Result := UInt64Sqrt(N) + else + begin + // ţٵ + I := GetUInt64HighBits(N) + 1; // õԼ Log2 N ֵ + I := (I div Exp) + 1; + X := 1 shl I; // õһϴ X0 ֵΪʼֵ + + X0 := UInt64ToExtended(X); + XN := UInt64ToExtended(N); + X1 := X0 - (Power(X0, Exp) - XN) / (Exp * Power(X0, Exp - 1)); + + while True do + begin + if (ExtendedToUInt64(X0) = ExtendedToUInt64(X1)) and (Abs(X0 - X1) < 0.001) then + begin + Result := ExtendedToUInt64(X1); + Exit; + end; + + X0 := X1; + X1 := X0 - (Power(X0, Exp) - XN) / (Exp * Power(X0, Exp - 1)); + end; + end; +end; + +function IsUInt128BitSet(Lo, Hi: TUInt64; N: Integer): Boolean; +begin + if N < 64 then + Result := (Lo and (TUInt64(1) shl N)) <> 0 + else + begin + Dec(N, 64); + Result := (Hi and (TUInt64(1) shl N)) <> 0; + end; +end; + +procedure SetUInt128Bit(var Lo, Hi: TUInt64; N: Integer); +begin + if N < 64 then + Lo := Lo or (TUInt64(1) shl N) + else + begin + Dec(N, 64); + Hi := Hi or (TUInt64(1) shl N); + end; +end; + +procedure ClearUInt128Bit(var Lo, Hi: TUInt64; N: Integer); +begin + if N < 64 then + Lo := Lo and not (TUInt64(1) shl N) + else + begin + Dec(N, 64); + Hi := Hi and not (TUInt64(1) shl N); + end; +end; + +function UnsignedAddWithLimitRadix(A, B, C: Cardinal; var R: Cardinal; + L, H: Cardinal): Cardinal; +begin + R := A + B + C; + if R > H then // нλ + begin + A := H - L + 1; // õ + B := R - L; // õ L ֵ + + Result := B div A; // Ƶĵڼͽ + R := L + (B mod A); // ȥƺ + end + else + Result := 0; +end; + +procedure InternalQuickSort(Mem: Pointer; L, R: Integer; ElementByteSize: Integer; + CompareProc: TCnMemSortCompareProc); +var + I, J, P: Integer; +begin + repeat + I := L; + J := R; + P := (L + R) shr 1; + repeat + while CompareProc(Pointer(TCnNativeInt(Mem) + I * ElementByteSize), + Pointer(TCnNativeInt(Mem) + P * ElementByteSize), ElementByteSize) < 0 do + Inc(I); + while CompareProc(Pointer(TCnNativeInt(Mem) + J * ElementByteSize), + Pointer(TCnNativeInt(Mem) + P * ElementByteSize), ElementByteSize) > 0 do + Dec(J); + + if I <= J then + begin + MemorySwap(Pointer(TCnNativeInt(Mem) + I * ElementByteSize), + Pointer(TCnNativeInt(Mem) + J * ElementByteSize), ElementByteSize); + + if P = I then + P := J + else if P = J then + P := I; + Inc(I); + Dec(J); + end; + until I > J; + + if L < J then + InternalQuickSort(Mem, L, J, ElementByteSize, CompareProc); + L := I; + until I >= R; +end; + +function DefaultCompareProc(P1, P2: Pointer; ElementByteSize: Integer): Integer; +begin + Result := MemoryCompare(P1, P2, ElementByteSize); +end; + +procedure MemoryQuickSort(Mem: Pointer; ElementByteSize: Integer; + ElementCount: Integer; CompareProc: TCnMemSortCompareProc); +begin + if (Mem <> nil) and (ElementCount > 0) and (ElementCount > 0) then + begin + if Assigned(CompareProc) then + InternalQuickSort(Mem, 0, ElementCount - 1, ElementByteSize, CompareProc) + else + InternalQuickSort(Mem, 0, ElementCount - 1, ElementByteSize, DefaultCompareProc); + end; +end; + +{$IFDEF COMPILER5} + +function BoolToStr(Value: Boolean; UseBoolStrs: Boolean): string; +begin + if UseBoolStrs then + begin + if Value then + Result := 'True' + else + Result := 'False'; + end + else + begin + if Value then + Result := '-1' + else + Result := '0'; + end; +end; + +{$ENDIF} + +// =========================== ѭλ ==================================== + +function RotateLeft16(A: Word; N: Integer): Word; +begin + Result := (A shl N) or (A shr (16 - N)); +end; + +function RotateRight16(A: Word; N: Integer): Word; +begin + Result := (A shr N) or (A shl (16 - N)); +end; + +function RotateLeft32(A: Cardinal; N: Integer): Cardinal; +begin + Result := (A shl N) or (A shr (32 - N)); +end; + +function RotateRight32(A: Cardinal; N: Integer): Cardinal; +begin + Result := (A shr N) or (A shl (32 - N)); +end; + +function RotateLeft64(A: TUInt64; N: Integer): TUInt64; +begin + Result := (A shl N) or (A shr (64 - N)); +end; +function RotateRight64(A: TUInt64; N: Integer): TUInt64; +begin + Result := (A shr N) or (A shl (64 - N)); +end; + +initialization + FByteOrderIsBigEndian := CurrentByteOrderIsBigEndian; + +end. diff --git a/CnPack/Crypto/CnPemUtils.pas b/CnPack/Crypto/CnPemUtils.pas index f4d5719..3f7ffeb 100644 --- a/CnPack/Crypto/CnPemUtils.pas +++ b/CnPack/Crypto/CnPemUtils.pas @@ -1,1219 +1,1219 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -unit CnPemUtils; -{* |
-================================================================================
-* ƣ
-* ԪƣPEM ʽ뵥Ԫ
-* ԪߣCnPack 
-*     עԪʵ PEM ʽĶȡ뱣棬ӽܻơ
-*           Ҳʵ PKCS1/PKCS5/PKCS7/ISO10126 ȶ봦ơ
-*           ע֧ PKCS12 淶֤鼰Կװʽ
-* ƽ̨WinXP + Delphi 5.0
-* ݲԣδ
-*   õԪ豾ػ
-* ޸ļ¼2024.05.27 V1.6
-*                ISO10126 Ĵ
-*           2023.12.14 V1.5
-*                SaveMemoryToPemStream δ
-*           2022.03.09 V1.4
-*                PKCS5 Ĵ
-*           2021.05.14 V1.3
-*               ĸ PKCS7 Ĵ
-*           2020.03.27 V1.2
-*               ģ Openssl ʵ PEM ļд룬ֲֻּ֧㷨
-*               Ŀǰд des/3des/aes128/192/256 PKCS7 룬 Openssl 1.0.2g
-*           2020.03.23 V1.1
-*               ģ Openssl ʵ PEM ļܶȡֲֻּ֧㷨
-*               Ŀǰȡ des/3des/aes128/192/256 PKCS7 룬 Openssl 1.0.2g
-*           2020.03.18 V1.0
-*               Ԫ CnRSA ж
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - SysUtils, Classes, CnNative, CnRandom, CnKDF, CnBase64, CnAES, CnDES; - -const - CN_PKCS1_BLOCK_TYPE_PRIVATE_00 = 00; - {* PKCS1 ʱĿֵֶһĬӦ RSA ˽Կܳ} - - CN_PKCS1_BLOCK_TYPE_PRIVATE_FF = 01; - {* PKCS1 ʱĿֵֶĬӦ RSA ˽Կǩ} - - CN_PKCS1_BLOCK_TYPE_PUBLIC_RANDOM = 02; - {* PKCS1 ʱĿֵֶĬӦ RSA ĹԿܳ} - -type - TCnKeyHashMethod = (ckhMd5, ckhSha256); - {* PEM ʽֵ֧Ӵ} - - TCnKeyEncryptMethod = (ckeNone, ckeDES, cke3DES, ckeAES128, ckeAES192, ckeAES256); - {* PEM ʽֵ֧ļ} - -// ======================= PEM ļдּ֧ӽ ======================== - -function LoadPemFileToMemory(const FileName: string; const ExpectHead: string; - const ExpectTail: string; MemoryStream: TMemoryStream; const Password: string = ''; - KeyHashMethod: TCnKeyHashMethod = ckhMd5): Boolean; -{* PEM ʽļָ֤ͷβʵݲܽ Base64 롣 - - - const FileName: string - ļ - const ExpectHead: string - ͷ - const ExpectTail: string - β - MemoryStream: TMemoryStream - ڴ - const Password: string - ļܣڴṩ - KeyHashMethod: TCnKeyHashMethod - ļʹõӴ - - ֵBoolean - ضǷɹ -} - -function LoadPemStreamToMemory(Stream: TStream; const ExpectHead: string; - const ExpectTail: string; MemoryStream: TMemoryStream; const Password: string = ''; - KeyHashMethod: TCnKeyHashMethod = ckhMd5): Boolean; -{* PEM ʽļָ֤ͷβʵݲܽ Base64 롣 - - - Stream: TStream - - const ExpectHead: string - ͷ - const ExpectTail: string - β - MemoryStream: TMemoryStream - ڴ - const Password: string - ܣڴṩ - KeyHashMethod: TCnKeyHashMethod - ʹõӴ - - ֵBoolean - ضǷɹ -} - -function SaveMemoryToPemFile(const FileName: string; const Head: string; const Tail: string; - MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod = ckeNone; - KeyHashMethod: TCnKeyHashMethod = ckhMd5; const Password: string = ''; Append: Boolean = False): Boolean; -{* Stream ݽ Base64 ܷвļͷβдļAppend Ϊ True ʱʾ׷ӡ - - - const FileName: string - дļ - const Head: string - дͷ - const Tail: string - дβ - MemoryStream: TMemoryStream - д - KeyEncryptMethod: TCnKeyEncryptMethod - üͣĬϲ - KeyHashMethod: TCnKeyHashMethod - Ӵ - const Password: string - 룬򴫿 - Append: Boolean - Ƿ׷ӵķʽд - - ֵBoolean - Ƿдɹ -} - -function SaveMemoryToPemStream(Stream: TStream; const Head: string; const Tail: string; - MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod = ckeNone; - KeyHashMethod: TCnKeyHashMethod = ckhMd5; const Password: string = ''; Append: Boolean = False): Boolean; -{* Stream ݽ Base64 ܷвͷβдAppend Ϊ True ʱʾ׷ӡ - - - Stream: TStream - д - const Head: string - дͷ - const Tail: string - дβ - MemoryStream: TMemoryStream - д - KeyEncryptMethod: TCnKeyEncryptMethod - üͣĬϲ - KeyHashMethod: TCnKeyHashMethod - ӴͣĬϲӴ - const Password: string - 룬򴫿 - Append: Boolean - Ƿ׷ӵķʽд - - ֵBoolean - Ƿдɹ -} - -// ===================== PKCS1 / PKCS7 Padding 봦 ==================== - -function AddPKCS1Padding(PaddingType: Integer; BlockSize: Integer; Data: Pointer; - DataByteLen: Integer; OutStream: TStream): Boolean; -{* ݿ鲹д Stream Уسɹڲô롣 - PaddingType ȡ 012BlockLen ֽ 128 ȡʽ - EB = 00 || BT || PS || 00 || D - 00 ǰ涨ֽڣBT 1 ֽڵ PaddingType0 1 2 ֱ 00 FF - PS Ķֽݣ 00 ǹ涨Ľβֽڡ - - - PaddingType: Integer - ͣȡ 0 1 2 - BlockSize: Integer - ֽڳ - Data: Pointer - ݿĵַ - DataByteLen: Integer - ݿֽڳ - OutStream: TStream - - - ֵBoolean - ضǷӳɹ -} - -function RemovePKCS1Padding(InData: Pointer; InDataByteLen: Integer; OutBuf: Pointer; - out OutByteLen: Integer): Boolean; -{* ȥݿ PKCS1 PaddingسɹOutBuf ָĿóб֤ - ɹOutLen ԭݳȡ - - - InData: Pointer - ȥݿĵַ - InDataByteLen: Integer - ȥݿֽڳ - OutBuf: Pointer - ȥݵ䳤ȱ㹻 - out OutByteLen: Integer - ȥݳ - - ֵBoolean - ضǷȥɹ -} - -function GetPKCS7PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; -{* ԭʼ鳤ȼ PKCS7 ijȡ - - - OrignalByteLen: Integer - ԭʼֽڳ - BlockSize: Integer - PKCS7 ֽڳ - - ֵInteger - PKCS7 ֽڳ -} - -procedure AddPKCS7Padding(Stream: TMemoryStream; BlockSize: Integer); -{* ĩβ PKCS7 涨䡰ݡ - - - Stream: TMemoryStream - ڴݣݽ׷дβ - BlockSize: Integer - PKCS7 ֽڳ - - ֵޣ -} - -procedure RemovePKCS7Padding(Stream: TMemoryStream); -{* ȥ PKCS7 涨ĩβ䡰ݡ - - - Stream: TMemoryStream - ȥڴ - - ֵޣ} - -function StrAddPKCS7Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; -{* ַĩβ PKCS7 涨䡰ݡ - - - const Str: AnsiString - ַ - BlockSize: Integer - PKCS7 ֽڳ - - ֵAnsiString - ضַ -} - -function StrRemovePKCS7Padding(const Str: AnsiString): AnsiString; -{* ȥ PKCS7 涨ַĩβ䡰ݡ - - - const Str: AnsiString - ȥַ - - ֵAnsiString - ȥַ -} - -procedure BytesAddPKCS7Padding(var Data: TBytes; BlockSize: Integer); -{* ֽĩβ PKCS7 涨䡰ݡ - - - var Data: TBytes - ֽ飬ݽ׷β - BlockSize: Integer - PKCS7 ֽڳ - - ֵޣ -} - -procedure BytesRemovePKCS7Padding(var Data: TBytes); -{* ȥ PKCS7 涨ֽĩβ䡰ݡ - - - var Data: TBytes - ȥֽ - - ֵޣ -} - -procedure AddPKCS5Padding(Stream: TMemoryStream); -{* ĩβ PKCS5 涨䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ - - - Stream: TMemoryStream - ڴݽ׷β - - ֵޣ -} - -procedure RemovePKCS5Padding(Stream: TMemoryStream); -{* ȥ PKCS7 涨ĩβ䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ - - - Stream: TMemoryStream - ȥڴ - - ֵޣ -} - -function StrAddPKCS5Padding(const Str: AnsiString): AnsiString; -{* ַĩβ PKCS5 涨䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ - - - const Str: AnsiString - ַ - - ֵAnsiString - ضַ -} - -function StrRemovePKCS5Padding(const Str: AnsiString): AnsiString; -{* ȥ PKCS5 涨ַĩβ䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ - - - const Str: AnsiString - ȥַ - - ֵAnsiString - ȥַ -} - -procedure BytesAddPKCS5Padding(var Data: TBytes); -{* ֽĩβ PKCS5 涨䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ - - - var Data: TBytes - ֽ飬ݽ׷β - - ֵޣ -} - -procedure BytesRemovePKCS5Padding(var Data: TBytes); -{* ȥ PKCS7 涨ֽĩβ䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ - - - var Data: TBytes - ȥֽ - - ֵޣ -} - -function GetISO10126PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; -{* ԭʼ鳤ȼ ISO10126Padding ijȡ - - - OrignalByteLen: Integer - ԭʼֽڳ - BlockSize: Integer - ISO10126 ֽڳ - - ֵInteger - PKCS7 ֽڳ -} - -procedure AddISO10126Padding(Stream: TMemoryStream; BlockSize: Integer); -{* ĩβ ISO10126Padding 涨䡰ͼݡ - - - Stream: TMemoryStream - ڴݽ׷β - BlockSize: Integer - ISO10126 ֽڳ - - ֵޣ -} - -procedure RemoveISO10126Padding(Stream: TMemoryStream); -{* ȥ ISO10126Padding 涨ĩβ䡰ͼݡ - - - Stream: TMemoryStream - ȥڴ - - ֵޣ -} - -function StrAddISO10126Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; -{* ַĩβ ISO10126Padding 涨䡰ͼݡ - - - const Str: AnsiString - ַ - BlockSize: Integer - ISO10126 ֽڴС - - ֵAnsiString - ضַ -} - -function StrRemoveISO10126Padding(const Str: AnsiString): AnsiString; -{* ȥ ISO10126Padding 涨ַĩβ䡰ͼݡ - - - const Str: AnsiString - ȥַ - - ֵAnsiString - ȥַ -} - -procedure BytesAddISO10126Padding(var Data: TBytes; BlockSize: Integer); -{* ֽĩβ ISO10126Padding 涨䡰ͼݡ - - - var Data: TBytes - ֽ飬ݽ׷β - BlockSize: Integer - ISO10126 ֽڳ - - ֵޣ -} - -procedure BytesRemoveISO10126Padding(var Data: TBytes); -{* ȥ ISO10126Padding 涨ֽĩβ䡰ͼݡ - - - var Data: TBytes - ȥֽ - - ֵޣ -} - -implementation - -const - PKCS1_PADDING_SIZE = 11; // һǰ 00һֽڡ 8 ֽ䣬һ 00 β - PKCS5_BLOCK_SIZE = 8; - - ENC_HEAD_PROCTYPE = 'Proc-Type:'; - ENC_HEAD_PROCTYPE_NUM = '4'; - ENC_HEAD_ENCRYPTED = 'ENCRYPTED'; - ENC_HEAD_DEK = 'DEK-Info:'; - - ENC_TYPE_AES128 = 'AES-128'; - ENC_TYPE_AES192 = 'AES-192'; - ENC_TYPE_AES256 = 'AES-256'; - ENC_TYPE_DES = 'DES'; - ENC_TYPE_3DES = 'DES-EDE3'; - - ENC_BLOCK_CBC = 'CBC'; - - ENC_TYPE_STRS: array[TCnKeyEncryptMethod] of string = - ('', ENC_TYPE_DES, ENC_TYPE_3DES, ENC_TYPE_AES128, ENC_TYPE_AES192, ENC_TYPE_AES256); - - ENC_TYPE_BLOCK_SIZE: array[TCnKeyEncryptMethod] of Byte = - (0, 8, 8, 16, 16, 16); - -function Min(A, B: Integer): Integer; -begin - if A < B then - Result := A - else - Result := B; -end; - -function AddPKCS1Padding(PaddingType, BlockSize: Integer; Data: Pointer; - DataByteLen: Integer; OutStream: TStream): Boolean; -var - I: Integer; - B, F: Byte; -begin - Result := False; - if (Data = nil) or (DataByteLen <= 0) then - Exit; - - // - if DataByteLen > BlockSize - PKCS1_PADDING_SIZE then - Exit; - - B := 0; - OutStream.Write(B, 1); // дǰֽ 00 - B := PaddingType; - F := BlockSize - DataByteLen - 3; // 3 ʾһǰ 00һֽڡһ 00 β - - OutStream.Write(B, 1); - case PaddingType of - CN_PKCS1_BLOCK_TYPE_PRIVATE_00: - begin - B := 0; - for I := 1 to F do - OutStream.Write(B, 1); - end; - CN_PKCS1_BLOCK_TYPE_PRIVATE_FF: - begin - B := $FF; - for I := 1 to F do - OutStream.Write(B, 1); - end; - CN_PKCS1_BLOCK_TYPE_PUBLIC_RANDOM: - begin - Randomize; - for I := 1 to F do - begin - B := Trunc(Random(255)); - if B = 0 then - Inc(B); - OutStream.Write(B, 1); - end; - end; - else - Exit; - end; - - B := 0; - OutStream.Write(B, 1); - OutStream.Write(Data^, DataByteLen); - Result := True; -end; - -function RemovePKCS1Padding(InData: Pointer; InDataByteLen: Integer; OutBuf: Pointer; - out OutByteLen: Integer): Boolean; -var - P: PAnsiChar; - I, J, Start: Integer; -begin - Result := False; - OutByteLen := 0; - I := 0; - - P := PAnsiChar(InData); - while P[I] = #0 do // ַһ #0Ѿȥ - Inc(I); - - if I >= InDataByteLen then - Exit; - - Start := 0; - case Ord(P[I]) of - CN_PKCS1_BLOCK_TYPE_PRIVATE_00: - begin - // P[I + 1] ʼѰҷ 00 - J := I + 1; - while J < InDataByteLen do - begin - if P[J] <> #0 then - begin - Start := J; - Break; - end; - Inc(J); - end; - end; - CN_PKCS1_BLOCK_TYPE_PRIVATE_FF, - CN_PKCS1_BLOCK_TYPE_PUBLIC_RANDOM: - begin - // P[I + 1] ʼѰҵһ 00 ı - J := I + 1; - while J < InDataByteLen do - begin - if P[J] = #0 then - begin - Start := J; - Break; - end; - Inc(J); - end; - - if Start <> 0 then - Inc(Start); - end; - end; - - if Start > 0 then - begin - Move(P[Start], OutBuf^, InDataByteLen - Start); - OutByteLen := InDataByteLen - Start; - Result := True; - end; -end; - -function GetPKCS7PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; -var - R: Byte; -begin - R := OrignalByteLen mod BlockSize; - R := BlockSize - R; - if R = 0 then - R := R + BlockSize; - Result := OrignalByteLen + R; -end; - -procedure AddPKCS7Padding(Stream: TMemoryStream; BlockSize: Integer); -var - R: Byte; - Buf: array[0..255] of Byte; -begin - R := Stream.Size mod BlockSize; - R := BlockSize - R; - if R = 0 then - R := R + BlockSize; - - FillChar(Buf[0], R, R); - Stream.Position := Stream.Size; - Stream.Write(Buf[0], R); -end; - -procedure RemovePKCS7Padding(Stream: TMemoryStream); -var - L: Byte; - Len: Cardinal; - Mem: Pointer; -begin - // ȥ Stream ĩβ 9 9 Padding - if Stream.Size > 1 then - begin - Stream.Position := Stream.Size - 1; - Stream.Read(L, 1); - - if Stream.Size - L < 0 then // ߴ粻ף - Exit; - - Len := Stream.Size - L; - Mem := GetMemory(Len); - if Mem <> nil then - begin - Move(Stream.Memory^, Mem^, Len); - Stream.Clear; - Stream.Write(Mem^, Len); - FreeMemory(Mem); - end; - end; -end; - -function StrAddPKCS7Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; -var - I, L: Integer; - R: Byte; -begin - L := Length(Str); - R := L mod BlockSize; - R := BlockSize - R; - if R = 0 then - R := R + BlockSize; - - SetLength(Result, L + R); - if L > 0 then - Move(Str[1], Result[1], L); - - for I := 1 to R do - Result[L + I] := AnsiChar(R); -end; - -function StrRemovePKCS7Padding(const Str: AnsiString): AnsiString; -var - L: Integer; - V: Byte; -begin - Result := Str; - if Result = '' then - Exit; - - L := Length(Result); - V := Ord(Result[L]); // ĩǼʾ˼ - - if V <= L then - Delete(Result, L - V + 1, V); -end; - -procedure AddPKCS5Padding(Stream: TMemoryStream); -begin - AddPKCS7Padding(Stream, PKCS5_BLOCK_SIZE); -end; - -procedure RemovePKCS5Padding(Stream: TMemoryStream); -begin - RemovePKCS7Padding(Stream); -end; - -function StrAddPKCS5Padding(const Str: AnsiString): AnsiString; -begin - Result := StrAddPKCS7Padding(Str, PKCS5_BLOCK_SIZE); -end; - -function StrRemovePKCS5Padding(const Str: AnsiString): AnsiString; -begin - Result := StrRemovePKCS7Padding(Str); -end; - -procedure BytesAddPKCS7Padding(var Data: TBytes; BlockSize: Integer); -var - R: Byte; - L, I: Integer; -begin - L := Length(Data); - R := L mod BlockSize; - R := BlockSize - R; - if R = 0 then - R := R + BlockSize; - - SetLength(Data, L + R); - for I := 0 to R - 1 do - Data[L + I] := R; -end; - -procedure BytesRemovePKCS7Padding(var Data: TBytes); -var - L: Integer; - V: Byte; -begin - L := Length(Data); - if L = 0 then - Exit; - - V := Ord(Data[L - 1]); // ĩǼʾ˼ֽ - - if V <= L then - SetLength(Data, L - V); -end; - -procedure BytesAddPKCS5Padding(var Data: TBytes); -begin - BytesAddPKCS7Padding(Data, PKCS5_BLOCK_SIZE); -end; - -procedure BytesRemovePKCS5Padding(var Data: TBytes); -begin - BytesRemovePKCS7Padding(Data); -end; - -function GetISO10126PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; -begin - Result := GetPKCS7PaddingByteLength(OrignalByteLen, BlockSize); // Ϊֱͬӵ -end; - -procedure AddISO10126Padding(Stream: TMemoryStream; BlockSize: Integer); -var - R: Byte; - Buf: array[0..255] of Byte; -begin - R := Stream.Size mod BlockSize; - R := BlockSize - R; - if R = 0 then - R := R + BlockSize; - - FillChar(Buf[0], R, 0); - Buf[R - 1] := R; - Stream.Position := Stream.Size; - Stream.Write(Buf[0], R); -end; - -procedure RemoveISO10126Padding(Stream: TMemoryStream); -begin - RemovePKCS7Padding(Stream); // Ϊֱͬӵ -end; - -function StrAddISO10126Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; -var - I, L: Integer; - R: Byte; -begin - L := Length(Str); - R := L mod BlockSize; - R := BlockSize - R; - if R = 0 then - R := R + BlockSize; - - SetLength(Result, L + R); - if L > 0 then - Move(Str[1], Result[1], L); - - if R > 1 then - begin - for I := 1 to R - 1 do - Result[L + I] := #0; - end; - Result[L + R] := AnsiChar(R); -end; - -function StrRemoveISO10126Padding(const Str: AnsiString): AnsiString; -begin - Result := StrRemovePKCS7Padding(Str); // Ϊֱͬӵ -end; - -procedure BytesAddISO10126Padding(var Data: TBytes; BlockSize: Integer); -var - R: Byte; - L, I: Integer; -begin - L := Length(Data); - R := L mod BlockSize; - R := BlockSize - R; - if R = 0 then - R := R + BlockSize; - - SetLength(Data, L + R); - if R > 1 then - begin - for I := 0 to R - 2 do - Data[L + I] := 0; - end; - Data[L - 1 + R] := R; -end; - -procedure BytesRemoveISO10126Padding(var Data: TBytes); -begin - BytesRemovePKCS7Padding(Data); // Ϊֱͬӵ -end; - -function EncryptPemStream(KeyHash: TCnKeyHashMethod; KeyEncrypt: TCnKeyEncryptMethod; - Stream: TStream; const Password: string; out EncryptedHead: string): Boolean; -const - CRLF = #13#10; -var - ES: TMemoryStream; - Keys: array[0..31] of Byte; //  Key Ҳֻ 32 ֽ - IvStr: AnsiString; - HexIv: string; - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - AesIv: TCnAESBuffer; - DesKey: TCnDESKey; - Des3Key: TCn3DESKey; - DesIv: TCnDESIv; -begin - Result := False; - - // - if (KeyEncrypt = ckeNone) or (Password = '') then - Exit; - - // Iv - SetLength(IvStr, ENC_TYPE_BLOCK_SIZE[KeyEncrypt]); - CnRandomFillBytes(@(IvStr[1]), ENC_TYPE_BLOCK_SIZE[KeyEncrypt]); - HexIv := DataToHex(@(IvStr[1]), ENC_TYPE_BLOCK_SIZE[KeyEncrypt], True); // Ҫд - - EncryptedHead := ENC_HEAD_PROCTYPE + ' ' + ENC_HEAD_PROCTYPE_NUM + ',' + ENC_HEAD_ENCRYPTED + CRLF; - EncryptedHead := EncryptedHead + ENC_HEAD_DEK + ' ' + ENC_TYPE_STRS[KeyEncrypt] - + '-' + ENC_BLOCK_CBC + ',' + HexIv + CRLF; - - ES := TMemoryStream.Create; - Stream.Position := 0; - - try - if KeyHash = ckhMd5 then - begin - if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys)) then - Exit; - end - else if KeyHash = ckhSha256 then - begin - if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys), ckdSha256) then - Exit; - end - else - Exit; - - case KeyEncrypt of - ckeDES: - begin - Move(Keys[0], DesKey[0], SizeOf(TCnDESKey)); - Move(IvStr[1], DesIv[0], SizeOf(TCnDESIv)); - - DESEncryptStreamCBC(Stream, Stream.Size, DesKey, DesIv, ES); - Result := True; - end; - cke3DES: - begin - Move(Keys[0], Des3Key[0], SizeOf(TCn3DESKey)); - Move(IvStr[1], DesIv[0], SizeOf(TCn3DESIv)); - - TripleDESEncryptStreamCBC(Stream, Stream.Size, Des3Key, DesIv, ES); - Result := True; - end; - ckeAES128: - begin - Move(Keys[0], AESKey128[0], SizeOf(TCnAESKey128)); - Move(IvStr[1], AesIv[0], SizeOf(TCnAESBuffer)); - - EncryptAES128StreamCBC(Stream, Stream.Size, AESKey128, AesIv, ES); - Result := True; - end; - ckeAES192: - begin - Move(Keys[0], AESKey192[0], SizeOf(TCnAESKey192)); - Move(IvStr[1], AesIv[0], SizeOf(TCnAESBuffer)); - - EncryptAES192StreamCBC(Stream, Stream.Size, AESKey192, AesIv, ES); - Result := True; - end; - ckeAES256: - begin - Move(Keys[0], AESKey256[0], SizeOf(TCnAESKey256)); - Move(IvStr[1], AesIv[0], SizeOf(TCnAESBuffer)); - - EncryptAES256StreamCBC(Stream, Stream.Size, AESKey256, AesIv, ES); - Result := True; - end; - end; - finally - if ES.Size > 0 then - begin - // ES д Stream - Stream.Size := 0; - Stream.Position := 0; - ES.SaveToStream(Stream); - Stream.Position := 0; - end; - ES.Free; - end; -end; - -// ü㷨㡢ʼ⿪ Base64 Sд Stream -function DecryptPemString(const S, M1, M2, HexIv, Password: string; Stream: TMemoryStream; - KeyHash: TCnKeyHashMethod): Boolean; -var - DS: TMemoryStream; - Keys: array[0..31] of Byte; //  Key Ҳֻ 32 ֽ - AESKey128: TCnAESKey128; - AESKey192: TCnAESKey192; - AESKey256: TCnAESKey256; - IvStr: AnsiString; - AesIv: TCnAESBuffer; - DesKey: TCnDESKey; - Des3Key: TCn3DESKey; - DesIv: TCnDESIv; -begin - Result := False; - DS := nil; - - if (M1 = '') or (M2 = '') or (HexIv = '') or (Password = '') then - Exit; - - try - DS := TMemoryStream.Create; - if ECN_BASE64_OK <> Base64Decode(AnsiString(S), DS, False) then - Exit; - - DS.Position := 0; - SetLength(IvStr, HexToData(HexIv)); - if Length(IvStr) > 0 then - HexToData(HexIv, @IvStr[1]); - - // Salt Լ Hash 㷨ӽܵ Key - FillChar(Keys[0], SizeOf(Keys), 0); - if KeyHash = ckhMd5 then - begin - if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys)) then - Exit; - end - else if KeyHash = ckhSha256 then - begin - if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys), ckdSha256) then - Exit; - end - else - Exit; - - // DS ģҪ⵽ Stream - if (M1 = ENC_TYPE_AES256) and (M2 = ENC_BLOCK_CBC) then - begin - // ⿪ AES-256-CBC ܵ - Move(Keys[0], AESKey256[0], SizeOf(TCnAESKey256)); - Move(IvStr[1], AesIv[0], Min(SizeOf(TCnAESBuffer), Length(IvStr))); - - DecryptAES256StreamCBC(DS, DS.Size, AESKey256, AesIv, Stream); - RemovePKCS7Padding(Stream); - Result := True; - end - else if (M1 = ENC_TYPE_AES192) and (M2 = ENC_BLOCK_CBC) then - begin - // ⿪ AES-192-CBC ܵ - Move(Keys[0], AESKey192[0], SizeOf(TCnAESKey192)); - Move(IvStr[1], AesIv[0], Min(SizeOf(TCnAESBuffer), Length(IvStr))); - - DecryptAES192StreamCBC(DS, DS.Size, AESKey192, AesIv, Stream); - RemovePKCS7Padding(Stream); - Result := True; - end - else if (M1 = ENC_TYPE_AES128) and (M2 = ENC_BLOCK_CBC) then - begin - // ⿪ AES-128-CBC ܵģ D5 òƿ Bug ³ AV - Move(Keys[0], AESKey128[0], SizeOf(TCnAESKey128)); - Move(IvStr[1], AesIv[0], Min(SizeOf(TCnAESBuffer), Length(IvStr))); - - DecryptAES128StreamCBC(DS, DS.Size, AESKey128, AesIv, Stream); - RemovePKCS7Padding(Stream); - Result := True; - end - else if (M1 = ENC_TYPE_DES) and (M2 = ENC_BLOCK_CBC) then - begin - // ⿪ DES-CBC ܵ - Move(Keys[0], DesKey[0], SizeOf(TCnDESKey)); - Move(IvStr[1], DesIv[0], Min(SizeOf(TCnDESIv), Length(IvStr))); - - DESDecryptStreamCBC(DS, DS.Size, DesKey, DesIv, Stream); - RemovePKCS7Padding(Stream); - Result := True; - end - else if (M1 = ENC_TYPE_3DES) and (M2 = ENC_BLOCK_CBC) then - begin - // ⿪ 3DES-CBC ܵ - Move(Keys[0], Des3Key[0], SizeOf(TCn3DESKey)); - Move(IvStr[1], DesIv[0], Min(SizeOf(TCn3DESIv), Length(IvStr))); - - TripleDESDecryptStreamCBC(DS, DS.Size, Des3Key, DesIv, Stream); - RemovePKCS7Padding(Stream); - Result := True; - end; - finally - DS.Free; - end; -end; - -function LoadPemStreamToMemory(Stream: TStream; const ExpectHead, ExpectTail: string; - MemoryStream: TMemoryStream; const Password: string; KeyHashMethod: TCnKeyHashMethod): Boolean; -var - I, J, HeadIndex, TailIndex: Integer; - S, L1, L2, M1, M2, M3: string; - Sl: TStringList; -begin - Result := False; - - if (Stream <> nil) and (Stream.Size > 0) and (ExpectHead <> '') and (ExpectTail <> '') then - begin - Sl := TStringList.Create; - try - Sl.LoadFromStream(Stream); - if Sl.Count > 2 then - begin - HeadIndex := -1; - for I := 0 to Sl.Count - 1 do - begin - if Trim(Sl[I]) = ExpectHead then - begin - HeadIndex := I; - Break; - end; - end; - - if HeadIndex < 0 then - Exit; - - if HeadIndex > 0 then - for I := 0 to HeadIndex - 1 do - Sl.Delete(0); - - // ҵͷˣβ - - TailIndex := -1; - for I := 0 to Sl.Count - 1 do - begin - if Trim(Sl[I]) = ExpectTail then - begin - TailIndex := I; - Break; - end; - end; - - if TailIndex > 0 then // ҵβͣɾβͺĶ - begin - if TailIndex < Sl.Count - 1 then - for I := Sl.Count - 1 downto TailIndex + 1 do - Sl.Delete(Sl.Count - 1); - end - else - Exit; - - if Sl.Count < 2 then // ûݣ˳ - Exit; - - // ͷβ֤ͨǰжǷ - L1 := Sl[1]; - if Pos(ENC_HEAD_PROCTYPE, L1) = 1 then // Ǽܵ - begin - Delete(L1, 1, Length(ENC_HEAD_PROCTYPE)); - I := Pos(',', L1); - if I <= 1 then - Exit; - - if Trim(Copy(L1, 1, I - 1)) <> ENC_HEAD_PROCTYPE_NUM then - Exit; - - if Trim(Copy(L1, I + 1, MaxInt)) <> ENC_HEAD_ENCRYPTED then - Exit; - - // ProcType: 4,ENCRYPTED жͨ - - L2 := Sl[2]; - if Pos(ENC_HEAD_DEK, L2) <> 1 then - Exit; - - Delete(L2, 1, Length(ENC_HEAD_DEK)); - I := Pos(',', L2); - if I <= 1 then - Exit; - - M1 := Trim(Copy(L2, 1, I - 1)); // õ AES256-CBC - M3 := UpperCase(Trim(Copy(L2, I + 1, MaxInt))); // õʱʹõijʼ - I := Pos('-', M1); - if I <= 1 then - Exit; - J := Pos('-', Copy(M1, I + 1, MaxInt)); - if J > 0 then - I := I + J; // AES-256-CBC - - M2 := UpperCase(Trim(Copy(M1, I + 1, MaxInt))); // õģʽ ECB CBC - M1 := UpperCase(Trim(Copy(M1, 1, I - 1))); // õ㷨 DES AES - - // ͷβȫɾ - Sl.Delete(Sl.Count - 1); - Sl.Delete(0); - Sl.Delete(0); - Sl.Delete(0); - - S := ''; - for I := 0 to Sl.Count - 1 do - S := S + Sl[I]; - - S := Trim(S); - - Result := DecryptPemString(S, M1, M2, M3, Password, MemoryStream, KeyHashMethod); - end - else // δܵģƴճ Base64 - begin - Sl.Delete(Sl.Count - 1); - Sl.Delete(0); - S := ''; - for I := 0 to Sl.Count - 1 do - S := S + Sl[I]; - - S := Trim(S); - - // To De Base64 S - MemoryStream.Clear; -{$IFDEF UNICODE} - Result := (ECN_BASE64_OK = Base64Decode(AnsiString(S), MemoryStream, False)); -{$ELSE} - Result := (ECN_BASE64_OK = Base64Decode(S, MemoryStream, False)); -{$ENDIF} - end; - end; - finally - Sl.Free; - end; - end; -end; - -function LoadPemFileToMemory(const FileName, ExpectHead, ExpectTail: string; - MemoryStream: TMemoryStream; const Password: string; KeyHashMethod: TCnKeyHashMethod): Boolean; -var - Stream: TStream; -begin - Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try - Result := LoadPemStreamToMemory(Stream, ExpectHead, ExpectTail, MemoryStream, Password, KeyHashMethod); - finally - Stream.Free; - end; -end; - -procedure SplitStringToList(const S: string; List: TStrings); -const - LINE_WIDTH = 64; -var - C, R: string; -begin - if List = nil then - Exit; - - List.Clear; - if S <> '' then - begin - R := S; - while R <> '' do - begin - C := Copy(R, 1, LINE_WIDTH); - Delete(R, 1, LINE_WIDTH); - List.Add(C); - end; - end; -end; - -function SaveMemoryToPemFile(const FileName, Head, Tail: string; - MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod; - KeyHashMethod: TCnKeyHashMethod; const Password: string; Append: Boolean): Boolean; -var - S, EH: string; - List, Sl: TStringList; -begin - Result := False; - if (MemoryStream <> nil) and (MemoryStream.Size <> 0) then - begin - MemoryStream.Position := 0; - - if (KeyEncryptMethod <> ckeNone) and (Password <> '') then - begin - // MemoryStream - AddPKCS7Padding(MemoryStream, ENC_TYPE_BLOCK_SIZE[KeyEncryptMethod]); - - // ټ - if not EncryptPemStream(KeyHashMethod, KeyEncryptMethod, MemoryStream, Password, EH) then - Exit; - end; - - if ECN_BASE64_OK = Base64Encode(MemoryStream, S) then - begin - List := TStringList.Create; - try - SplitStringToList(S, List); - - List.Insert(0, Head); // ͨͷ - if EH <> '' then // ͷ - List.Insert(1, EH); - List.Add(Tail); // ͨβ - - if Append and FileExists(FileName) then - begin - Sl := TStringList.Create; - try - Sl.LoadFromFile(FileName); - Sl.AddStrings(List); - Sl.SaveToFile(FileName); - finally - Sl.Free; - end; - end - else - List.SaveToFile(FileName); - - Result := True; - finally - List.Free; - end; - end; - end; -end; - -function SaveMemoryToPemStream(Stream: TStream; const Head, Tail: string; - MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod; - KeyHashMethod: TCnKeyHashMethod; const Password: string; Append: Boolean): Boolean; -var - S, EH: string; - List: TStringList; -begin - Result := False; - if (MemoryStream <> nil) and (MemoryStream.Size <> 0) then - begin - MemoryStream.Position := 0; - - if (KeyEncryptMethod <> ckeNone) and (Password <> '') then - begin - // MemoryStream - AddPKCS7Padding(MemoryStream, ENC_TYPE_BLOCK_SIZE[KeyEncryptMethod]); - - // ټ - if not EncryptPemStream(KeyHashMethod, KeyEncryptMethod, MemoryStream, Password, EH) then - Exit; - end; - - if ECN_BASE64_OK = Base64Encode(MemoryStream, S) then - begin - List := TStringList.Create; - try - SplitStringToList(S, List); - - List.Insert(0, Head); // ͨͷ - if EH <> '' then // ͷ - List.Insert(1, EH); - List.Add(Tail); // ͨβ - - if not Append then - Stream.Size := 0; - - List.SaveToStream(Stream); - - Result := True; - finally - List.Free; - end; - end; - end; -end; - -end. +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnPemUtils; +{* |
+================================================================================
+* ƣ
+* ԪƣPEM ʽ뵥Ԫ
+* ԪߣCnPack 
+*     עԪʵ PEM ʽĶȡ뱣棬ӽܻơ
+*           Ҳʵ PKCS1/PKCS5/PKCS7/ISO10126 ȶ봦ơ
+*           ע֧ PKCS12 淶֤鼰Կװʽ
+* ƽ̨WinXP + Delphi 5.0
+* ݲԣδ
+*   õԪ豾ػ
+* ޸ļ¼2024.05.27 V1.6
+*                ISO10126 Ĵ
+*           2023.12.14 V1.5
+*                SaveMemoryToPemStream δ
+*           2022.03.09 V1.4
+*                PKCS5 Ĵ
+*           2021.05.14 V1.3
+*               ĸ PKCS7 Ĵ
+*           2020.03.27 V1.2
+*               ģ Openssl ʵ PEM ļд룬ֲֻּ֧㷨
+*               Ŀǰд des/3des/aes128/192/256 PKCS7 룬 Openssl 1.0.2g
+*           2020.03.23 V1.1
+*               ģ Openssl ʵ PEM ļܶȡֲֻּ֧㷨
+*               Ŀǰȡ des/3des/aes128/192/256 PKCS7 룬 Openssl 1.0.2g
+*           2020.03.18 V1.0
+*               Ԫ CnRSA ж
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, CnNative, CnRandom, CnKDF, CnBase64, CnAES, CnDES; + +const + CN_PKCS1_BLOCK_TYPE_PRIVATE_00 = 00; + {* PKCS1 ʱĿֵֶһĬӦ RSA ˽Կܳ} + + CN_PKCS1_BLOCK_TYPE_PRIVATE_FF = 01; + {* PKCS1 ʱĿֵֶĬӦ RSA ˽Կǩ} + + CN_PKCS1_BLOCK_TYPE_PUBLIC_RANDOM = 02; + {* PKCS1 ʱĿֵֶĬӦ RSA ĹԿܳ} + +type + TCnKeyHashMethod = (ckhMd5, ckhSha256); + {* PEM ʽֵ֧Ӵ} + + TCnKeyEncryptMethod = (ckeNone, ckeDES, cke3DES, ckeAES128, ckeAES192, ckeAES256); + {* PEM ʽֵ֧ļ} + +// ======================= PEM ļдּ֧ӽ ======================== + +function LoadPemFileToMemory(const FileName: string; const ExpectHead: string; + const ExpectTail: string; MemoryStream: TMemoryStream; const Password: string = ''; + KeyHashMethod: TCnKeyHashMethod = ckhMd5): Boolean; +{* PEM ʽļָ֤ͷβʵݲܽ Base64 롣 + + + const FileName: string - ļ + const ExpectHead: string - ͷ + const ExpectTail: string - β + MemoryStream: TMemoryStream - ڴ + const Password: string - ļܣڴṩ + KeyHashMethod: TCnKeyHashMethod - ļʹõӴ + + ֵBoolean - ضǷɹ +} + +function LoadPemStreamToMemory(Stream: TStream; const ExpectHead: string; + const ExpectTail: string; MemoryStream: TMemoryStream; const Password: string = ''; + KeyHashMethod: TCnKeyHashMethod = ckhMd5): Boolean; +{* PEM ʽļָ֤ͷβʵݲܽ Base64 롣 + + + Stream: TStream - + const ExpectHead: string - ͷ + const ExpectTail: string - β + MemoryStream: TMemoryStream - ڴ + const Password: string - ܣڴṩ + KeyHashMethod: TCnKeyHashMethod - ʹõӴ + + ֵBoolean - ضǷɹ +} + +function SaveMemoryToPemFile(const FileName: string; const Head: string; const Tail: string; + MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod = ckeNone; + KeyHashMethod: TCnKeyHashMethod = ckhMd5; const Password: string = ''; Append: Boolean = False): Boolean; +{* Stream ݽ Base64 ܷвļͷβдļAppend Ϊ True ʱʾ׷ӡ + + + const FileName: string - дļ + const Head: string - дͷ + const Tail: string - дβ + MemoryStream: TMemoryStream - д + KeyEncryptMethod: TCnKeyEncryptMethod - üͣĬϲ + KeyHashMethod: TCnKeyHashMethod - Ӵ + const Password: string - 룬򴫿 + Append: Boolean - Ƿ׷ӵķʽд + + ֵBoolean - Ƿдɹ +} + +function SaveMemoryToPemStream(Stream: TStream; const Head: string; const Tail: string; + MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod = ckeNone; + KeyHashMethod: TCnKeyHashMethod = ckhMd5; const Password: string = ''; Append: Boolean = False): Boolean; +{* Stream ݽ Base64 ܷвͷβдAppend Ϊ True ʱʾ׷ӡ + + + Stream: TStream - д + const Head: string - дͷ + const Tail: string - дβ + MemoryStream: TMemoryStream - д + KeyEncryptMethod: TCnKeyEncryptMethod - üͣĬϲ + KeyHashMethod: TCnKeyHashMethod - ӴͣĬϲӴ + const Password: string - 룬򴫿 + Append: Boolean - Ƿ׷ӵķʽд + + ֵBoolean - Ƿдɹ +} + +// ===================== PKCS1 / PKCS7 Padding 봦 ==================== + +function AddPKCS1Padding(PaddingType: Integer; BlockSize: Integer; Data: Pointer; + DataByteLen: Integer; OutStream: TStream): Boolean; +{* ݿ鲹д Stream Уسɹڲô롣 + PaddingType ȡ 012BlockLen ֽ 128 ȡʽ + EB = 00 || BT || PS || 00 || D + 00 ǰ涨ֽڣBT 1 ֽڵ PaddingType0 1 2 ֱ 00 FF + PS Ķֽݣ 00 ǹ涨Ľβֽڡ + + + PaddingType: Integer - ͣȡ 0 1 2 + BlockSize: Integer - ֽڳ + Data: Pointer - ݿĵַ + DataByteLen: Integer - ݿֽڳ + OutStream: TStream - + + ֵBoolean - ضǷӳɹ +} + +function RemovePKCS1Padding(InData: Pointer; InDataByteLen: Integer; OutBuf: Pointer; + out OutByteLen: Integer): Boolean; +{* ȥݿ PKCS1 PaddingسɹOutBuf ָĿóб֤ + ɹOutLen ԭݳȡ + + + InData: Pointer - ȥݿĵַ + InDataByteLen: Integer - ȥݿֽڳ + OutBuf: Pointer - ȥݵ䳤ȱ㹻 + out OutByteLen: Integer - ȥݳ + + ֵBoolean - ضǷȥɹ +} + +function GetPKCS7PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; +{* ԭʼ鳤ȼ PKCS7 ijȡ + + + OrignalByteLen: Integer - ԭʼֽڳ + BlockSize: Integer - PKCS7 ֽڳ + + ֵInteger - PKCS7 ֽڳ +} + +procedure AddPKCS7Padding(Stream: TMemoryStream; BlockSize: Integer); +{* ĩβ PKCS7 涨䡰ݡ + + + Stream: TMemoryStream - ڴݣݽ׷дβ + BlockSize: Integer - PKCS7 ֽڳ + + ֵޣ +} + +procedure RemovePKCS7Padding(Stream: TMemoryStream); +{* ȥ PKCS7 涨ĩβ䡰ݡ + + + Stream: TMemoryStream - ȥڴ + + ֵޣ} + +function StrAddPKCS7Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; +{* ַĩβ PKCS7 涨䡰ݡ + + + const Str: AnsiString - ַ + BlockSize: Integer - PKCS7 ֽڳ + + ֵAnsiString - ضַ +} + +function StrRemovePKCS7Padding(const Str: AnsiString): AnsiString; +{* ȥ PKCS7 涨ַĩβ䡰ݡ + + + const Str: AnsiString - ȥַ + + ֵAnsiString - ȥַ +} + +procedure BytesAddPKCS7Padding(var Data: TBytes; BlockSize: Integer); +{* ֽĩβ PKCS7 涨䡰ݡ + + + var Data: TBytes - ֽ飬ݽ׷β + BlockSize: Integer - PKCS7 ֽڳ + + ֵޣ +} + +procedure BytesRemovePKCS7Padding(var Data: TBytes); +{* ȥ PKCS7 涨ֽĩβ䡰ݡ + + + var Data: TBytes - ȥֽ + + ֵޣ +} + +procedure AddPKCS5Padding(Stream: TMemoryStream); +{* ĩβ PKCS5 涨䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + Stream: TMemoryStream - ڴݽ׷β + + ֵޣ +} + +procedure RemovePKCS5Padding(Stream: TMemoryStream); +{* ȥ PKCS7 涨ĩβ䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + Stream: TMemoryStream - ȥڴ + + ֵޣ +} + +function StrAddPKCS5Padding(const Str: AnsiString): AnsiString; +{* ַĩβ PKCS5 涨䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + const Str: AnsiString - ַ + + ֵAnsiString - ضַ +} + +function StrRemovePKCS5Padding(const Str: AnsiString): AnsiString; +{* ȥ PKCS5 涨ַĩβ䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + const Str: AnsiString - ȥַ + + ֵAnsiString - ȥַ +} + +procedure BytesAddPKCS5Padding(var Data: TBytes); +{* ֽĩβ PKCS5 涨䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + var Data: TBytes - ֽ飬ݽ׷β + + ֵޣ +} + +procedure BytesRemovePKCS5Padding(var Data: TBytes); +{* ȥ PKCS7 涨ֽĩβ䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + var Data: TBytes - ȥֽ + + ֵޣ +} + +function GetISO10126PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; +{* ԭʼ鳤ȼ ISO10126Padding ijȡ + + + OrignalByteLen: Integer - ԭʼֽڳ + BlockSize: Integer - ISO10126 ֽڳ + + ֵInteger - PKCS7 ֽڳ +} + +procedure AddISO10126Padding(Stream: TMemoryStream; BlockSize: Integer); +{* ĩβ ISO10126Padding 涨䡰ͼݡ + + + Stream: TMemoryStream - ڴݽ׷β + BlockSize: Integer - ISO10126 ֽڳ + + ֵޣ +} + +procedure RemoveISO10126Padding(Stream: TMemoryStream); +{* ȥ ISO10126Padding 涨ĩβ䡰ͼݡ + + + Stream: TMemoryStream - ȥڴ + + ֵޣ +} + +function StrAddISO10126Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; +{* ַĩβ ISO10126Padding 涨䡰ͼݡ + + + const Str: AnsiString - ַ + BlockSize: Integer - ISO10126 ֽڴС + + ֵAnsiString - ضַ +} + +function StrRemoveISO10126Padding(const Str: AnsiString): AnsiString; +{* ȥ ISO10126Padding 涨ַĩβ䡰ͼݡ + + + const Str: AnsiString - ȥַ + + ֵAnsiString - ȥַ +} + +procedure BytesAddISO10126Padding(var Data: TBytes; BlockSize: Integer); +{* ֽĩβ ISO10126Padding 涨䡰ͼݡ + + + var Data: TBytes - ֽ飬ݽ׷β + BlockSize: Integer - ISO10126 ֽڳ + + ֵޣ +} + +procedure BytesRemoveISO10126Padding(var Data: TBytes); +{* ȥ ISO10126Padding 涨ֽĩβ䡰ͼݡ + + + var Data: TBytes - ȥֽ + + ֵޣ +} + +implementation + +const + PKCS1_PADDING_SIZE = 11; // һǰ 00һֽڡ 8 ֽ䣬һ 00 β + PKCS5_BLOCK_SIZE = 8; + + ENC_HEAD_PROCTYPE = 'Proc-Type:'; + ENC_HEAD_PROCTYPE_NUM = '4'; + ENC_HEAD_ENCRYPTED = 'ENCRYPTED'; + ENC_HEAD_DEK = 'DEK-Info:'; + + ENC_TYPE_AES128 = 'AES-128'; + ENC_TYPE_AES192 = 'AES-192'; + ENC_TYPE_AES256 = 'AES-256'; + ENC_TYPE_DES = 'DES'; + ENC_TYPE_3DES = 'DES-EDE3'; + + ENC_BLOCK_CBC = 'CBC'; + + ENC_TYPE_STRS: array[TCnKeyEncryptMethod] of string = + ('', ENC_TYPE_DES, ENC_TYPE_3DES, ENC_TYPE_AES128, ENC_TYPE_AES192, ENC_TYPE_AES256); + + ENC_TYPE_BLOCK_SIZE: array[TCnKeyEncryptMethod] of Byte = + (0, 8, 8, 16, 16, 16); + +function Min(A, B: Integer): Integer; +begin + if A < B then + Result := A + else + Result := B; +end; + +function AddPKCS1Padding(PaddingType, BlockSize: Integer; Data: Pointer; + DataByteLen: Integer; OutStream: TStream): Boolean; +var + I: Integer; + B, F: Byte; +begin + Result := False; + if (Data = nil) or (DataByteLen <= 0) then + Exit; + + // + if DataByteLen > BlockSize - PKCS1_PADDING_SIZE then + Exit; + + B := 0; + OutStream.Write(B, 1); // дǰֽ 00 + B := PaddingType; + F := BlockSize - DataByteLen - 3; // 3 ʾһǰ 00һֽڡһ 00 β + + OutStream.Write(B, 1); + case PaddingType of + CN_PKCS1_BLOCK_TYPE_PRIVATE_00: + begin + B := 0; + for I := 1 to F do + OutStream.Write(B, 1); + end; + CN_PKCS1_BLOCK_TYPE_PRIVATE_FF: + begin + B := $FF; + for I := 1 to F do + OutStream.Write(B, 1); + end; + CN_PKCS1_BLOCK_TYPE_PUBLIC_RANDOM: + begin + Randomize; + for I := 1 to F do + begin + B := Trunc(Random(255)); + if B = 0 then + Inc(B); + OutStream.Write(B, 1); + end; + end; + else + Exit; + end; + + B := 0; + OutStream.Write(B, 1); + OutStream.Write(Data^, DataByteLen); + Result := True; +end; + +function RemovePKCS1Padding(InData: Pointer; InDataByteLen: Integer; OutBuf: Pointer; + out OutByteLen: Integer): Boolean; +var + P: PAnsiChar; + I, J, Start: Integer; +begin + Result := False; + OutByteLen := 0; + I := 0; + + P := PAnsiChar(InData); + while P[I] = #0 do // ַһ #0Ѿȥ + Inc(I); + + if I >= InDataByteLen then + Exit; + + Start := 0; + case Ord(P[I]) of + CN_PKCS1_BLOCK_TYPE_PRIVATE_00: + begin + // P[I + 1] ʼѰҷ 00 + J := I + 1; + while J < InDataByteLen do + begin + if P[J] <> #0 then + begin + Start := J; + Break; + end; + Inc(J); + end; + end; + CN_PKCS1_BLOCK_TYPE_PRIVATE_FF, + CN_PKCS1_BLOCK_TYPE_PUBLIC_RANDOM: + begin + // P[I + 1] ʼѰҵһ 00 ı + J := I + 1; + while J < InDataByteLen do + begin + if P[J] = #0 then + begin + Start := J; + Break; + end; + Inc(J); + end; + + if Start <> 0 then + Inc(Start); + end; + end; + + if Start > 0 then + begin + Move(P[Start], OutBuf^, InDataByteLen - Start); + OutByteLen := InDataByteLen - Start; + Result := True; + end; +end; + +function GetPKCS7PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; +var + R: Byte; +begin + R := OrignalByteLen mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + Result := OrignalByteLen + R; +end; + +procedure AddPKCS7Padding(Stream: TMemoryStream; BlockSize: Integer); +var + R: Byte; + Buf: array[0..255] of Byte; +begin + R := Stream.Size mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + FillChar(Buf[0], R, R); + Stream.Position := Stream.Size; + Stream.Write(Buf[0], R); +end; + +procedure RemovePKCS7Padding(Stream: TMemoryStream); +var + L: Byte; + Len: Cardinal; + Mem: Pointer; +begin + // ȥ Stream ĩβ 9 9 Padding + if Stream.Size > 1 then + begin + Stream.Position := Stream.Size - 1; + Stream.Read(L, 1); + + if Stream.Size - L < 0 then // ߴ粻ף + Exit; + + Len := Stream.Size - L; + Mem := GetMemory(Len); + if Mem <> nil then + begin + Move(Stream.Memory^, Mem^, Len); + Stream.Clear; + Stream.Write(Mem^, Len); + FreeMemory(Mem); + end; + end; +end; + +function StrAddPKCS7Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; +var + I, L: Integer; + R: Byte; +begin + L := Length(Str); + R := L mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + SetLength(Result, L + R); + if L > 0 then + Move(Str[1], Result[1], L); + + for I := 1 to R do + Result[L + I] := AnsiChar(R); +end; + +function StrRemovePKCS7Padding(const Str: AnsiString): AnsiString; +var + L: Integer; + V: Byte; +begin + Result := Str; + if Result = '' then + Exit; + + L := Length(Result); + V := Ord(Result[L]); // ĩǼʾ˼ + + if V <= L then + Delete(Result, L - V + 1, V); +end; + +procedure AddPKCS5Padding(Stream: TMemoryStream); +begin + AddPKCS7Padding(Stream, PKCS5_BLOCK_SIZE); +end; + +procedure RemovePKCS5Padding(Stream: TMemoryStream); +begin + RemovePKCS7Padding(Stream); +end; + +function StrAddPKCS5Padding(const Str: AnsiString): AnsiString; +begin + Result := StrAddPKCS7Padding(Str, PKCS5_BLOCK_SIZE); +end; + +function StrRemovePKCS5Padding(const Str: AnsiString): AnsiString; +begin + Result := StrRemovePKCS7Padding(Str); +end; + +procedure BytesAddPKCS7Padding(var Data: TBytes; BlockSize: Integer); +var + R: Byte; + L, I: Integer; +begin + L := Length(Data); + R := L mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + SetLength(Data, L + R); + for I := 0 to R - 1 do + Data[L + I] := R; +end; + +procedure BytesRemovePKCS7Padding(var Data: TBytes); +var + L: Integer; + V: Byte; +begin + L := Length(Data); + if L = 0 then + Exit; + + V := Ord(Data[L - 1]); // ĩǼʾ˼ֽ + + if V <= L then + SetLength(Data, L - V); +end; + +procedure BytesAddPKCS5Padding(var Data: TBytes); +begin + BytesAddPKCS7Padding(Data, PKCS5_BLOCK_SIZE); +end; + +procedure BytesRemovePKCS5Padding(var Data: TBytes); +begin + BytesRemovePKCS7Padding(Data); +end; + +function GetISO10126PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; +begin + Result := GetPKCS7PaddingByteLength(OrignalByteLen, BlockSize); // Ϊֱͬӵ +end; + +procedure AddISO10126Padding(Stream: TMemoryStream; BlockSize: Integer); +var + R: Byte; + Buf: array[0..255] of Byte; +begin + R := Stream.Size mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + FillChar(Buf[0], R, 0); + Buf[R - 1] := R; + Stream.Position := Stream.Size; + Stream.Write(Buf[0], R); +end; + +procedure RemoveISO10126Padding(Stream: TMemoryStream); +begin + RemovePKCS7Padding(Stream); // Ϊֱͬӵ +end; + +function StrAddISO10126Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; +var + I, L: Integer; + R: Byte; +begin + L := Length(Str); + R := L mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + SetLength(Result, L + R); + if L > 0 then + Move(Str[1], Result[1], L); + + if R > 1 then + begin + for I := 1 to R - 1 do + Result[L + I] := #0; + end; + Result[L + R] := AnsiChar(R); +end; + +function StrRemoveISO10126Padding(const Str: AnsiString): AnsiString; +begin + Result := StrRemovePKCS7Padding(Str); // Ϊֱͬӵ +end; + +procedure BytesAddISO10126Padding(var Data: TBytes; BlockSize: Integer); +var + R: Byte; + L, I: Integer; +begin + L := Length(Data); + R := L mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + SetLength(Data, L + R); + if R > 1 then + begin + for I := 0 to R - 2 do + Data[L + I] := 0; + end; + Data[L - 1 + R] := R; +end; + +procedure BytesRemoveISO10126Padding(var Data: TBytes); +begin + BytesRemovePKCS7Padding(Data); // Ϊֱͬӵ +end; + +function EncryptPemStream(KeyHash: TCnKeyHashMethod; KeyEncrypt: TCnKeyEncryptMethod; + Stream: TStream; const Password: string; out EncryptedHead: string): Boolean; +const + CRLF = #13#10; +var + ES: TMemoryStream; + Keys: array[0..31] of Byte; //  Key Ҳֻ 32 ֽ + IvStr: AnsiString; + HexIv: string; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AesIv: TCnAESBuffer; + DesKey: TCnDESKey; + Des3Key: TCn3DESKey; + DesIv: TCnDESIv; +begin + Result := False; + + // + if (KeyEncrypt = ckeNone) or (Password = '') then + Exit; + + // Iv + SetLength(IvStr, ENC_TYPE_BLOCK_SIZE[KeyEncrypt]); + CnRandomFillBytes(@(IvStr[1]), ENC_TYPE_BLOCK_SIZE[KeyEncrypt]); + HexIv := DataToHex(@(IvStr[1]), ENC_TYPE_BLOCK_SIZE[KeyEncrypt], True); // Ҫд + + EncryptedHead := ENC_HEAD_PROCTYPE + ' ' + ENC_HEAD_PROCTYPE_NUM + ',' + ENC_HEAD_ENCRYPTED + CRLF; + EncryptedHead := EncryptedHead + ENC_HEAD_DEK + ' ' + ENC_TYPE_STRS[KeyEncrypt] + + '-' + ENC_BLOCK_CBC + ',' + HexIv + CRLF; + + ES := TMemoryStream.Create; + Stream.Position := 0; + + try + if KeyHash = ckhMd5 then + begin + if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys)) then + Exit; + end + else if KeyHash = ckhSha256 then + begin + if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys), ckdSha256) then + Exit; + end + else + Exit; + + case KeyEncrypt of + ckeDES: + begin + Move(Keys[0], DesKey[0], SizeOf(TCnDESKey)); + Move(IvStr[1], DesIv[0], SizeOf(TCnDESIv)); + + DESEncryptStreamCBC(Stream, Stream.Size, DesKey, DesIv, ES); + Result := True; + end; + cke3DES: + begin + Move(Keys[0], Des3Key[0], SizeOf(TCn3DESKey)); + Move(IvStr[1], DesIv[0], SizeOf(TCn3DESIv)); + + TripleDESEncryptStreamCBC(Stream, Stream.Size, Des3Key, DesIv, ES); + Result := True; + end; + ckeAES128: + begin + Move(Keys[0], AESKey128[0], SizeOf(TCnAESKey128)); + Move(IvStr[1], AesIv[0], SizeOf(TCnAESBuffer)); + + EncryptAES128StreamCBC(Stream, Stream.Size, AESKey128, AesIv, ES); + Result := True; + end; + ckeAES192: + begin + Move(Keys[0], AESKey192[0], SizeOf(TCnAESKey192)); + Move(IvStr[1], AesIv[0], SizeOf(TCnAESBuffer)); + + EncryptAES192StreamCBC(Stream, Stream.Size, AESKey192, AesIv, ES); + Result := True; + end; + ckeAES256: + begin + Move(Keys[0], AESKey256[0], SizeOf(TCnAESKey256)); + Move(IvStr[1], AesIv[0], SizeOf(TCnAESBuffer)); + + EncryptAES256StreamCBC(Stream, Stream.Size, AESKey256, AesIv, ES); + Result := True; + end; + end; + finally + if ES.Size > 0 then + begin + // ES д Stream + Stream.Size := 0; + Stream.Position := 0; + ES.SaveToStream(Stream); + Stream.Position := 0; + end; + ES.Free; + end; +end; + +// ü㷨㡢ʼ⿪ Base64 Sд Stream +function DecryptPemString(const S, M1, M2, HexIv, Password: string; Stream: TMemoryStream; + KeyHash: TCnKeyHashMethod): Boolean; +var + DS: TMemoryStream; + Keys: array[0..31] of Byte; //  Key Ҳֻ 32 ֽ + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + IvStr: AnsiString; + AesIv: TCnAESBuffer; + DesKey: TCnDESKey; + Des3Key: TCn3DESKey; + DesIv: TCnDESIv; +begin + Result := False; + DS := nil; + + if (M1 = '') or (M2 = '') or (HexIv = '') or (Password = '') then + Exit; + + try + DS := TMemoryStream.Create; + if ECN_BASE64_OK <> Base64Decode(AnsiString(S), DS, False) then + Exit; + + DS.Position := 0; + SetLength(IvStr, HexToData(HexIv)); + if Length(IvStr) > 0 then + HexToData(HexIv, @IvStr[1]); + + // Salt Լ Hash 㷨ӽܵ Key + FillChar(Keys[0], SizeOf(Keys), 0); + if KeyHash = ckhMd5 then + begin + if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys)) then + Exit; + end + else if KeyHash = ckhSha256 then + begin + if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys), ckdSha256) then + Exit; + end + else + Exit; + + // DS ģҪ⵽ Stream + if (M1 = ENC_TYPE_AES256) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ AES-256-CBC ܵ + Move(Keys[0], AESKey256[0], SizeOf(TCnAESKey256)); + Move(IvStr[1], AesIv[0], Min(SizeOf(TCnAESBuffer), Length(IvStr))); + + DecryptAES256StreamCBC(DS, DS.Size, AESKey256, AesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end + else if (M1 = ENC_TYPE_AES192) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ AES-192-CBC ܵ + Move(Keys[0], AESKey192[0], SizeOf(TCnAESKey192)); + Move(IvStr[1], AesIv[0], Min(SizeOf(TCnAESBuffer), Length(IvStr))); + + DecryptAES192StreamCBC(DS, DS.Size, AESKey192, AesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end + else if (M1 = ENC_TYPE_AES128) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ AES-128-CBC ܵģ D5 òƿ Bug ³ AV + Move(Keys[0], AESKey128[0], SizeOf(TCnAESKey128)); + Move(IvStr[1], AesIv[0], Min(SizeOf(TCnAESBuffer), Length(IvStr))); + + DecryptAES128StreamCBC(DS, DS.Size, AESKey128, AesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end + else if (M1 = ENC_TYPE_DES) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ DES-CBC ܵ + Move(Keys[0], DesKey[0], SizeOf(TCnDESKey)); + Move(IvStr[1], DesIv[0], Min(SizeOf(TCnDESIv), Length(IvStr))); + + DESDecryptStreamCBC(DS, DS.Size, DesKey, DesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end + else if (M1 = ENC_TYPE_3DES) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ 3DES-CBC ܵ + Move(Keys[0], Des3Key[0], SizeOf(TCn3DESKey)); + Move(IvStr[1], DesIv[0], Min(SizeOf(TCn3DESIv), Length(IvStr))); + + TripleDESDecryptStreamCBC(DS, DS.Size, Des3Key, DesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end; + finally + DS.Free; + end; +end; + +function LoadPemStreamToMemory(Stream: TStream; const ExpectHead, ExpectTail: string; + MemoryStream: TMemoryStream; const Password: string; KeyHashMethod: TCnKeyHashMethod): Boolean; +var + I, J, HeadIndex, TailIndex: Integer; + S, L1, L2, M1, M2, M3: string; + Sl: TStringList; +begin + Result := False; + + if (Stream <> nil) and (Stream.Size > 0) and (ExpectHead <> '') and (ExpectTail <> '') then + begin + Sl := TStringList.Create; + try + Sl.LoadFromStream(Stream); + if Sl.Count > 2 then + begin + HeadIndex := -1; + for I := 0 to Sl.Count - 1 do + begin + if Trim(Sl[I]) = ExpectHead then + begin + HeadIndex := I; + Break; + end; + end; + + if HeadIndex < 0 then + Exit; + + if HeadIndex > 0 then + for I := 0 to HeadIndex - 1 do + Sl.Delete(0); + + // ҵͷˣβ + + TailIndex := -1; + for I := 0 to Sl.Count - 1 do + begin + if Trim(Sl[I]) = ExpectTail then + begin + TailIndex := I; + Break; + end; + end; + + if TailIndex > 0 then // ҵβͣɾβͺĶ + begin + if TailIndex < Sl.Count - 1 then + for I := Sl.Count - 1 downto TailIndex + 1 do + Sl.Delete(Sl.Count - 1); + end + else + Exit; + + if Sl.Count < 2 then // ûݣ˳ + Exit; + + // ͷβ֤ͨǰжǷ + L1 := Sl[1]; + if Pos(ENC_HEAD_PROCTYPE, L1) = 1 then // Ǽܵ + begin + Delete(L1, 1, Length(ENC_HEAD_PROCTYPE)); + I := Pos(',', L1); + if I <= 1 then + Exit; + + if Trim(Copy(L1, 1, I - 1)) <> ENC_HEAD_PROCTYPE_NUM then + Exit; + + if Trim(Copy(L1, I + 1, MaxInt)) <> ENC_HEAD_ENCRYPTED then + Exit; + + // ProcType: 4,ENCRYPTED жͨ + + L2 := Sl[2]; + if Pos(ENC_HEAD_DEK, L2) <> 1 then + Exit; + + Delete(L2, 1, Length(ENC_HEAD_DEK)); + I := Pos(',', L2); + if I <= 1 then + Exit; + + M1 := Trim(Copy(L2, 1, I - 1)); // õ AES256-CBC + M3 := UpperCase(Trim(Copy(L2, I + 1, MaxInt))); // õʱʹõijʼ + I := Pos('-', M1); + if I <= 1 then + Exit; + J := Pos('-', Copy(M1, I + 1, MaxInt)); + if J > 0 then + I := I + J; // AES-256-CBC + + M2 := UpperCase(Trim(Copy(M1, I + 1, MaxInt))); // õģʽ ECB CBC + M1 := UpperCase(Trim(Copy(M1, 1, I - 1))); // õ㷨 DES AES + + // ͷβȫɾ + Sl.Delete(Sl.Count - 1); + Sl.Delete(0); + Sl.Delete(0); + Sl.Delete(0); + + S := ''; + for I := 0 to Sl.Count - 1 do + S := S + Sl[I]; + + S := Trim(S); + + Result := DecryptPemString(S, M1, M2, M3, Password, MemoryStream, KeyHashMethod); + end + else // δܵģƴճ Base64 + begin + Sl.Delete(Sl.Count - 1); + Sl.Delete(0); + S := ''; + for I := 0 to Sl.Count - 1 do + S := S + Sl[I]; + + S := Trim(S); + + // To De Base64 S + MemoryStream.Clear; +{$IFDEF UNICODE} + Result := (ECN_BASE64_OK = Base64Decode(AnsiString(S), MemoryStream, False)); +{$ELSE} + Result := (ECN_BASE64_OK = Base64Decode(S, MemoryStream, False)); +{$ENDIF} + end; + end; + finally + Sl.Free; + end; + end; +end; + +function LoadPemFileToMemory(const FileName, ExpectHead, ExpectTail: string; + MemoryStream: TMemoryStream; const Password: string; KeyHashMethod: TCnKeyHashMethod): Boolean; +var + Stream: TStream; +begin + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + Result := LoadPemStreamToMemory(Stream, ExpectHead, ExpectTail, MemoryStream, Password, KeyHashMethod); + finally + Stream.Free; + end; +end; + +procedure SplitStringToList(const S: string; List: TStrings); +const + LINE_WIDTH = 64; +var + C, R: string; +begin + if List = nil then + Exit; + + List.Clear; + if S <> '' then + begin + R := S; + while R <> '' do + begin + C := Copy(R, 1, LINE_WIDTH); + Delete(R, 1, LINE_WIDTH); + List.Add(C); + end; + end; +end; + +function SaveMemoryToPemFile(const FileName, Head, Tail: string; + MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod; + KeyHashMethod: TCnKeyHashMethod; const Password: string; Append: Boolean): Boolean; +var + S, EH: string; + List, Sl: TStringList; +begin + Result := False; + if (MemoryStream <> nil) and (MemoryStream.Size <> 0) then + begin + MemoryStream.Position := 0; + + if (KeyEncryptMethod <> ckeNone) and (Password <> '') then + begin + // MemoryStream + AddPKCS7Padding(MemoryStream, ENC_TYPE_BLOCK_SIZE[KeyEncryptMethod]); + + // ټ + if not EncryptPemStream(KeyHashMethod, KeyEncryptMethod, MemoryStream, Password, EH) then + Exit; + end; + + if ECN_BASE64_OK = Base64Encode(MemoryStream, S) then + begin + List := TStringList.Create; + try + SplitStringToList(S, List); + + List.Insert(0, Head); // ͨͷ + if EH <> '' then // ͷ + List.Insert(1, EH); + List.Add(Tail); // ͨβ + + if Append and FileExists(FileName) then + begin + Sl := TStringList.Create; + try + Sl.LoadFromFile(FileName); + Sl.AddStrings(List); + Sl.SaveToFile(FileName); + finally + Sl.Free; + end; + end + else + List.SaveToFile(FileName); + + Result := True; + finally + List.Free; + end; + end; + end; +end; + +function SaveMemoryToPemStream(Stream: TStream; const Head, Tail: string; + MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod; + KeyHashMethod: TCnKeyHashMethod; const Password: string; Append: Boolean): Boolean; +var + S, EH: string; + List: TStringList; +begin + Result := False; + if (MemoryStream <> nil) and (MemoryStream.Size <> 0) then + begin + MemoryStream.Position := 0; + + if (KeyEncryptMethod <> ckeNone) and (Password <> '') then + begin + // MemoryStream + AddPKCS7Padding(MemoryStream, ENC_TYPE_BLOCK_SIZE[KeyEncryptMethod]); + + // ټ + if not EncryptPemStream(KeyHashMethod, KeyEncryptMethod, MemoryStream, Password, EH) then + Exit; + end; + + if ECN_BASE64_OK = Base64Encode(MemoryStream, S) then + begin + List := TStringList.Create; + try + SplitStringToList(S, List); + + List.Insert(0, Head); // ͨͷ + if EH <> '' then // ͷ + List.Insert(1, EH); + List.Add(Tail); // ͨβ + + if not Append then + Stream.Size := 0; + + List.SaveToStream(Stream); + + Result := True; + finally + List.Free; + end; + end; + end; +end; + +end. diff --git a/CnPack/Crypto/CnRandom.pas b/CnPack/Crypto/CnRandom.pas index de6a2c3..5bce99f 100644 --- a/CnPack/Crypto/CnRandom.pas +++ b/CnPack/Crypto/CnRandom.pas @@ -1,415 +1,415 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -unit CnRandom; -{* |
-================================================================================
-* ƣ
-* Ԫƣ䵥Ԫ
-* ԪߣCnPack  (master@cnpack.org)
-*     עԪװ Windows ƽ̨ MacOS/Linux ƽ̨µİȫ
-*           ṩȫ书ܡ
-* ƽ̨Win7 + Delphi 5.0
-* ݲԣWin32/Win64/MacOS/Linux + Unicode/NonUnicode
-*   õԪ豾ػ
-* ޸ļ¼2023.01.15 V1.3
-*                Windows ȫ urandom ֧ Linux
-*           2023.01.08 V1.2
-*                Win64  API 
-*           2022.08.22 V1.1
-*               ʹòϵͳṩ
-*           2020.03.27 V1.0
-*               Ԫ CnPrime ж
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - SysUtils {$IFDEF MSWINDOWS}, Windows {$ENDIF}, Classes, CnNative; - -type - ECnRandomAPIError = class(Exception); - -function RandomUInt64: TUInt64; -{* UInt64 Χڵڲ֧ UInt64 ƽ̨ Int64 档 - - - ޣ - - ֵTUInt64 - UInt64 Χڵ -} - -function RandomUInt64LessThan(HighValue: TUInt64): TUInt64; -{* شڵ 0 Сָ UInt64 ֵ - - - HighValue: TUInt64 - ָ UInt64 - - ֵTUInt64 - شڵ 0 Сָ HighValue -} - -function RandomInt64: Int64; -{* شڵ 0 С Int64 ޵ - - - ޣ - - ֵInt64 - شڵ 0 С Int64 ޵ -} - -function RandomInt64LessThan(HighValue: Int64): Int64; -{* شڵ 0 Сָ Int64 ֵб֤ HighValue 0 - - - HighValue: Int64 - ָ Int64 - - ֵInt64 - شڵ 0 Сָ HighValue -} - -function RandomUInt32: Cardinal; -{* UInt32 Χڵ - - - ޣ - - ֵCardinal - UInt32 Χڵ -} - -function RandomUInt32LessThan(HighValue: Cardinal): Cardinal; -{* شڵ 0 Сָ UInt32 ֵ - - - HighValue: Cardinal - ָ UInt32 - - ֵCardinal - شڵ 0 Сָ HighValue -} - -function RandomInt32: Integer; -{* شڵ 0 С Int32 ޵ - - - ޣ - - ֵInteger - شڵ 0 С Int32 ޵ -} - -function RandomInt32LessThan(HighValue: Integer): Integer; -{* شڵ 0 Сָ Int32 б֤ HighValue 0 - - - HighValue: Integer - ָ Int32 - - ֵInteger - شڵ 0 Сָ HighValue -} - -function CnKnuthShuffle(ArrayBase: Pointer; ElementByteSize: Integer; - ElementCount: Integer): Boolean; -{* ߵϴ㷨 ArrayBase ָԪسߴΪ ElementSize ElementCount Ԫؾϴơ - - - ArrayBase: Pointer - ϴƵڴַ - ElementByteSize: Integer - ϴƵÿڴԪҲÿһƵֽڴС - ElementCount: Integer - ڴԪҲƵ - - ֵBoolean - ϴǷɹ -} - -function CnRandomFillBytes(Buf: PAnsiChar; BufByteLen: Integer): Boolean; -{* ʹ Windows API /dev/random 豸ʵ䣬ڲγʼ沢ͷš - - - Buf: PAnsiChar - ڴַ - BufByteLen: Integer - ڴֽڳ - - ֵBoolean - Ƿɹ -} - -function CnRandomFillBytes2(Buf: PAnsiChar; BufByteLen: Integer): Boolean; -{* ʹ Windows API /dev/urandom 豸ʵ䣬 - Windows ʹԤȳʼõ١ - - - Buf: PAnsiChar - ڴַ - BufByteLen: Integer - ڴֽڳ - - ֵBoolean - Ƿɹ -} - -implementation - -{$IFDEF MSWINDOWS} - -const - ADVAPI32 = 'advapi32.dll'; - - CRYPT_VERIFYCONTEXT = $F0000000; - CRYPT_NEWKEYSET = $8; - CRYPT_DELETEKEYSET = $10; - - PROV_RSA_FULL = 1; - NTE_BAD_KEYSET = $80090016; - -function CryptAcquireContext(phProv: PHandle; pszContainer: PAnsiChar; - pszProvider: PAnsiChar; dwProvType: LongWord; dwFlags: LongWord): BOOL; - stdcall; external ADVAPI32 name 'CryptAcquireContextA'; - -function CryptReleaseContext(hProv: THandle; dwFlags: LongWord): BOOL; - stdcall; external ADVAPI32 name 'CryptReleaseContext'; - -function CryptGenRandom(hProv: THandle; dwLen: LongWord; pbBuffer: PAnsiChar): BOOL; - stdcall; external ADVAPI32 name 'CryptGenRandom'; - -var - FHProv: THandle = 0; - -{$ELSE} - -const - DEV_FILE = '/dev/urandom'; - -{$ENDIF} - -function CnRandomFillBytes(Buf: PAnsiChar; BufByteLen: Integer): Boolean; -var -{$IFDEF MSWINDOWS} - HProv: THandle; - Res: DWORD; - B: Boolean; -{$ELSE} - F: TFileStream; -{$ENDIF} -begin - Result := False; -{$IFDEF MSWINDOWS} - // ʹ Windows API ʵ - HProv := 0; - B := CryptAcquireContext(@HProv, nil, nil, PROV_RSA_FULL, 0); - if not B then - B := CryptAcquireContext(@HProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - - if not B then - begin - Res := GetLastError; - if Res = NTE_BAD_KEYSET then // KeyContainer ڣ½ķʽ - begin - if not CryptAcquireContext(@HProv, nil, nil, PROV_RSA_FULL, CRYPT_NEWKEYSET) then - raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext NewKeySet $%8.8x', [GetLastError]); - end - else - raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext $%8.8x', [Res]); - end; - - if HProv <> 0 then - begin - try - Result := CryptGenRandom(HProv, BufByteLen, Buf); - if not Result then - raise ECnRandomAPIError.CreateFmt('Error CryptGenRandom $%8.8x', [GetLastError]); - finally - CryptReleaseContext(HProv, 0); - end; - end; -{$ELSE} - // MacOS/Linux µʵ֣öȡ /dev/urandom ݵķʽ - F := nil; - try - F := TFileStream.Create(DEV_FILE, fmOpenRead); - Result := F.Read(Buf^, BufByteLen) = BufByteLen; - finally - F.Free; - end; -{$ENDIF} -end; - -function CnRandomFillBytes2(Buf: PAnsiChar; BufByteLen: Integer): Boolean; -{$IFNDEF MSWINDOWS} -var - F: TFileStream; -{$ENDIF} -begin -{$IFDEF MSWINDOWS} - Result := CryptGenRandom(FHProv, BufByteLen, Buf); -{$ELSE} - // MacOS/Linux µʵ֣öȡ /dev/urandom ݵķʽ - F := nil; - try - F := TFileStream.Create(DEV_FILE, fmOpenRead); - Result := F.Read(Buf^, BufByteLen) = BufByteLen; - finally - F.Free; - end; -{$ENDIF} -end; - -function RandomUInt64: TUInt64; -var - HL: array[0..1] of Cardinal; -begin - // ϵͳ - if not CnRandomFillBytes2(@HL[0], SizeOf(TUInt64)) then - begin - // ֱ Random * High(TUInt64) ܻᾫȲ Lo ȫ FF˷ֿ - Randomize; - HL[0] := Trunc(Random * High(Cardinal) - 1) + 1; - HL[1] := Trunc(Random * High(Cardinal) - 1) + 1; - end; - - Result := (TUInt64(HL[0]) shl 32) + HL[1]; -end; - -function RandomUInt64LessThan(HighValue: TUInt64): TUInt64; -begin - Result := UInt64Mod(RandomUInt64, HighValue); -end; - -function RandomInt64LessThan(HighValue: Int64): Int64; -var - HL: array[0..1] of Cardinal; -begin - // ϵͳ - if not CnRandomFillBytes2(@HL[0], SizeOf(Int64)) then - begin - // ֱ Random * High(Int64) ܻᾫȲ Lo ȫ FF˷ֿ - Randomize; - HL[0] := Trunc(Random * High(Integer) - 1) + 1; // Int64 λ 1⸺ - HL[1] := Trunc(Random * High(Cardinal) - 1) + 1; - end - else - HL[0] := HL[0] mod (Cardinal(High(Integer)) + 1); // Int64 λ 1⸺ - - Result := (Int64(HL[0]) shl 32) + HL[1]; - Result := Result mod HighValue; // δ HighValue Сڵ 0 -end; - -function RandomInt64: Int64; -begin - Result := RandomInt64LessThan(High(Int64)); -end; - -function RandomUInt32: Cardinal; -var - D: Cardinal; -begin - // ϵͳ - if not CnRandomFillBytes2(@D, SizeOf(Cardinal)) then - begin - Randomize; - D := Trunc(Random * High(Cardinal) - 1) + 1; - end; - - Result := D; -end; - -function RandomUInt32LessThan(HighValue: Cardinal): Cardinal; -begin - Result := RandomUInt32 mod HighValue; -end; - -function RandomInt32: Integer; -begin - Result := RandomInt32LessThan(High(Integer)); -end; - -function RandomInt32LessThan(HighValue: Integer): Integer; -var - D: Cardinal; -begin - // ϵͳ - if not CnRandomFillBytes2(@D, SizeOf(Cardinal)) then - begin - Randomize; - D := Trunc(Random * High(Integer) - 1) + 1; - end - else - D := D mod (Cardinal(High(Integer)) + 1); - - Result := Integer(Int64(D) mod Int64(HighValue)); // δ HighValue Сڵ 0 -end; - -function CnKnuthShuffle(ArrayBase: Pointer; ElementByteSize: Integer; - ElementCount: Integer): Boolean; -var - I, R: Integer; - B1, B2: Pointer; -begin - Result := False; - if (ArrayBase = nil) or (ElementByteSize <= 0) or (ElementCount < 0) then // Ȳ - Exit; - - Result := True; - if ElementCount <= 1 then // ûԪػֻһԪʱϴ - Exit; - - for I := ElementCount - 1 downto 0 do - begin - R := RandomInt32LessThan(I + 1); // 0 I ڵҪ 1 - B1 := Pointer(TCnNativeUInt(ArrayBase) + TCnNativeUInt(I * ElementByteSize)); - B2 := Pointer(TCnNativeUInt(ArrayBase) + TCnNativeUInt(R * ElementByteSize)); - MemorySwap(B1, B2, ElementByteSize); - end; - Result := True; -end; - -{$IFDEF MSWINDOWS} - -procedure StartRandom; -var - Res: DWORD; - B: Boolean; -begin - FHProv := 0; - B := CryptAcquireContext(@FHProv, nil, nil, PROV_RSA_FULL, 0); - if not B then - B := CryptAcquireContext(@FHProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - - if not B then - begin - Res := GetLastError; - if Res = NTE_BAD_KEYSET then // KeyContainer ڣ½ķʽ - begin - if not CryptAcquireContext(@FHProv, nil, nil, PROV_RSA_FULL, CRYPT_NEWKEYSET) then - raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext NewKeySet $%8.8x', [GetLastError]); - end - else - raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext $%8.8x', [Res]); - end; -end; - -procedure StopRandom; -begin - if FHProv <> 0 then - begin - CryptReleaseContext(FHProv, 0); - FHProv := 0; - end; -end; - -initialization - StartRandom; - -finalization - StopRandom; - -{$ENDIF} - -end. +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnRandom; +{* |
+================================================================================
+* ƣ
+* Ԫƣ䵥Ԫ
+* ԪߣCnPack  (master@cnpack.org)
+*     עԪװ Windows ƽ̨ MacOS/Linux ƽ̨µİȫ
+*           ṩȫ书ܡ
+* ƽ̨Win7 + Delphi 5.0
+* ݲԣWin32/Win64/MacOS/Linux + Unicode/NonUnicode
+*   õԪ豾ػ
+* ޸ļ¼2023.01.15 V1.3
+*                Windows ȫ urandom ֧ Linux
+*           2023.01.08 V1.2
+*                Win64  API 
+*           2022.08.22 V1.1
+*               ʹòϵͳṩ
+*           2020.03.27 V1.0
+*               Ԫ CnPrime ж
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils {$IFDEF MSWINDOWS}, Windows {$ENDIF}, Classes, CnNative; + +type + ECnRandomAPIError = class(Exception); + +function RandomUInt64: TUInt64; +{* UInt64 Χڵڲ֧ UInt64 ƽ̨ Int64 档 + + + ޣ + + ֵTUInt64 - UInt64 Χڵ +} + +function RandomUInt64LessThan(HighValue: TUInt64): TUInt64; +{* شڵ 0 Сָ UInt64 ֵ + + + HighValue: TUInt64 - ָ UInt64 + + ֵTUInt64 - شڵ 0 Сָ HighValue +} + +function RandomInt64: Int64; +{* شڵ 0 С Int64 ޵ + + + ޣ + + ֵInt64 - شڵ 0 С Int64 ޵ +} + +function RandomInt64LessThan(HighValue: Int64): Int64; +{* شڵ 0 Сָ Int64 ֵб֤ HighValue 0 + + + HighValue: Int64 - ָ Int64 + + ֵInt64 - شڵ 0 Сָ HighValue +} + +function RandomUInt32: Cardinal; +{* UInt32 Χڵ + + + ޣ + + ֵCardinal - UInt32 Χڵ +} + +function RandomUInt32LessThan(HighValue: Cardinal): Cardinal; +{* شڵ 0 Сָ UInt32 ֵ + + + HighValue: Cardinal - ָ UInt32 + + ֵCardinal - شڵ 0 Сָ HighValue +} + +function RandomInt32: Integer; +{* شڵ 0 С Int32 ޵ + + + ޣ + + ֵInteger - شڵ 0 С Int32 ޵ +} + +function RandomInt32LessThan(HighValue: Integer): Integer; +{* شڵ 0 Сָ Int32 б֤ HighValue 0 + + + HighValue: Integer - ָ Int32 + + ֵInteger - شڵ 0 Сָ HighValue +} + +function CnKnuthShuffle(ArrayBase: Pointer; ElementByteSize: Integer; + ElementCount: Integer): Boolean; +{* ߵϴ㷨 ArrayBase ָԪسߴΪ ElementSize ElementCount Ԫؾϴơ + + + ArrayBase: Pointer - ϴƵڴַ + ElementByteSize: Integer - ϴƵÿڴԪҲÿһƵֽڴС + ElementCount: Integer - ڴԪҲƵ + + ֵBoolean - ϴǷɹ +} + +function CnRandomFillBytes(Buf: PAnsiChar; BufByteLen: Integer): Boolean; +{* ʹ Windows API /dev/random 豸ʵ䣬ڲγʼ沢ͷš + + + Buf: PAnsiChar - ڴַ + BufByteLen: Integer - ڴֽڳ + + ֵBoolean - Ƿɹ +} + +function CnRandomFillBytes2(Buf: PAnsiChar; BufByteLen: Integer): Boolean; +{* ʹ Windows API /dev/urandom 豸ʵ䣬 + Windows ʹԤȳʼõ١ + + + Buf: PAnsiChar - ڴַ + BufByteLen: Integer - ڴֽڳ + + ֵBoolean - Ƿɹ +} + +implementation + +{$IFDEF MSWINDOWS} + +const + ADVAPI32 = 'advapi32.dll'; + + CRYPT_VERIFYCONTEXT = $F0000000; + CRYPT_NEWKEYSET = $8; + CRYPT_DELETEKEYSET = $10; + + PROV_RSA_FULL = 1; + NTE_BAD_KEYSET = $80090016; + +function CryptAcquireContext(phProv: PHandle; pszContainer: PAnsiChar; + pszProvider: PAnsiChar; dwProvType: LongWord; dwFlags: LongWord): BOOL; + stdcall; external ADVAPI32 name 'CryptAcquireContextA'; + +function CryptReleaseContext(hProv: THandle; dwFlags: LongWord): BOOL; + stdcall; external ADVAPI32 name 'CryptReleaseContext'; + +function CryptGenRandom(hProv: THandle; dwLen: LongWord; pbBuffer: PAnsiChar): BOOL; + stdcall; external ADVAPI32 name 'CryptGenRandom'; + +var + FHProv: THandle = 0; + +{$ELSE} + +const + DEV_FILE = '/dev/urandom'; + +{$ENDIF} + +function CnRandomFillBytes(Buf: PAnsiChar; BufByteLen: Integer): Boolean; +var +{$IFDEF MSWINDOWS} + HProv: THandle; + Res: DWORD; + B: Boolean; +{$ELSE} + F: TFileStream; +{$ENDIF} +begin + Result := False; +{$IFDEF MSWINDOWS} + // ʹ Windows API ʵ + HProv := 0; + B := CryptAcquireContext(@HProv, nil, nil, PROV_RSA_FULL, 0); + if not B then + B := CryptAcquireContext(@HProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + + if not B then + begin + Res := GetLastError; + if Res = NTE_BAD_KEYSET then // KeyContainer ڣ½ķʽ + begin + if not CryptAcquireContext(@HProv, nil, nil, PROV_RSA_FULL, CRYPT_NEWKEYSET) then + raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext NewKeySet $%8.8x', [GetLastError]); + end + else + raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext $%8.8x', [Res]); + end; + + if HProv <> 0 then + begin + try + Result := CryptGenRandom(HProv, BufByteLen, Buf); + if not Result then + raise ECnRandomAPIError.CreateFmt('Error CryptGenRandom $%8.8x', [GetLastError]); + finally + CryptReleaseContext(HProv, 0); + end; + end; +{$ELSE} + // MacOS/Linux µʵ֣öȡ /dev/urandom ݵķʽ + F := nil; + try + F := TFileStream.Create(DEV_FILE, fmOpenRead); + Result := F.Read(Buf^, BufByteLen) = BufByteLen; + finally + F.Free; + end; +{$ENDIF} +end; + +function CnRandomFillBytes2(Buf: PAnsiChar; BufByteLen: Integer): Boolean; +{$IFNDEF MSWINDOWS} +var + F: TFileStream; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + Result := CryptGenRandom(FHProv, BufByteLen, Buf); +{$ELSE} + // MacOS/Linux µʵ֣öȡ /dev/urandom ݵķʽ + F := nil; + try + F := TFileStream.Create(DEV_FILE, fmOpenRead); + Result := F.Read(Buf^, BufByteLen) = BufByteLen; + finally + F.Free; + end; +{$ENDIF} +end; + +function RandomUInt64: TUInt64; +var + HL: array[0..1] of Cardinal; +begin + // ϵͳ + if not CnRandomFillBytes2(@HL[0], SizeOf(TUInt64)) then + begin + // ֱ Random * High(TUInt64) ܻᾫȲ Lo ȫ FF˷ֿ + Randomize; + HL[0] := Trunc(Random * High(Cardinal) - 1) + 1; + HL[1] := Trunc(Random * High(Cardinal) - 1) + 1; + end; + + Result := (TUInt64(HL[0]) shl 32) + HL[1]; +end; + +function RandomUInt64LessThan(HighValue: TUInt64): TUInt64; +begin + Result := UInt64Mod(RandomUInt64, HighValue); +end; + +function RandomInt64LessThan(HighValue: Int64): Int64; +var + HL: array[0..1] of Cardinal; +begin + // ϵͳ + if not CnRandomFillBytes2(@HL[0], SizeOf(Int64)) then + begin + // ֱ Random * High(Int64) ܻᾫȲ Lo ȫ FF˷ֿ + Randomize; + HL[0] := Trunc(Random * High(Integer) - 1) + 1; // Int64 λ 1⸺ + HL[1] := Trunc(Random * High(Cardinal) - 1) + 1; + end + else + HL[0] := HL[0] mod (Cardinal(High(Integer)) + 1); // Int64 λ 1⸺ + + Result := (Int64(HL[0]) shl 32) + HL[1]; + Result := Result mod HighValue; // δ HighValue Сڵ 0 +end; + +function RandomInt64: Int64; +begin + Result := RandomInt64LessThan(High(Int64)); +end; + +function RandomUInt32: Cardinal; +var + D: Cardinal; +begin + // ϵͳ + if not CnRandomFillBytes2(@D, SizeOf(Cardinal)) then + begin + Randomize; + D := Trunc(Random * High(Cardinal) - 1) + 1; + end; + + Result := D; +end; + +function RandomUInt32LessThan(HighValue: Cardinal): Cardinal; +begin + Result := RandomUInt32 mod HighValue; +end; + +function RandomInt32: Integer; +begin + Result := RandomInt32LessThan(High(Integer)); +end; + +function RandomInt32LessThan(HighValue: Integer): Integer; +var + D: Cardinal; +begin + // ϵͳ + if not CnRandomFillBytes2(@D, SizeOf(Cardinal)) then + begin + Randomize; + D := Trunc(Random * High(Integer) - 1) + 1; + end + else + D := D mod (Cardinal(High(Integer)) + 1); + + Result := Integer(Int64(D) mod Int64(HighValue)); // δ HighValue Сڵ 0 +end; + +function CnKnuthShuffle(ArrayBase: Pointer; ElementByteSize: Integer; + ElementCount: Integer): Boolean; +var + I, R: Integer; + B1, B2: Pointer; +begin + Result := False; + if (ArrayBase = nil) or (ElementByteSize <= 0) or (ElementCount < 0) then // Ȳ + Exit; + + Result := True; + if ElementCount <= 1 then // ûԪػֻһԪʱϴ + Exit; + + for I := ElementCount - 1 downto 0 do + begin + R := RandomInt32LessThan(I + 1); // 0 I ڵҪ 1 + B1 := Pointer(TCnNativeUInt(ArrayBase) + TCnNativeUInt(I * ElementByteSize)); + B2 := Pointer(TCnNativeUInt(ArrayBase) + TCnNativeUInt(R * ElementByteSize)); + MemorySwap(B1, B2, ElementByteSize); + end; + Result := True; +end; + +{$IFDEF MSWINDOWS} + +procedure StartRandom; +var + Res: DWORD; + B: Boolean; +begin + FHProv := 0; + B := CryptAcquireContext(@FHProv, nil, nil, PROV_RSA_FULL, 0); + if not B then + B := CryptAcquireContext(@FHProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + + if not B then + begin + Res := GetLastError; + if Res = NTE_BAD_KEYSET then // KeyContainer ڣ½ķʽ + begin + if not CryptAcquireContext(@FHProv, nil, nil, PROV_RSA_FULL, CRYPT_NEWKEYSET) then + raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext NewKeySet $%8.8x', [GetLastError]); + end + else + raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext $%8.8x', [Res]); + end; +end; + +procedure StopRandom; +begin + if FHProv <> 0 then + begin + CryptReleaseContext(FHProv, 0); + FHProv := 0; + end; +end; + +initialization + StartRandom; + +finalization + StopRandom; + +{$ENDIF} + +end. diff --git a/CnPack/Crypto/CnSHA1.pas b/CnPack/Crypto/CnSHA1.pas index 4daf51e..0553764 100644 --- a/CnPack/Crypto/CnSHA1.pas +++ b/CnPack/Crypto/CnSHA1.pas @@ -1,737 +1,737 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -unit CnSHA1; -{* |
-================================================================================
-* ƣ
-* ԪƣSHA1 Ӵ㷨ʵֵԪ
-* ԪߣCnPack  (master@cnpack.org)
-*           /ֲ䲿ֹܡ
-*     עԪʵ SHA1 Ӵ㷨Ӧ HMAC 㷨
-* ƽ̨PWin2000Pro + Delphi 5.0
-* ݲԣPWin9X/2000/XP + Delphi 5/6
-*   õԪеַϱػʽ
-* ޸ļ¼2022.04.26 V1.5
-*               ޸ LongWord  Integer ַת֧ MacOS64
-*           2019.12.12 V1.4
-*               ֧ TBytes
-*           2019.04.15 V1.3
-*               ֧ Win32/Win64/MacOS32
-*           2015.08.14 V1.2
-*               л Pascal ֿ֧ƽ̨
-*           2014.10.22 V1.1
-*                HMAC 
-*           2010.07.14 V1.0
-*               Ԫ
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - SysUtils, Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, CnNative, CnConsts; - -type - PCnSHA1Digest = ^TCnSHA1Digest; - TCnSHA1Digest = array[0..19] of Byte; - {* SHA1 Ӵս20 ֽ} - - TCnSHA1Context = record - {* SHA1 Ľṹ} - Hash: array[0..4] of Cardinal; - Hi, Lo: Cardinal; - Buffer: array[0..63] of Byte; - Index: Integer; - Ipad: array[0..63] of Byte; {!< HMAC: inner padding } - Opad: array[0..63] of Byte; {!< HMAC: outer padding } - end; - - TCnSHA1CalcProgressFunc = procedure (ATotal, AProgress: Int64; - var Cancel: Boolean) of object; - {* SHA1 ӴսȻص¼} - -function SHA1(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA1Digest; -{* ݿ SHA1 㡣 - - - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵTCnSHA1Digest - ص SHA1 Ӵֵ -} - -function SHA1Buffer(const Buffer; Count: Cardinal): TCnSHA1Digest; -{* ݿ SHA1 㡣 - - - const Buffer - ݿַ - Count: Cardinal - ݿֽڳ - - ֵTCnSHA1Digest - ص SHA1 Ӵֵ -} - -function SHA1Bytes(Data: TBytes): TCnSHA1Digest; -{* ֽ SHA1 㡣 - - - Data: TBytes - ֽ - - ֵTCnSHA1Digest - ص SHA1 Ӵֵ -} - -function SHA1String(const Str: string): TCnSHA1Digest; -{* String ݽ SHA1 㡣ע D2009 ϰ汾 string Ϊ UnicodeString - лὫǿת AnsiString м㡣 - - - const Str: string - ַ - - ֵTCnSHA1Digest - ص SHA1 Ӵֵ -} - -function SHA1StringA(const Str: AnsiString): TCnSHA1Digest; -{* AnsiString ַ SHA1 㣬ֱӼڲݣޱ봦 - - - const Str: AnsiString - ַ - - ֵTCnSHA1Digest - ص SHA1 Ӵֵ -} - -function SHA1StringW(const Str: WideString): TCnSHA1Digest; -{* WideString ַת SHA1 㡣 - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - - ֵTCnSHA1Digest - ص SHA1 Ӵֵ -} - -{$IFDEF UNICODE} - -function SHA1UnicodeString(const Str: string): TCnSHA1Digest; -{* UnicodeString ݽֱӵ SHA1 㣬ֱӼڲ UTF16 ݣת - - - const Str: string - Ŀַ - - ֵTCnSHA1Digest - ص SHA1 Ӵֵ -} - -{$ELSE} - -function SHA1UnicodeString(const Str: WideString): TCnSHA1Digest; -{* UnicodeString ݽֱӵ SHA1 㣬ֱӼڲ UTF16 ݣת - - - const Str: WideString - Ŀַ - - ֵTCnSHA1Digest - ص SHA1 Ӵֵ -} - -{$ENDIF} - -function SHA1File(const FileName: string; - CallBack: TCnSHA1CalcProgressFunc = nil): TCnSHA1Digest; -{* ָļݽ SHA1 㡣 - - - const FileName: string - ļ - CallBack: TCnSHA1CalcProgressFunc - ȻصĬΪ - - ֵTCnSHA1Digest - ص SHA1 Ӵֵ -} - -function SHA1Stream(Stream: TStream; - CallBack: TCnSHA1CalcProgressFunc = nil): TCnSHA1Digest; -{* ָݽ SHA1 㡣 - - - Stream: TStream - - CallBack: TCnSHA1CalcProgressFunc - ȻصĬΪ - - ֵTCnSHA1Digest - ص SHA1 Ӵֵ -} - -// ⲿݽɢ SHA1 㣬SHA1Update ɶα - -procedure SHA1Init(var Context: TCnSHA1Context); -{* ʼһ SHA1 ģ׼ SHA1 - - - var Context: TCnSHA1Context - ʼ SHA1 - - ֵޣ -} - -procedure SHA1Update(var Context: TCnSHA1Context; Input: PAnsiChar; ByteLength: Integer); -{* ԳʼĶһݽ SHA1 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnSHA1Context - SHA1 - Input: PAnsiChar - ݿַ - ByteLength: Integer - ݿֽڳ - - ֵޣ -} - -procedure SHA1Final(var Context: TCnSHA1Context; var Digest: TCnSHA1Digest); -{* ּ㣬 SHA1 Digest С - - - var Context: TCnSHA1Context - SHA1 - var Digest: TCnSHA1Digest - ص SHA1 Ӵֵ - - ֵޣ -} - -function SHA1Print(const Digest: TCnSHA1Digest): string; -{* ʮƸʽ SHA1 Ӵֵ - - - const Digest: TCnSHA1Digest - ָ SHA1 Ӵֵ - - ֵstring - ʮַ -} - -function SHA1Match(const D1: TCnSHA1Digest; const D2: TCnSHA1Digest): Boolean; -{* Ƚ SHA1 ӴֵǷȡ - - - const D1: TCnSHA1Digest - Ƚϵ SHA1 Ӵֵһ - const D2: TCnSHA1Digest - Ƚϵ SHA1 Ӵֵ - - ֵBoolean - Ƿ -} - -function SHA1DigestToStr(const Digest: TCnSHA1Digest): string; -{* SHA1 Ӵֱֵת stringÿֽڶӦһַ - - - const Digest: TCnSHA1Digest - ת SHA1 Ӵֵ - - ֵstring - صַ -} - -procedure SHA1Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA1Digest); -{* SHA1 HMACHash-based Message Authentication Code㣬 - ͨݵļϼԿĸҲмΡ - - - Key: PAnsiChar - SHA1 Կݿַ - KeyByteLength: Integer - SHA1 Կݿֽڳ - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - var Output: TCnSHA1Digest - ص SHA1 Ӵֵ - - ֵޣ -} - -implementation - -const - MAX_FILE_SIZE = 512 * 1024 * 1024; - // If file size <= this size (bytes), using Mapping, else stream - - HMAC_SHA1_BLOCK_SIZE_BYTE = 64; - HMAC_SHA1_OUTPUT_LENGTH_BYTE = 20; - -function LRot32(X: Cardinal; C: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := X shl (C and 31) + X shr (32 - C and 31); -end; - -function F1(x, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := z xor (x and (y xor z)); -end; - -function F2(x, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := x xor y xor z; -end; - -function F3(x, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (x and y) or (z and (x or y)); -end; - -function RB(A: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (A shr 24) or ((A shr 8) and $FF00) or ((A shl 8) and $FF0000) or (A shl 24); -end; - -procedure SHA1Compress(var Data: TCnSHA1Context); -var - A, B, C, D, E, T: Cardinal; - W: array[0..79] of Cardinal; - I: Integer; -begin - Move(Data.Buffer, W, Sizeof(Data.Buffer)); - for I := 0 to 15 do - W[I] := RB(W[I]); - for I := 16 to 79 do - W[I] := LRot32(W[I - 3] xor W[I - 8] xor W[I - 14] xor W[I - 16], 1); - A := Data.Hash[0]; - B := Data.Hash[1]; - C := Data.Hash[2]; - D := Data.Hash[3]; - E := Data.Hash[4]; - for I := 0 to 19 do - begin - T := LRot32(A, 5) + F1(B, C, D) + E + W[I] + $5A827999; - E := D; - D := C; - C := LRot32(B, 30); - B := A; - A := T; - end; - for I := 20 to 39 do - begin - T := LRot32(A, 5) + F2(B, C, D) + E + W[I] + $6ED9EBA1; - E := D; - D := C; - C := LRot32(B, 30); - B := A; - A := T; - end; - for I := 40 to 59 do - begin - T := LRot32(A, 5) + F3(B, C, D) + E + W[I] + $8F1BBCDC; - E := D; - D := C; - C := LRot32(B, 30); - B := A; - A := T; - end; - for I := 60 to 79 do - begin - T := LRot32(A, 5) + F2(B, C, D) + E + W[I] + $CA62C1D6; - E := D; - D := C; - C := LRot32(B, 30); - B := A; - A := T; - end; - Data.Hash[0] := Data.Hash[0] + A; - Data.Hash[1] := Data.Hash[1] + B; - Data.Hash[2] := Data.Hash[2] + C; - Data.Hash[3] := Data.Hash[3] + D; - Data.Hash[4] := Data.Hash[4] + E; - FillChar(W, Sizeof(W), 0); - FillChar(Data.Buffer, Sizeof(Data.Buffer), 0); -end; - -procedure SHA1Init(var Context: TCnSHA1Context); -begin - Context.Hi := 0; - Context.Lo := 0; - Context.Index := 0; - FillChar(Context.Buffer, Sizeof(Context.Buffer), 0); - Context.Hash[0] := $67452301; - Context.Hash[1] := $EFCDAB89; - Context.Hash[2] := $98BADCFE; - Context.Hash[3] := $10325476; - Context.Hash[4] := $C3D2E1F0; -end; - -procedure SHA1UpdateLen(var Context: TCnSHA1Context; Len: Integer); -var - I: Cardinal; - K: Integer; -begin - for K := 0 to 7 do - begin - I := Context.Lo; - Inc(Context.Lo, Len); - if Context.Lo < I then - Inc(Context.Hi); - end; -end; - -procedure SHA1Update(var Context: TCnSHA1Context; Input: PAnsiChar; ByteLength: Integer); -begin - SHA1UpdateLen(Context, ByteLength); - while ByteLength > 0 do - begin - Context.Buffer[Context.Index] := PByte(Input)^; - Inc(PByte(Input)); - Inc(Context.Index); - Dec(ByteLength); - if Context.Index = 64 then - begin - Context.Index := 0; - SHA1Compress(Context); - end; - end; -end; - -procedure SHA1UpdateW(var Context: TCnSHA1Context; Input: PWideChar; CharLength: Cardinal); -var -{$IFDEF MSWINDOWS} - pContent: PAnsiChar; - iLen: Cardinal; -{$ELSE} - S: string; // UnicodeString - A: AnsiString; -{$ENDIF} -begin -{$IFDEF MSWINDOWS} - GetMem(pContent, CharLength * SizeOf(WideChar)); - try - iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 - PAnsiChar(pContent), CharLength * SizeOf(WideChar), nil, nil); - SHA1Update(Context, pContent, iLen); - finally - FreeMem(pContent); - end; -{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ - S := StrNew(Input); - A := AnsiString(S); - SHA1Update(Context, @A[1], Length(A)); -{$ENDIF} -end; - -procedure SHA1Final(var Context: TCnSHA1Context; var Digest: TCnSHA1Digest); -type - PDWord = ^Cardinal; -begin - Context.Buffer[Context.Index] := $80; - if Context.Index >= 56 then - SHA1Compress(Context); - PDWord(@Context.Buffer[56])^ := RB(Context.Hi); - PDWord(@Context.Buffer[60])^ := RB(Context.Lo); - SHA1Compress(Context); - Context.Hash[0] := RB(Context.Hash[0]); - Context.Hash[1] := RB(Context.Hash[1]); - Context.Hash[2] := RB(Context.Hash[2]); - Context.Hash[3] := RB(Context.Hash[3]); - Context.Hash[4] := RB(Context.Hash[4]); - Move(Context.Hash, Digest, Sizeof(Digest)); -end; - -// ݿ SHA1 -function SHA1(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA1Digest; -var - Context: TCnSHA1Context; -begin - SHA1Init(Context); - SHA1Update(Context, Input, ByteLength); - SHA1Final(Context, Result); -end; - -// ݿ SHA1 -function SHA1Buffer(const Buffer; Count: Cardinal): TCnSHA1Digest; -var - Context: TCnSHA1Context; -begin - SHA1Init(Context); - SHA1Update(Context, PAnsiChar(Buffer), Count); - SHA1Final(Context, Result); -end; - -function SHA1Bytes(Data: TBytes): TCnSHA1Digest; -var - Context: TCnSHA1Context; -begin - SHA1Init(Context); - SHA1Update(Context, PAnsiChar(@Data[0]), Length(Data)); - SHA1Final(Context, Result); -end; - -// String ݽ SHA1 -function SHA1String(const Str: string): TCnSHA1Digest; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := SHA1StringA(AStr); -end; - -// AnsiString ݽ SHA1 -function SHA1StringA(const Str: AnsiString): TCnSHA1Digest; -var - Context: TCnSHA1Context; -begin - SHA1Init(Context); - SHA1Update(Context, PAnsiChar(Str), Length(Str)); - SHA1Final(Context, Result); -end; - -// WideString ݽ SHA1 -function SHA1StringW(const Str: WideString): TCnSHA1Digest; -var - Context: TCnSHA1Context; -begin - SHA1Init(Context); - SHA1UpdateW(Context, PWideChar(Str), Length(Str)); - SHA1Final(Context, Result); -end; - -{$IFDEF UNICODE} -function SHA1UnicodeString(const Str: string): TCnSHA1Digest; -{$ELSE} -function SHA1UnicodeString(const Str: WideString): TCnSHA1Digest; -{$ENDIF} -var - Context: TCnSHA1Context; -begin - SHA1Init(Context); - SHA1Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - SHA1Final(Context, Result); -end; - -function InternalSHA1Stream(Stream: TStream; const BufSize: Cardinal; var D: - TCnSHA1Digest; CallBack: TCnSHA1CalcProgressFunc = nil): Boolean; -var - Context: TCnSHA1Context; - Buf: PAnsiChar; - BufLen: Cardinal; - Size: Int64; - ReadBytes: Cardinal; - TotalBytes: Int64; - SavePos: Int64; - CancelCalc: Boolean; -begin - Result := False; - Size := Stream.Size; - SavePos := Stream.Position; - TotalBytes := 0; - if Size = 0 then Exit; - if Size < BufSize then BufLen := Size - else BufLen := BufSize; - - CancelCalc := False; - SHA1Init(Context); - GetMem(Buf, BufLen); - try - Stream.Position := 0; - repeat - ReadBytes := Stream.Read(Buf^, BufLen); - if ReadBytes <> 0 then - begin - Inc(TotalBytes, ReadBytes); - SHA1Update(Context, Buf, ReadBytes); - if Assigned(CallBack) then - begin - CallBack(Size, TotalBytes, CancelCalc); - if CancelCalc then Exit; - end; - end; - until (ReadBytes = 0) or (TotalBytes = Size); - SHA1Final(Context, D); - Result := True; - finally - FreeMem(Buf, BufLen); - Stream.Position := SavePos; - end; -end; - -// ָ SHA1 -function SHA1Stream(Stream: TStream; - CallBack: TCnSHA1CalcProgressFunc = nil): TCnSHA1Digest; -begin - InternalSHA1Stream(Stream, 4096 * 1024, Result, CallBack); -end; - -// ָļݽ SHA1 -function SHA1File(const FileName: string; - CallBack: TCnSHA1CalcProgressFunc): TCnSHA1Digest; -var -{$IFDEF MSWINDOWS} - FileHandle: THandle; - MapHandle: THandle; - ViewPointer: Pointer; - Context: TCnSHA1Context; -{$ENDIF} - Stream: TStream; - FileIsZeroSize: Boolean; - - function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; -{$IFDEF MSWINDOWS} - var - H: THandle; - Info: BY_HANDLE_FILE_INFORMATION; - Rec : Int64Rec; -{$ENDIF} - begin -{$IFDEF MSWINDOWS} - Result := False; - IsEmpty := False; - H := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); - if H = INVALID_HANDLE_VALUE then Exit; - try - if not GetFileInformationByHandle(H, Info) then Exit; - finally - CloseHandle(H); - end; - Rec.Lo := Info.nFileSizeLow; - Rec.Hi := Info.nFileSizeHigh; - Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); - IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); -{$ELSE} - Result := True; // Windows ƽ̨ Trueʾ Mapping -{$ENDIF} - end; - -begin - FileIsZeroSize := False; - if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then - begin - // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ - Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try - InternalSHA1Stream(Stream, 4096 * 1024, Result, CallBack); - finally - Stream.Free; - end; - end - else - begin -{$IFDEF MSWINDOWS} - SHA1Init(Context); - FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or - FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or - FILE_FLAG_SEQUENTIAL_SCAN, 0); - if FileHandle <> INVALID_HANDLE_VALUE then - begin - try - MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); - if MapHandle <> 0 then - begin - try - ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); - if ViewPointer <> nil then - begin - try - SHA1Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); - finally - UnmapViewOfFile(ViewPointer); - end; - end - else - begin - raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); - end; - finally - CloseHandle(MapHandle); - end; - end - else - begin - if not FileIsZeroSize then - raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); - end; - finally - CloseHandle(FileHandle); - end; - end; - SHA1Final(Context, Result); -{$ENDIF} - end; -end; - -// ʮƸʽ SHA1 Ӵֵ -function SHA1Print(const Digest: TCnSHA1Digest): string; -begin - Result := DataToHex(@Digest[0], SizeOf(TCnSHA1Digest)); -end; - -// Ƚ SHA1 ӴֵǷ -function SHA1Match(const D1, D2: TCnSHA1Digest): Boolean; -var - I: Integer; -begin - I := 0; - Result := True; - while Result and (I < 20) do - begin - Result := D1[I] = D2[I]; - Inc(I); - end; -end; - -// SHA1 Ӵֵת string -function SHA1DigestToStr(const Digest: TCnSHA1Digest): string; -begin - Result := MemoryToString(@Digest[0], SizeOf(TCnSHA1Digest)); -end; - -procedure SHA1HmacInit(var Ctx: TCnSHA1Context; Key: PAnsiChar; KeyLength: Integer); -var - I: Integer; - Sum: TCnSHA1Digest; -begin - if KeyLength > HMAC_SHA1_BLOCK_SIZE_BYTE then - begin - Sum := SHA1Buffer(Key, KeyLength); - KeyLength := HMAC_SHA1_OUTPUT_LENGTH_BYTE; - Key := @(Sum[0]); - end; - - FillChar(Ctx.Ipad, HMAC_SHA1_BLOCK_SIZE_BYTE, $36); - FillChar(Ctx.Opad, HMAC_SHA1_BLOCK_SIZE_BYTE, $5C); - - for I := 0 to KeyLength - 1 do - begin - Ctx.Ipad[I] := Byte(Ctx.Ipad[I] xor Byte(Key[I])); - Ctx.Opad[I] := Byte(Ctx.Opad[I] xor Byte(Key[I])); - end; - - SHA1Init(Ctx); - SHA1Update(Ctx, @(Ctx.Ipad[0]), HMAC_SHA1_BLOCK_SIZE_BYTE); -end; - -procedure SHA1HmacUpdate(var Ctx: TCnSHA1Context; Input: PAnsiChar; Length: Cardinal); -begin - SHA1Update(Ctx, Input, Length); -end; - -procedure SHA1HmacFinal(var Ctx: TCnSHA1Context; var Output: TCnSHA1Digest); -var - Len: Integer; - TmpBuf: TCnSHA1Digest; -begin - Len := HMAC_SHA1_OUTPUT_LENGTH_BYTE; - SHA1Final(Ctx, TmpBuf); - SHA1Init(Ctx); - SHA1Update(Ctx, @(Ctx.Opad[0]), HMAC_SHA1_BLOCK_SIZE_BYTE); - SHA1Update(Ctx, @(TmpBuf[0]), Len); - SHA1Final(Ctx, Output); -end; - -procedure SHA1Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA1Digest); -var - Ctx: TCnSHA1Context; -begin - SHA1HmacInit(Ctx, Key, KeyByteLength); - SHA1HmacUpdate(Ctx, Input, ByteLength); - SHA1HmacFinal(Ctx, Output); -end; - -end. +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnSHA1; +{* |
+================================================================================
+* ƣ
+* ԪƣSHA1 Ӵ㷨ʵֵԪ
+* ԪߣCnPack  (master@cnpack.org)
+*           /ֲ䲿ֹܡ
+*     עԪʵ SHA1 Ӵ㷨Ӧ HMAC 㷨
+* ƽ̨PWin2000Pro + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2022.04.26 V1.5
+*               ޸ LongWord  Integer ַת֧ MacOS64
+*           2019.12.12 V1.4
+*               ֧ TBytes
+*           2019.04.15 V1.3
+*               ֧ Win32/Win64/MacOS32
+*           2015.08.14 V1.2
+*               л Pascal ֿ֧ƽ̨
+*           2014.10.22 V1.1
+*                HMAC 
+*           2010.07.14 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, CnNative, CnConsts; + +type + PCnSHA1Digest = ^TCnSHA1Digest; + TCnSHA1Digest = array[0..19] of Byte; + {* SHA1 Ӵս20 ֽ} + + TCnSHA1Context = record + {* SHA1 Ľṹ} + Hash: array[0..4] of Cardinal; + Hi, Lo: Cardinal; + Buffer: array[0..63] of Byte; + Index: Integer; + Ipad: array[0..63] of Byte; {!< HMAC: inner padding } + Opad: array[0..63] of Byte; {!< HMAC: outer padding } + end; + + TCnSHA1CalcProgressFunc = procedure (ATotal, AProgress: Int64; + var Cancel: Boolean) of object; + {* SHA1 ӴսȻص¼} + +function SHA1(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA1Digest; +{* ݿ SHA1 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1Buffer(const Buffer; Count: Cardinal): TCnSHA1Digest; +{* ݿ SHA1 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1Bytes(Data: TBytes): TCnSHA1Digest; +{* ֽ SHA1 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1String(const Str: string): TCnSHA1Digest; +{* String ݽ SHA1 㡣ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1StringA(const Str: AnsiString): TCnSHA1Digest; +{* AnsiString ַ SHA1 㣬ֱӼڲݣޱ봦 + + + const Str: AnsiString - ַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1StringW(const Str: WideString): TCnSHA1Digest; +{* WideString ַת SHA1 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +{$IFDEF UNICODE} + +function SHA1UnicodeString(const Str: string): TCnSHA1Digest; +{* UnicodeString ݽֱӵ SHA1 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +{$ELSE} + +function SHA1UnicodeString(const Str: WideString): TCnSHA1Digest; +{* UnicodeString ݽֱӵ SHA1 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +{$ENDIF} + +function SHA1File(const FileName: string; + CallBack: TCnSHA1CalcProgressFunc = nil): TCnSHA1Digest; +{* ָļݽ SHA1 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA1CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1Stream(Stream: TStream; + CallBack: TCnSHA1CalcProgressFunc = nil): TCnSHA1Digest; +{* ָݽ SHA1 㡣 + + + Stream: TStream - + CallBack: TCnSHA1CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +// ⲿݽɢ SHA1 㣬SHA1Update ɶα + +procedure SHA1Init(var Context: TCnSHA1Context); +{* ʼһ SHA1 ģ׼ SHA1 + + + var Context: TCnSHA1Context - ʼ SHA1 + + ֵޣ +} + +procedure SHA1Update(var Context: TCnSHA1Context; Input: PAnsiChar; ByteLength: Integer); +{* ԳʼĶһݽ SHA1 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA1Context - SHA1 + Input: PAnsiChar - ݿַ + ByteLength: Integer - ݿֽڳ + + ֵޣ +} + +procedure SHA1Final(var Context: TCnSHA1Context; var Digest: TCnSHA1Digest); +{* ּ㣬 SHA1 Digest С + + + var Context: TCnSHA1Context - SHA1 + var Digest: TCnSHA1Digest - ص SHA1 Ӵֵ + + ֵޣ +} + +function SHA1Print(const Digest: TCnSHA1Digest): string; +{* ʮƸʽ SHA1 Ӵֵ + + + const Digest: TCnSHA1Digest - ָ SHA1 Ӵֵ + + ֵstring - ʮַ +} + +function SHA1Match(const D1: TCnSHA1Digest; const D2: TCnSHA1Digest): Boolean; +{* Ƚ SHA1 ӴֵǷȡ + + + const D1: TCnSHA1Digest - Ƚϵ SHA1 Ӵֵһ + const D2: TCnSHA1Digest - Ƚϵ SHA1 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA1DigestToStr(const Digest: TCnSHA1Digest): string; +{* SHA1 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA1Digest - ת SHA1 Ӵֵ + + ֵstring - صַ +} + +procedure SHA1Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA1Digest); +{* SHA1 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA1 Կݿַ + KeyByteLength: Integer - SHA1 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA1Digest - ص SHA1 Ӵֵ + + ֵޣ +} + +implementation + +const + MAX_FILE_SIZE = 512 * 1024 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + HMAC_SHA1_BLOCK_SIZE_BYTE = 64; + HMAC_SHA1_OUTPUT_LENGTH_BYTE = 20; + +function LRot32(X: Cardinal; C: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X shl (C and 31) + X shr (32 - C and 31); +end; + +function F1(x, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := z xor (x and (y xor z)); +end; + +function F2(x, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := x xor y xor z; +end; + +function F3(x, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (x and y) or (z and (x or y)); +end; + +function RB(A: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (A shr 24) or ((A shr 8) and $FF00) or ((A shl 8) and $FF0000) or (A shl 24); +end; + +procedure SHA1Compress(var Data: TCnSHA1Context); +var + A, B, C, D, E, T: Cardinal; + W: array[0..79] of Cardinal; + I: Integer; +begin + Move(Data.Buffer, W, Sizeof(Data.Buffer)); + for I := 0 to 15 do + W[I] := RB(W[I]); + for I := 16 to 79 do + W[I] := LRot32(W[I - 3] xor W[I - 8] xor W[I - 14] xor W[I - 16], 1); + A := Data.Hash[0]; + B := Data.Hash[1]; + C := Data.Hash[2]; + D := Data.Hash[3]; + E := Data.Hash[4]; + for I := 0 to 19 do + begin + T := LRot32(A, 5) + F1(B, C, D) + E + W[I] + $5A827999; + E := D; + D := C; + C := LRot32(B, 30); + B := A; + A := T; + end; + for I := 20 to 39 do + begin + T := LRot32(A, 5) + F2(B, C, D) + E + W[I] + $6ED9EBA1; + E := D; + D := C; + C := LRot32(B, 30); + B := A; + A := T; + end; + for I := 40 to 59 do + begin + T := LRot32(A, 5) + F3(B, C, D) + E + W[I] + $8F1BBCDC; + E := D; + D := C; + C := LRot32(B, 30); + B := A; + A := T; + end; + for I := 60 to 79 do + begin + T := LRot32(A, 5) + F2(B, C, D) + E + W[I] + $CA62C1D6; + E := D; + D := C; + C := LRot32(B, 30); + B := A; + A := T; + end; + Data.Hash[0] := Data.Hash[0] + A; + Data.Hash[1] := Data.Hash[1] + B; + Data.Hash[2] := Data.Hash[2] + C; + Data.Hash[3] := Data.Hash[3] + D; + Data.Hash[4] := Data.Hash[4] + E; + FillChar(W, Sizeof(W), 0); + FillChar(Data.Buffer, Sizeof(Data.Buffer), 0); +end; + +procedure SHA1Init(var Context: TCnSHA1Context); +begin + Context.Hi := 0; + Context.Lo := 0; + Context.Index := 0; + FillChar(Context.Buffer, Sizeof(Context.Buffer), 0); + Context.Hash[0] := $67452301; + Context.Hash[1] := $EFCDAB89; + Context.Hash[2] := $98BADCFE; + Context.Hash[3] := $10325476; + Context.Hash[4] := $C3D2E1F0; +end; + +procedure SHA1UpdateLen(var Context: TCnSHA1Context; Len: Integer); +var + I: Cardinal; + K: Integer; +begin + for K := 0 to 7 do + begin + I := Context.Lo; + Inc(Context.Lo, Len); + if Context.Lo < I then + Inc(Context.Hi); + end; +end; + +procedure SHA1Update(var Context: TCnSHA1Context; Input: PAnsiChar; ByteLength: Integer); +begin + SHA1UpdateLen(Context, ByteLength); + while ByteLength > 0 do + begin + Context.Buffer[Context.Index] := PByte(Input)^; + Inc(PByte(Input)); + Inc(Context.Index); + Dec(ByteLength); + if Context.Index = 64 then + begin + Context.Index := 0; + SHA1Compress(Context); + end; + end; +end; + +procedure SHA1UpdateW(var Context: TCnSHA1Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + pContent: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(pContent, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(pContent), CharLength * SizeOf(WideChar), nil, nil); + SHA1Update(Context, pContent, iLen); + finally + FreeMem(pContent); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SHA1Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +procedure SHA1Final(var Context: TCnSHA1Context; var Digest: TCnSHA1Digest); +type + PDWord = ^Cardinal; +begin + Context.Buffer[Context.Index] := $80; + if Context.Index >= 56 then + SHA1Compress(Context); + PDWord(@Context.Buffer[56])^ := RB(Context.Hi); + PDWord(@Context.Buffer[60])^ := RB(Context.Lo); + SHA1Compress(Context); + Context.Hash[0] := RB(Context.Hash[0]); + Context.Hash[1] := RB(Context.Hash[1]); + Context.Hash[2] := RB(Context.Hash[2]); + Context.Hash[3] := RB(Context.Hash[3]); + Context.Hash[4] := RB(Context.Hash[4]); + Move(Context.Hash, Digest, Sizeof(Digest)); +end; + +// ݿ SHA1 +function SHA1(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, Input, ByteLength); + SHA1Final(Context, Result); +end; + +// ݿ SHA1 +function SHA1Buffer(const Buffer; Count: Cardinal): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, PAnsiChar(Buffer), Count); + SHA1Final(Context, Result); +end; + +function SHA1Bytes(Data: TBytes): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA1Final(Context, Result); +end; + +// String ݽ SHA1 +function SHA1String(const Str: string): TCnSHA1Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA1StringA(AStr); +end; + +// AnsiString ݽ SHA1 +function SHA1StringA(const Str: AnsiString): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, PAnsiChar(Str), Length(Str)); + SHA1Final(Context, Result); +end; + +// WideString ݽ SHA1 +function SHA1StringW(const Str: WideString): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1UpdateW(Context, PWideChar(Str), Length(Str)); + SHA1Final(Context, Result); +end; + +{$IFDEF UNICODE} +function SHA1UnicodeString(const Str: string): TCnSHA1Digest; +{$ELSE} +function SHA1UnicodeString(const Str: WideString): TCnSHA1Digest; +{$ENDIF} +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA1Final(Context, Result); +end; + +function InternalSHA1Stream(Stream: TStream; const BufSize: Cardinal; var D: + TCnSHA1Digest; CallBack: TCnSHA1CalcProgressFunc = nil): Boolean; +var + Context: TCnSHA1Context; + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then Exit; + if Size < BufSize then BufLen := Size + else BufLen := BufSize; + + CancelCalc := False; + SHA1Init(Context); + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + SHA1Update(Context, Buf, ReadBytes); + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + SHA1Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ָ SHA1 +function SHA1Stream(Stream: TStream; + CallBack: TCnSHA1CalcProgressFunc = nil): TCnSHA1Digest; +begin + InternalSHA1Stream(Stream, 4096 * 1024, Result, CallBack); +end; + +// ָļݽ SHA1 +function SHA1File(const FileName: string; + CallBack: TCnSHA1CalcProgressFunc): TCnSHA1Digest; +var +{$IFDEF MSWINDOWS} + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; + Context: TCnSHA1Context; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; + + function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} + var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec : Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then Exit; + try + if not GetFileInformationByHandle(H, Info) then Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} + end; + +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSHA1Stream(Stream, 4096 * 1024, Result, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + SHA1Init(Context); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + SHA1Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + SHA1Final(Context, Result); +{$ENDIF} + end; +end; + +// ʮƸʽ SHA1 Ӵֵ +function SHA1Print(const Digest: TCnSHA1Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA1Digest)); +end; + +// Ƚ SHA1 ӴֵǷ +function SHA1Match(const D1, D2: TCnSHA1Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 20) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// SHA1 Ӵֵת string +function SHA1DigestToStr(const Digest: TCnSHA1Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA1Digest)); +end; + +procedure SHA1HmacInit(var Ctx: TCnSHA1Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA1Digest; +begin + if KeyLength > HMAC_SHA1_BLOCK_SIZE_BYTE then + begin + Sum := SHA1Buffer(Key, KeyLength); + KeyLength := HMAC_SHA1_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Ctx.Ipad, HMAC_SHA1_BLOCK_SIZE_BYTE, $36); + FillChar(Ctx.Opad, HMAC_SHA1_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Ctx.Ipad[I] := Byte(Ctx.Ipad[I] xor Byte(Key[I])); + Ctx.Opad[I] := Byte(Ctx.Opad[I] xor Byte(Key[I])); + end; + + SHA1Init(Ctx); + SHA1Update(Ctx, @(Ctx.Ipad[0]), HMAC_SHA1_BLOCK_SIZE_BYTE); +end; + +procedure SHA1HmacUpdate(var Ctx: TCnSHA1Context; Input: PAnsiChar; Length: Cardinal); +begin + SHA1Update(Ctx, Input, Length); +end; + +procedure SHA1HmacFinal(var Ctx: TCnSHA1Context; var Output: TCnSHA1Digest); +var + Len: Integer; + TmpBuf: TCnSHA1Digest; +begin + Len := HMAC_SHA1_OUTPUT_LENGTH_BYTE; + SHA1Final(Ctx, TmpBuf); + SHA1Init(Ctx); + SHA1Update(Ctx, @(Ctx.Opad[0]), HMAC_SHA1_BLOCK_SIZE_BYTE); + SHA1Update(Ctx, @(TmpBuf[0]), Len); + SHA1Final(Ctx, Output); +end; + +procedure SHA1Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA1Digest); +var + Ctx: TCnSHA1Context; +begin + SHA1HmacInit(Ctx, Key, KeyByteLength); + SHA1HmacUpdate(Ctx, Input, ByteLength); + SHA1HmacFinal(Ctx, Output); +end; + +end. diff --git a/CnPack/Crypto/CnSHA2.pas b/CnPack/Crypto/CnSHA2.pas index dfcc2aa..655e6d8 100644 --- a/CnPack/Crypto/CnSHA2.pas +++ b/CnPack/Crypto/CnSHA2.pas @@ -1,2337 +1,2337 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -unit CnSHA2; -{* |
-================================================================================
-* ƣ
-* ԪƣSHA2 Ӵ㷨ʵֵԪ
-* ԪߣCnPack  (master@cnpack.org)
-*           / C  Pascal ֲ䲿ֹܡ
-*     עԪʵ SHA2 ϵӴ㷨Ӧ HMAC 㷨 SHA224/256/384/512
-*           עDelphi 5/6/7 Ԫз Int64 ޷ UInt64  SHA512/384
-*           ԭǻڲ޷ļӼλԼƵȶͬΨһ
-*           ͬDZȽϣԪûƵıȽϡ
-* ƽ̨PWinXP + Delphi 5.0
-* ݲԣPWinXP/7 + Delphi 5/6
-*   õԪеַϱػʽ
-* ޸ļ¼2022.04.26 V1.4
-*               ޸ LongWord  Integer ַת֧ MacOS64
-*           2019.04.15 V1.3
-*               ֧ Win32/Win64/MacOS32
-*           2017.10.31 V1.2
-*                SHA512/384 HMAC 
-*           2016.09.30 V1.1
-*               ʵ SHA512/384D567з Int64 ޷ UInt64
-*           2016.09.27 V1.0
-*               Ԫ
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - SysUtils, Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, CnNative, CnConsts; - -type - PCnSHAGeneralDigest = ^TCnSHAGeneralDigest; - TCnSHAGeneralDigest = array[0..63] of Byte; - - PCnSHA224Digest = ^TCnSHA224Digest; - TCnSHA224Digest = array[0..27] of Byte; - {* SHA224 Ӵս28 ֽ} - - PCnSHA256Digest = ^TCnSHA256Digest; - TCnSHA256Digest = array[0..31] of Byte; - {* SHA256 Ӵս32 ֽ} - - PCnSHA384Digest = ^TCnSHA384Digest; - TCnSHA384Digest = array[0..47] of Byte; - {* SHA384 Ӵս48 ֽ} - - PCnSHA512Digest = ^TCnSHA512Digest; - TCnSHA512Digest = array[0..63] of Byte; - {* SHA512 Ӵս64 ֽ} - - TCnSHA256Context = packed record - {* SHA256 Ľṹ} - DataLen: Cardinal; - Data: array[0..63] of Byte; - BitLen: Int64; - State: array[0..7] of Cardinal; - Ipad: array[0..63] of Byte; {!< HMAC: inner padding } - Opad: array[0..63] of Byte; {!< HMAC: outer padding } - end; - - TCnSHA224Context = TCnSHA256Context; - {* SHA224 Ľṹ} - - TCnSHA512Context = packed record - {* SHA512 Ľṹ} - DataLen: Cardinal; - Data: array[0..127] of Byte; - TotalLen: Int64; - State: array[0..7] of Int64; - Ipad: array[0..127] of Byte; {!< HMAC: inner padding } - Opad: array[0..127] of Byte; {!< HMAC: outer padding } - end; - - TCnSHA384Context = TCnSHA512Context; - {* SHA512 Ľṹ} - - TCnSHACalcProgressFunc = procedure(ATotal, AProgress: Int64; var Cancel: - Boolean) of object; - {* SHA2 ϵӴսȻص¼} - -function SHA224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA224Digest; -{* ݿ SHA224 㡣 - - - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵTCnSHA224Digest - ص SHA224 Ӵֵ -} - -function SHA256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA256Digest; -{* ݿ SHA256 㡣 - - - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵTCnSHA256Digest - ص SHA256 Ӵֵ -} - -function SHA384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA384Digest; -{* ݿ SHA384 㡣 - - - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵTCnSHA384Digest - ص SHA384Ӵֵ -} - -function SHA512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA512Digest; -{* ݿ SHA512 㡣 - - - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵTCnSHA512Digest - ص SHA512 Ӵֵ -} - -function SHA224Buffer(const Buffer; Count: Cardinal): TCnSHA224Digest; -{* ݿ SHA224 㡣 - - - const Buffer - ݿַ - Count: Cardinal - ݿֽڳ - - ֵTCnSHA224Digest - ص SHA224 Ӵֵ -} - -function SHA256Buffer(const Buffer; Count: Cardinal): TCnSHA256Digest; -{* ݿ SHA256 㡣 - - - const Buffer - ݿַ - Count: Cardinal - - - ֵTCnSHA256Digest - ص SHA256 Ӵֵ -} - -function SHA384Buffer(const Buffer; Count: Cardinal): TCnSHA384Digest; -{* ݿ SHA384 㡣 - - - const Buffer - ݿַ - Count: Cardinal - - - ֵTCnSHA384Digest - ص SHA384Ӵֵ -} - -function SHA512Buffer(const Buffer; Count: Cardinal): TCnSHA512Digest; -{* ݿ SHA512 㡣 - - - const Buffer - ݿַ - Count: Cardinal - - - ֵTCnSHA512Digest - ص SHA512 Ӵֵ -} - -function SHA224Bytes(Data: TBytes): TCnSHA224Digest; -{* ֽ SHA224 㡣 - - - Data: TBytes - ֽ - - ֵTCnSHA224Digest - ص SHA224 Ӵֵ -} - -function SHA256Bytes(Data: TBytes): TCnSHA256Digest; -{* ֽ SHA256 㡣 - - - Data: TBytes - ֽ - - ֵTCnSHA256Digest - ص SHA256 Ӵֵ -} - -function SHA384Bytes(Data: TBytes): TCnSHA384Digest; -{* ֽ SHA384 㡣 - - Data: TBytes - ֽ - - ֵTCnSHA384Digest - ص SHA384Ӵֵ -} - -function SHA512Bytes(Data: TBytes): TCnSHA512Digest; -{* ֽ SHA512 㡣 - - - Data: TBytes - ֽ - - ֵTCnSHA512Digest - ص SHA512 Ӵֵ -} - -function SHA224String(const Str: string): TCnSHA224Digest; -{* String ݽ SHA224 㣬ע D2009 ϰ汾 string Ϊ UnicodeString - лὫǿת AnsiString м㡣 - - - const Str: string - ַ - - ֵTCnSHA224Digest - ص SHA224 Ӵֵ -} - -function SHA256String(const Str: string): TCnSHA256Digest; -{* String ݽ SHA256 㣬ע D2009 ϰ汾 string Ϊ UnicodeString - лὫǿת AnsiString м㡣 - - - const Str: string - ַ - - ֵTCnSHA256Digest - ص SHA256 Ӵֵ -} - -function SHA384String(const Str: string): TCnSHA384Digest; -{* String ݽ SHA384 㣬ע D2009ϰ汾string Ϊ UnicodeString - лὫǿת AnsiString м㡣 - - - const Str: string - ַ - - ֵTCnSHA384Digest - ص SHA384Ӵֵ -} - -function SHA512String(const Str: string): TCnSHA512Digest; -{* String ݽ SHA512 㣬ע D2009 ϰ汾 string Ϊ UnicodeString - лὫǿת AnsiString м㡣 - - - const Str: string - ַ - - ֵTCnSHA512Digest - ص SHA512 Ӵֵ -} - - -function SHA224StringA(const Str: AnsiString): TCnSHA224Digest; -{* AnsiString ݽ SHA224 㡣 - - - const Str: AnsiString - - - ֵTCnSHA224Digest - ص SHA224 Ӵֵ -} - -function SHA224StringW(const Str: WideString): TCnSHA224Digest; -{* WideString ݽ SHA224 㡣 - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - - ֵTCnSHA224Digest - ص SHA224 Ӵֵ -} - -function SHA256StringA(const Str: AnsiString): TCnSHA256Digest; -{* AnsiString ݽ SHA256 㡣 - - - const Str: AnsiString - - - ֵTCnSHA256Digest - ص SHA256 Ӵֵ -} - -function SHA256StringW(const Str: WideString): TCnSHA256Digest; -{* WideString ݽ SHA256 㡣 - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - - ֵTCnSHA256Digest - ص SHA256 Ӵֵ -} - -function SHA384StringA(const Str: AnsiString): TCnSHA384Digest; -{* AnsiString ݽ SHA384 㡣 - - - const Str: AnsiString - - - ֵTCnSHA384Digest - ص SHA384Ӵֵ -} - -function SHA384StringW(const Str: WideString): TCnSHA384Digest; -{* WideString ݽ SHA384 㡣 - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - - ֵTCnSHA384Digest - ص SHA384Ӵֵ -} - -function SHA512StringA(const Str: AnsiString): TCnSHA512Digest; -{* AnsiString ݽ SHA512 㡣 - - - const Str: AnsiString - - - ֵTCnSHA512Digest - ص SHA512 Ӵֵ -} - -function SHA512StringW(const Str: WideString): TCnSHA512Digest; -{* WideString ݽ SHA512 㡣 - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - - ֵTCnSHA512Digest - ص SHA512 Ӵֵ -} - -{$IFDEF UNICODE} - -function SHA224UnicodeString(const Str: string): TCnSHA224Digest; -{* UnicodeString ݽֱӵ SHA224 㣬ֱӼڲ UTF16 ݣת - - - const Str: string - Ŀַ - - ֵTCnSHA224Digest - ص SHA224 Ӵֵ -} - -function SHA256UnicodeString(const Str: string): TCnSHA256Digest; -{* UnicodeString ݽֱӵ SHA256 㣬ֱӼڲ UTF16 ݣת - - - const Str: string - Ŀַ - - ֵTCnSHA256Digest - ص SHA256 Ӵֵ -} - -function SHA384UnicodeString(const Str: string): TCnSHA384Digest; -{* UnicodeString ݽֱӵ SHA384 㣬ֱӼڲ UTF16 ݣת - - - const Str: string - Ŀַ - - ֵTCnSHA384Digest - ص SHA384Ӵֵ -} - -function SHA512UnicodeString(const Str: string): TCnSHA512Digest; -{* UnicodeString ݽֱӵ SHA512 㣬ֱӼڲ UTF16 ݣת - - - const Str: string - Ŀַ - - ֵTCnSHA512Digest - ص SHA512 Ӵֵ -} - -{$ELSE} - -function SHA224UnicodeString(const Str: WideString): TCnSHA224Digest; -{* UnicodeString ݽֱӵ SHA224 㣬ֱӼڲ UTF16 ݣת - - - const Str: WideString - Ŀַ - - ֵTCnSHA224Digest - ص SHA224 Ӵֵ -} - -function SHA256UnicodeString(const Str: WideString): TCnSHA256Digest; -{* UnicodeString ݽֱӵ SHA256 㣬ֱӼڲ UTF16 ݣת - - - const Str: WideString - Ŀַ - - ֵTCnSHA256Digest - ص SHA256 Ӵֵ -} - -function SHA384UnicodeString(const Str: WideString): TCnSHA384Digest; -{* UnicodeString ݽֱӵ SHA384 㣬ֱӼڲ UTF16 ݣת - - - const Str: WideString - Ŀַ - - ֵTCnSHA384Digest - ص SHA384Ӵֵ -} - -function SHA512UnicodeString(const Str: WideString): TCnSHA512Digest; -{* UnicodeString ݽֱӵ SHA512 㣬ֱӼڲ UTF16 ݣת - - - const Str: WideString - Ŀַ - - ֵTCnSHA512Digest - ص SHA512 Ӵֵ -} - -{$ENDIF} - -function SHA224File(const FileName: string; CallBack: TCnSHACalcProgressFunc = - nil): TCnSHA224Digest; -{* ָļݽ SHA256 㡣 - - - const FileName: string - ļ - CallBack: TCnSHACalcProgressFunc - ȻصĬΪ - - ֵTCnSHA224Digest - ص SHA224 Ӵֵ -} - -function SHA224Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): - TCnSHA224Digest; -{* ָݽ SHA224 㡣 - - - Stream: TStream - - CallBack: TCnSHACalcProgressFunc - ȻصĬΪ - - ֵTCnSHA224Digest - ص SHA224 Ӵֵ -} - -function SHA256File(const FileName: string; CallBack: TCnSHACalcProgressFunc = - nil): TCnSHA256Digest; -{* ָļݽ SHA256 㡣 - - - const FileName: string - ļ - CallBack: TCnSHACalcProgressFunc - ȻصĬΪ - - ֵTCnSHA256Digest - ص SHA256 Ӵֵ -} - -function SHA256Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): - TCnSHA256Digest; -{* ָݽ SHA256 㡣 - - - Stream: TStream - - CallBack: TCnSHACalcProgressFunc - ȻصĬΪ - - ֵTCnSHA256Digest - ص SHA256 Ӵֵ -} - -function SHA384File(const FileName: string; CallBack: TCnSHACalcProgressFunc = - nil): TCnSHA384Digest; -{* ָļݽ SHA384 㡣 - - - const FileName: string - ļ - CallBack: TCnSHACalcProgressFunc - ȻصĬΪ - - ֵTCnSHA384Digest - ص SHA384Ӵֵ -} - -function SHA384Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): - TCnSHA384Digest; -{* ָݽ SHA384 㡣 - - - Stream: TStream - - CallBack: TCnSHACalcProgressFunc - ȻصĬΪ - - ֵTCnSHA384Digest - ص SHA384Ӵֵ -} - -function SHA512File(const FileName: string; CallBack: TCnSHACalcProgressFunc = - nil): TCnSHA512Digest; -{* ָļݽ SHA512 㡣 - - - const FileName: string - ļ - CallBack: TCnSHACalcProgressFunc - ȻصĬΪ - - ֵTCnSHA512Digest - ص SHA512 Ӵֵ -} - -function SHA512Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): - TCnSHA512Digest; -{* ָݽ SHA512 㡣 - - - Stream: TStream - - CallBack: TCnSHACalcProgressFunc - ȻصĬΪ - - ֵTCnSHA512Digest - ص SHA512 Ӵֵ -} - -// ⲿݽɢ SHA224 㣬SHA224Update ɶα - -procedure SHA224Init(var Context: TCnSHA224Context); -{* ʼһ SHA224 ģ׼ SHA224 - - - var Context: TCnSHA224Context - ʼ SHA224 - - ֵޣ -} - -procedure SHA224Update(var Context: TCnSHA224Context; Input: PAnsiChar; ByteLength: Cardinal); -{* ԳʼĶһݽ SHA224 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnSHA224Context - SHA224 - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵޣ -} - -procedure SHA224Final(var Context: TCnSHA224Context; var Digest: TCnSHA224Digest); -{* ּ㣬 SHA224 Digest С - - - var Context: TCnSHA224Context - SHA224 - var Digest: TCnSHA224Digest - ص SHA224 Ӵֵ - - ֵޣ -} - -// ⲿݽɢ SHA256 㣬SHA256Update ɶα - -procedure SHA256Init(var Context: TCnSHA256Context); -{* ʼһ SHA256 ģ׼ SHA256 - - - var Context: TCnSHA256Context - ʼ SHA256 - - ֵޣ -} - -procedure SHA256Update(var Context: TCnSHA256Context; Input: PAnsiChar; ByteLength: Cardinal); -{* ԳʼĶһݽ SHA256 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnSHA256Context - SHA256 - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵޣ -} - -procedure SHA256Final(var Context: TCnSHA256Context; var Digest: TCnSHA256Digest); -{* ּ㣬 SHA256 Digest С - - - var Context: TCnSHA256Context - SHA256 - var Digest: TCnSHA256Digest - ص SHA256 Ӵֵ - - ֵޣ -} - -// ⲿݽɢ SHA384 㣬SHA384Update ɶα - -procedure SHA384Init(var Context: TCnSHA384Context); -{* ʼһ SHA384 ģ׼ SHA384 - - - var Context: TCnSHA384Context - ʼ SHA384 - - ֵޣ -} - -procedure SHA384Update(var Context: TCnSHA384Context; Input: PAnsiChar; ByteLength: Cardinal); -{* ԳʼĶһݽ SHA384 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnSHA384Context - SHA384 - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵޣ -} - -procedure SHA384Final(var Context: TCnSHA384Context; var Digest: TCnSHA384Digest); -{* ּ㣬 SHA384 Digest С - - - var Context: TCnSHA384Context - SHA384 - var Digest: TCnSHA384Digest - ص SHA384 Ӵֵ - - ֵޣ -} - -// ⲿݽɢ SHA512 㣬SHA512Update ɶα - -procedure SHA512Init(var Context: TCnSHA512Context); -{* ʼһ SHA512 ģ׼ SHA512 - - - var Context: TCnSHA512Context - ʼ SHA512 - - ֵޣ -} - -procedure SHA512Update(var Context: TCnSHA512Context; Input: PAnsiChar; ByteLength: Cardinal); -{* ԳʼĶһݽ SHA512 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnSHA512Context - SHA512 - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵޣ -} - -procedure SHA512Final(var Context: TCnSHA512Context; var Digest: TCnSHA512Digest); -{* ּ㣬 SHA512 Digest - - - var Context: TCnSHA512Context - SHA512 - var Digest: TCnSHA512Digest - ص SHA512 Ӵֵ - - ֵޣ -} - -function SHA224Print(const Digest: TCnSHA224Digest): string; -{* ʮƸʽ SHA224 Ӵֵ - - - const Digest: TCnSHA224Digest - ָ SHA224 Ӵֵ - - ֵstring - ʮַ -} - -function SHA256Print(const Digest: TCnSHA256Digest): string; -{* ʮƸʽ SHA256 Ӵֵ - - - const Digest: TCnSHA256Digest - ָ SHA256 Ӵֵ - - ֵstring - ʮַ -} - -function SHA384Print(const Digest: TCnSHA384Digest): string; -{* ʮƸʽ SHA384 Ӵֵ - - - const Digest: TCnSHA384Digest - ָ SHA384 Ӵֵ - - ֵstring - ʮַ -} - -function SHA512Print(const Digest: TCnSHA512Digest): string; -{* ʮƸʽ SHA512 Ӵֵ - - - const Digest: TCnSHA512Digest - ָ SHA512 Ӵֵ - - ֵstring - ʮַ -} - -function SHA224Match(const D1: TCnSHA224Digest; const D2: TCnSHA224Digest): Boolean; -{* Ƚ SHA224 ӴֵǷȡ - - - const D1: TCnSHA224Digest - Ƚϵ SHA224 Ӵֵһ - const D2: TCnSHA224Digest - Ƚϵ SHA224 Ӵֵ - - ֵBoolean - Ƿ -} - -function SHA256Match(const D1: TCnSHA256Digest; const D2: TCnSHA256Digest): Boolean; -{* Ƚ SHA256 ӴֵǷȡ - - - const D1: TCnSHA256Digest - Ƚϵ SHA256 Ӵֵһ - const D2: TCnSHA256Digest - Ƚϵ SHA256 Ӵֵ - - ֵBoolean - Ƿ -} - -function SHA384Match(const D1: TCnSHA384Digest; const D2: TCnSHA384Digest): Boolean; -{* Ƚ SHA384 ӴֵǷȡ - - - const D1: TCnSHA384Digest - Ƚϵ SHA384 Ӵֵһ - const D2: TCnSHA384Digest - Ƚϵ SHA384 Ӵֵ - - ֵBoolean - Ƿ -} - -function SHA512Match(const D1: TCnSHA512Digest; const D2: TCnSHA512Digest): Boolean; -{* Ƚ SHA512 ӴֵǷȡ - - - const D1: TCnSHA512Digest - Ƚϵ SHA512 Ӵֵһ - const D2: TCnSHA512Digest - Ƚϵ SHA512 Ӵֵ - - ֵBoolean - Ƿ -} - -function SHA224DigestToStr(const Digest: TCnSHA224Digest): string; -{* SHA224 Ӵֱֵת stringÿֽڶӦһַ - - - const Digest: TCnSHA224Digest - ת SHA224 Ӵֵ - - ֵstring - صַ -} - -function SHA256DigestToStr(const Digest: TCnSHA256Digest): string; -{* SHA256 Ӵֱֵת stringÿֽڶӦһַ - - - const Digest: TCnSHA256Digest - ת SHA256 Ӵֵ - - ֵstring - صַ -} - -function SHA384DigestToStr(const Digest: TCnSHA384Digest): string; -{* SHA384 Ӵֱֵת stringÿֽڶӦһַ - - - const Digest: TCnSHA384Digest - ת SHA384 Ӵֵ - - ֵstring - صַ -} - -function SHA512DigestToStr(const Digest: TCnSHA512Digest): string; -{* SHA512 Ӵֱֵת stringÿֽڶӦһַ - - - const Digest: TCnSHA512Digest - ת SHA512 Ӵֵ - - ֵstring - صַ -} - -procedure SHA224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA224Digest); -{* SHA224 HMACHash-based Message Authentication Code㣬 - ͨݵļϼԿĸҲмΡ - - - Key: PAnsiChar - SHA224 Կݿַ - KeyByteLength: Integer - SHA224 Կݿֽڳ - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - var Output: TCnSHA224Digest - ص SHA224 Ӵֵ - - ֵޣ -} - -procedure SHA256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA256Digest); -{* SHA256 HMACHash-based Message Authentication Code㣬 - ͨݵļϼԿĸҲмΡ - - - Key: PAnsiChar - SHA256 Կݿַ - KeyByteLength: Integer - SHA256 Կݿֽڳ - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - var Output: TCnSHA256Digest - ص SHA256 Ӵֵ - - ֵޣ -} - -procedure SHA384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA384Digest); -{* SHA384 HMACHash-based Message Authentication Code㣬 - ͨݵļϼԿĸҲмΡ - - - Key: PAnsiChar - SHA384 Կݿַ - KeyByteLength: Integer - SHA384 Կݿֽڳ - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - var Output: TCnSHA384Digest - ص SHA384 Ӵֵ - - ֵޣ -} - -procedure SHA512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA512Digest); -{* SHA512 HMACHash-based Message Authentication Code㣬 - ͨݵļϼԿĸҲмΡ - - - Key: PAnsiChar - SHA512 Կݿַ - KeyByteLength: Integer - SHA512 Կݿֽڳ - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - var Output: TCnSHA512Digest - ص SHA512 Ӵֵ - - ֵޣ -} - -implementation - -const - HMAC_SHA2_224_256_BLOCK_SIZE_BYTE = 64; - HMAC_SHA2_384_512_BLOCK_SIZE_BYTE = 128; - - HMAC_SHA2_224_OUTPUT_LENGTH_BYTE = 28; - HMAC_SHA2_256_OUTPUT_LENGTH_BYTE = 32; - HMAC_SHA2_384_OUTPUT_LENGTH_BYTE = 48; - HMAC_SHA2_512_OUTPUT_LENGTH_BYTE = 64; - -type - TSHA2Type = (stSHA2_224, stSHA2_256, stSHA2_384, stSHA2_512); - -const - MAX_FILE_SIZE = 512 * 1024 * 1024; - // If file size <= this size (bytes), using Mapping, else stream - - KEYS256: array[0..63] of Cardinal = ($428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, - $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5, $D807AA98, $12835B01, $243185BE, - $550C7DC3, $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, $E49B69C1, $EFBE4786, - $0FC19DC6, $240CA1CC, $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA, $983E5152, - $A831C66D, $B00327C8, $BF597FC7, $C6E00BF3, $D5A79147, $06CA6351, $14292967, - $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, $650A7354, $766A0ABB, $81C2C92E, - $92722C85, $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, $D192E819, $D6990624, - $F40E3585, $106AA070, $19A4C116, $1E376C08, $2748774C, $34B0BCB5, $391C0CB3, - $4ED8AA4A, $5B9CCA4F, $682E6FF3, $748F82EE, $78A5636F, $84C87814, $8CC70208, - $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2); - - KEYS512: array[0..79] of TUInt64 = ($428A2F98D728AE22, $7137449123EF65CD, - $B5C0FBCFEC4D3B2F, $E9B5DBA58189DBBC, $3956C25BF348B538, $59F111F1B605D019, - $923F82A4AF194F9B, $AB1C5ED5DA6D8118, $D807AA98A3030242, $12835B0145706FBE, - $243185BE4EE4B28C, $550C7DC3D5FFB4E2, $72BE5D74F27B896F, $80DEB1FE3B1696B1, - $9BDC06A725C71235, $C19BF174CF692694, $E49B69C19EF14AD2, $EFBE4786384F25E3, - $0FC19DC68B8CD5B5, $240CA1CC77AC9C65, $2DE92C6F592B0275, $4A7484AA6EA6E483, - $5CB0A9DCBD41FBD4, $76F988DA831153B5, $983E5152EE66DFAB, $A831C66D2DB43210, - $B00327C898FB213F, $BF597FC7BEEF0EE4, $C6E00BF33DA88FC2, $D5A79147930AA725, - $06CA6351E003826F, $142929670A0E6E70, $27B70A8546D22FFC, $2E1B21385C26C926, - $4D2C6DFC5AC42AED, $53380D139D95B3DF, $650A73548BAF63DE, $766A0ABB3C77B2A8, - $81C2C92E47EDAEE6, $92722C851482353B, $A2BFE8A14CF10364, $A81A664BBC423001, - $C24B8B70D0F89791, $C76C51A30654BE30, $D192E819D6EF5218, $D69906245565A910, - $F40E35855771202A, $106AA07032BBD1B8, $19A4C116B8D2D0C8, $1E376C085141AB53, - $2748774CDF8EEB99, $34B0BCB5E19B48A8, $391C0CB3C5C95A63, $4ED8AA4AE3418ACB, - $5B9CCA4F7763E373, $682E6FF3D6B2B8A3, $748F82EE5DEFB2FC, $78A5636F43172F60, - $84C87814A1F0AB72, $8CC702081A6439EC, $90BEFFFA23631E28, $A4506CEBDE82BDE9, - $BEF9A3F7B2C67915, $C67178F2E372532B, $CA273ECEEA26619C, $D186B8C721C0C207, - $EADA7DD6CDE0EB1E, $F57D4F7FEE6ED178, $06F067AA72176FBA, $0A637DC5A2C898A6, - $113F9804BEF90DAE, $1B710B35131C471B, $28DB77F523047D84, $32CAAB7B40C72493, - $3C9EBE0A15C9BEBC, $431D67C49C100D4C, $4CC5D4BECB3E42B6, $597F299CFC657E2A, - $5FCB6FAB3AD6FAEC, $6C44198C4A475817); - -function ROTRight256(A, B: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (A shr B) or (A shl (32 - B)); -end; - -function ROTRight512(X: TUInt64; Y: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (X shr Y) or (X shl (64 - Y)); -end; - -function SHR512(X: TUInt64; Y: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (X and $FFFFFFFFFFFFFFFF) shr Y; -end; - -function CH256(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (X and Y) xor ((not X) and Z); -end; - -function CH512(X, Y, Z: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (((Y xor Z) and X) xor Z); -end; - -function MAJ256(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (X and Y) xor (X and Z) xor (Y and Z); -end; - -function MAJ512(X, Y, Z: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := ((X or Y) and Z) or (X and Y); -end; - -function EP0256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := ROTRight256(X, 2) xor ROTRight256(X, 13) xor ROTRight256(X, 22); -end; - -function EP1256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := ROTRight256(X, 6) xor ROTRight256(X, 11) xor ROTRight256(X, 25); -end; - -function SIG0256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := ROTRight256(X, 7) xor ROTRight256(X, 18) xor (X shr 3); -end; - -function SIG1256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := ROTRight256(X, 17) xor ROTRight256(X, 19) xor (X shr 10); -end; - -function SIG0512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := ROTRight512(X, 28) xor ROTRight512(X, 34) xor ROTRight512(X, 39); -end; - -function SIG1512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := ROTRight512(X, 14) xor ROTRight512(X, 18) xor ROTRight512(X, 41); -end; - -function Gamma0512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := ROTRight512(X, 1) xor ROTRight512(X, 8) xor SHR512(X, 7); -end; - -function Gamma1512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := ROTRight512(X, 19) xor ROTRight512(X, 61) xor SHR512(X, 6); -end; - -procedure SHA256Transform(var Context: TCnSHA256Context; Data: PAnsiChar); -var - A, B, C, D, E, F, G, H, T1, T2: Cardinal; - M: array[0..63] of Cardinal; - I, J: Integer; -begin - I := 0; - J := 0; - while I < 16 do - begin - M[I] := (Cardinal(Data[J]) shl 24) or (Cardinal(Data[J + 1]) shl 16) or (Cardinal(Data - [J + 2]) shl 8) or Cardinal(Data[J + 3]); - Inc(I); - Inc(J, 4); - end; - - while I < 64 do - begin - M[I] := SIG1256(M[I - 2]) + M[I - 7] + SIG0256(M[I - 15]) + M[I - 16]; - Inc(I); - end; - - A := Context.State[0]; - B := Context.State[1]; - C := Context.State[2]; - D := Context.State[3]; - E := Context.State[4]; - F := Context.State[5]; - G := Context.State[6]; - H := Context.State[7]; - - I := 0; - while I < 64 do - begin - T1 := H + EP1256(E) + CH256(E, F, G) + KEYS256[I] + M[I]; - T2 := EP0256(A) + MAJ256(A, B, C); - H := G; - G := F; - F := E; - E := D + T1; - D := C; - C := B; - B := A; - A := T1 + T2; - Inc(I); - end; - - Context.State[0] := Context.State[0] + A; - Context.State[1] := Context.State[1] + B; - Context.State[2] := Context.State[2] + C; - Context.State[3] := Context.State[3] + D; - Context.State[4] := Context.State[4] + E; - Context.State[5] := Context.State[5] + F; - Context.State[6] := Context.State[6] + G; - Context.State[7] := Context.State[7] + H; -end; - -{$WARNINGS OFF} - -procedure SHA512Transform(var Context: TCnSHA512Context; Data: PAnsiChar; BlockCount: Integer); -var - A, B, C, D, E, F, G, H, T1, T2: TUInt64; - M: array[0..79] of TUInt64; - I, J, K: Integer; - OrigData: PAnsiChar; -begin - OrigData := Data; - for K := 0 to BlockCount - 1 do - begin - Data := PAnsiChar(TCnNativeInt(OrigData) + (K shl 7)); - - I := 0; - J := 0; - while I < 16 do - begin - M[I] := (TUInt64(Data[J]) shl 56) or (TUInt64(Data[J + 1]) shl 48) or - (TUInt64(Data[J + 2]) shl 40) or (TUInt64(Data[J + 3]) shl 32) or - (TUInt64(Data[J + 4]) shl 24) or (TUInt64(Data[J + 5]) shl 16) or - (TUInt64(Data[J + 6]) shl 8) or TUInt64(Data[J + 7]); - Inc(I); - Inc(J, 8); - end; - - while I < 80 do - begin - M[I] := Gamma1512(M[I - 2]) + M[I - 7] + Gamma0512(M[I - 15]) + M[I - 16]; - Inc(I); - end; - - A := Context.State[0]; - B := Context.State[1]; - C := Context.State[2]; - D := Context.State[3]; - E := Context.State[4]; - F := Context.State[5]; - G := Context.State[6]; - H := Context.State[7]; - - I := 0; - while I < 80 do - begin - T1 := H + SIG1512(E) + CH512(E, F, G) + KEYS512[I] + M[I]; - T2 := SIG0512(A) + MAJ512(A, B, C); - H := G; - G := F; - F := E; - E := D + T1; - D := C; - C := B; - B := A; - A := T1 + T2; - Inc(I); - end; - - // з޷ WarningӰ - Context.State[0] := Context.State[0] + A; - Context.State[1] := Context.State[1] + B; - Context.State[2] := Context.State[2] + C; - Context.State[3] := Context.State[3] + D; - Context.State[4] := Context.State[4] + E; - Context.State[5] := Context.State[5] + F; - Context.State[6] := Context.State[6] + G; - Context.State[7] := Context.State[7] + H; - end; -end; - -{$WARNINGS ON} - -procedure SHA224Init(var Context: TCnSHA224Context); -begin - Context.DataLen := 0; - Context.BitLen := 0; - Context.State[0] := $C1059ED8; - Context.State[1] := $367CD507; - Context.State[2] := $3070DD17; - Context.State[3] := $F70E5939; - Context.State[4] := $FFC00B31; - Context.State[5] := $68581511; - Context.State[6] := $64F98FA7; - Context.State[7] := $BEFA4FA4; - FillChar(Context.Data, SizeOf(Context.Data), 0); -end; - -procedure SHA224Update(var Context: TCnSHA224Context; Input: PAnsiChar; ByteLength: Cardinal); -begin - SHA256Update(Context, Input, ByteLength); -end; - -procedure SHA256UpdateW(var Context: TCnSHA256Context; Input: PWideChar; CharLength: Cardinal); forward; - -procedure SHA224UpdateW(var Context: TCnSHA224Context; Input: PWideChar; CharLength: Cardinal); -begin - SHA256UpdateW(Context, Input, CharLength); -end; - -procedure SHA224Final(var Context: TCnSHA224Context; var Digest: TCnSHA224Digest); -var - Dig: TCnSHA256Digest; -begin - SHA256Final(Context, Dig); - Move(Dig[0], Digest[0], SizeOf(TCnSHA224Digest)); -end; - -procedure SHA256Init(var Context: TCnSHA256Context); -begin - Context.DataLen := 0; - Context.BitLen := 0; - Context.State[0] := $6A09E667; - Context.State[1] := $BB67AE85; - Context.State[2] := $3C6EF372; - Context.State[3] := $A54FF53A; - Context.State[4] := $510E527F; - Context.State[5] := $9B05688C; - Context.State[6] := $1F83D9AB; - Context.State[7] := $5BE0CD19; - FillChar(Context.Data, SizeOf(Context.Data), 0); -end; - -procedure SHA256Update(var Context: TCnSHA256Context; Input: PAnsiChar; ByteLength: Cardinal); -var - I: Integer; -begin - for I := 0 to ByteLength - 1 do - begin - Context.Data[Context.DataLen] := Byte(Input[I]); - Inc(Context.DataLen); - if Context.DataLen = 64 then - begin - SHA256Transform(Context, @Context.Data[0]); - Context.BitLen := Context.BitLen + 512; - Context.DataLen := 0; - end; - end; -end; - -procedure SHA256UpdateW(var Context: TCnSHA256Context; Input: PWideChar; CharLength: Cardinal); -var -{$IFDEF MSWINDOWS} - Content: PAnsiChar; - iLen: Cardinal; -{$ELSE} - S: string; // UnicodeString - A: AnsiString; -{$ENDIF} -begin -{$IFDEF MSWINDOWS} - GetMem(Content, CharLength * SizeOf(WideChar)); - try - iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 - PAnsiChar(Content), CharLength * SizeOf(WideChar), nil, nil); - SHA256Update(Context, Content, iLen); - finally - FreeMem(Content); - end; -{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ - S := StrNew(Input); - A := AnsiString(S); - SHA256Update(Context, @A[1], Length(A)); -{$ENDIF} -end; - -procedure SHA256Final(var Context: TCnSHA256Context; var Digest: TCnSHA256Digest); -var - I: Integer; -begin - I := Context.DataLen; - Context.Data[I] := $80; - Inc(I); - - if Context.Datalen < 56 then - begin - while I < 56 do - begin - Context.Data[I] := 0; - Inc(I); - end; - end - else - begin - while I < 64 do - begin - Context.Data[I] := 0; - Inc(I); - end; - - SHA256Transform(Context, @(Context.Data[0])); - FillChar(Context.Data, 56, 0); - end; - - Context.BitLen := Context.BitLen + Context.DataLen * 8; - Context.Data[63] := Context.Bitlen; - Context.Data[62] := Context.Bitlen shr 8; - Context.Data[61] := Context.Bitlen shr 16; - Context.Data[60] := Context.Bitlen shr 24; - Context.Data[59] := Context.Bitlen shr 32; - Context.Data[58] := Context.Bitlen shr 40; - Context.Data[57] := Context.Bitlen shr 48; - Context.Data[56] := Context.Bitlen shr 56; - SHA256Transform(Context, @(Context.Data[0])); - - for I := 0 to 3 do - begin - Digest[I] := (Context.State[0] shr (24 - I * 8)) and $000000FF; - Digest[I + 4] := (Context.State[1] shr (24 - I * 8)) and $000000FF; - Digest[I + 8] := (Context.State[2] shr (24 - I * 8)) and $000000FF; - Digest[I + 12] := (Context.State[3] shr (24 - I * 8)) and $000000FF; - Digest[I + 16] := (Context.State[4] shr (24 - I * 8)) and $000000FF; - Digest[I + 20] := (Context.State[5] shr (24 - I * 8)) and $000000FF; - Digest[I + 24] := (Context.State[6] shr (24 - I * 8)) and $000000FF; - Digest[I + 28] := (Context.State[7] shr (24 - I * 8)) and $000000FF; - end; -end; - -{$WARNINGS OFF} - -procedure SHA384Init(var Context: TCnSHA384Context); -begin - Context.DataLen := 0; - Context.TotalLen := 0; - Context.State[0] := $CBBB9D5DC1059ED8; - Context.State[1] := $629A292A367CD507; - Context.State[2] := $9159015A3070DD17; - Context.State[3] := $152FECD8F70E5939; - Context.State[4] := $67332667FFC00B31; - Context.State[5] := $8EB44A8768581511; - Context.State[6] := $DB0C2E0D64F98FA7; - Context.State[7] := $47B5481DBEFA4FA4; - FillChar(Context.Data, SizeOf(Context.Data), 0); -end; - -{$WARNINGS ON} - -procedure SHA384Update(var Context: TCnSHA384Context; Input: PAnsiChar; ByteLength: Cardinal); -begin - SHA512Update(Context, Input, ByteLength); -end; - -procedure SHA512UpdateW(var Context: TCnSHA512Context; Input: PWideChar; CharLength: Cardinal); forward; - -procedure SHA384UpdateW(var Context: TCnSHA384Context; Input: PWideChar; CharLength: Cardinal); -begin - SHA512UpdateW(Context, Input, CharLength); -end; - -procedure SHA384Final(var Context: TCnSHA384Context; var Digest: TCnSHA384Digest); -var - Dig: TCnSHA512Digest; -begin - SHA512Final(Context, Dig); - Move(Dig[0], Digest[0], SizeOf(TCnSHA384Digest)); -end; - -{$WARNINGS OFF} - -procedure SHA512Init(var Context: TCnSHA512Context); -begin - Context.DataLen := 0; - Context.TotalLen := 0; - Context.State[0] := $6A09E667F3BCC908; - Context.State[1] := $BB67AE8584CAA73B; - Context.State[2] := $3C6EF372FE94F82B; - Context.State[3] := $A54FF53A5F1D36F1; - Context.State[4] := $510E527FADE682D1; - Context.State[5] := $9B05688C2B3E6C1F; - Context.State[6] := $1F83D9ABFB41BD6B; - Context.State[7] := $5BE0CD19137E2179; - FillChar(Context.Data, SizeOf(Context.Data), 0); -end; - -{$WARNINGS ON} - -procedure SHA512Update(var Context: TCnSHA512Context; Input: PAnsiChar; ByteLength: Cardinal); -var - TempLength, RemainLength, NewLength, BlockCount: Cardinal; -begin - TempLength := 128 - Context.DataLen; - if ByteLength < TempLength then - RemainLength := ByteLength - else - RemainLength := TempLength; - - Move(Input^, Context.Data[Context.DataLen], RemainLength); - if Context.DataLen + ByteLength < 128 then - begin - Inc(Context.DataLen, ByteLength); - Exit; - end; - - NewLength := Cardinal(ByteLength) - RemainLength; - BlockCount := NewLength div 128; - Input := PAnsiChar(TCnNativeUInt(Input) + RemainLength); - - SHA512Transform(Context, @Context.Data[0], 1); - SHA512Transform(Context, Input, BlockCount); - - RemainLength := NewLength mod 128; - Input := PAnsiChar(TCnNativeUInt(Input) + (BlockCount shl 7)); - Move(Input^, Context.Data[Context.DataLen], RemainLength); - - Context.DataLen := RemainLength; - Inc(Context.TotalLen, (BlockCount + 1) shl 7); -end; - -procedure SHA512UpdateW(var Context: TCnSHA512Context; Input: PWideChar; CharLength: Cardinal); -var -{$IFDEF MSWINDOWS} - Content: PAnsiChar; - iLen: Cardinal; -{$ELSE} - S: string; // UnicodeString - A: AnsiString; -{$ENDIF} -begin -{$IFDEF MSWINDOWS} - GetMem(Content, CharLength * SizeOf(WideChar)); - try - iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 - PAnsiChar(Content), CharLength * SizeOf(WideChar), nil, nil); - SHA512Update(Context, Content, iLen); - finally - FreeMem(Content); - end; -{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ - S := StrNew(Input); - A := AnsiString(S); - SHA512Update(Context, @A[1], Length(A)); -{$ENDIF} -end; - -procedure SHA512Final(var Context: TCnSHA512Context; var Digest: TCnSHA512Digest); -var - I: Integer; - BlockCount, BitLength, PmLength: Cardinal; -begin - if (Context.DataLen mod 128) > 111 then - BlockCount := 2 - else - BlockCount := 1; - - BitLength := (Context.TotalLen + Context.DataLen) shl 3; - PmLength := BlockCount shl 7; - FillChar(Context.Data[Context.DataLen], PmLength - Context.DataLen, 0); - Context.Data[Context.DataLen] := $80; - - Context.Data[PmLength - 1] := Byte(BitLength); - Context.Data[PmLength - 2] := Byte(BitLength shr 8); - Context.Data[PmLength - 3] := Byte(BitLength shr 16); - Context.Data[PmLength - 4] := Byte(BitLength shr 24); - - SHA512Transform(Context, @(Context.Data[0]), BlockCount); - - for I := 0 to 7 do - begin - Digest[I] := (Context.State[0] shr (56 - I * 8)) and $000000FF; - Digest[I + 8] := (Context.State[1] shr (56 - I * 8)) and $000000FF; - Digest[I + 16] := (Context.State[2] shr (56 - I * 8)) and $000000FF; - Digest[I + 24] := (Context.State[3] shr (56 - I * 8)) and $000000FF; - Digest[I + 32] := (Context.State[4] shr (56 - I * 8)) and $000000FF; - Digest[I + 40] := (Context.State[5] shr (56 - I * 8)) and $000000FF; - Digest[I + 48] := (Context.State[6] shr (56 - I * 8)) and $000000FF; - Digest[I + 56] := (Context.State[7] shr (56 - I * 8)) and $000000FF; - end; -end; - -// ݿ SHA224 -function SHA224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA224Digest; -var - Context: TCnSHA224Context; -begin - SHA224Init(Context); - SHA224Update(Context, Input, ByteLength); - SHA224Final(Context, Result); -end; - -// ݿ SHA256 -function SHA256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA256Digest; -var - Context: TCnSHA256Context; -begin - SHA256Init(Context); - SHA256Update(Context, Input, ByteLength); - SHA256Final(Context, Result); -end; - -// ݿ SHA384 -function SHA384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA384Digest; -var - Context: TCnSHA384Context; -begin - SHA384Init(Context); - SHA384Update(Context, Input, ByteLength); - SHA384Final(Context, Result); -end; - -// ݿ SHA512 -function SHA512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA512Digest; -var - Context: TCnSHA512Context; -begin - SHA512Init(Context); - SHA512Update(Context, Input, ByteLength); - SHA512Final(Context, Result); -end; - -// ݿ SHA224 -function SHA224Buffer(const Buffer; Count: Cardinal): TCnSHA224Digest; -var - Context: TCnSHA224Context; -begin - SHA224Init(Context); - SHA224Update(Context, PAnsiChar(Buffer), Count); - SHA224Final(Context, Result); -end; - -// ݿ SHA256 -function SHA256Buffer(const Buffer; Count: Cardinal): TCnSHA256Digest; -var - Context: TCnSHA256Context; -begin - SHA256Init(Context); - SHA256Update(Context, PAnsiChar(Buffer), Count); - SHA256Final(Context, Result); -end; - -// ݿ SHA384 -function SHA384Buffer(const Buffer; Count: Cardinal): TCnSHA384Digest; -var - Context: TCnSHA384Context; -begin - SHA384Init(Context); - SHA384Update(Context, PAnsiChar(Buffer), Count); - SHA384Final(Context, Result); -end; - -// ݿ SHA512 -function SHA512Buffer(const Buffer; Count: Cardinal): TCnSHA512Digest; -var - Context: TCnSHA512Context; -begin - SHA512Init(Context); - SHA512Update(Context, PAnsiChar(Buffer), Count); - SHA512Final(Context, Result); -end; - -// ֽ SHA224 -function SHA224Bytes(Data: TBytes): TCnSHA224Digest; -var - Context: TCnSHA224Context; -begin - SHA224Init(Context); - SHA224Update(Context, PAnsiChar(@Data[0]), Length(Data)); - SHA224Final(Context, Result); -end; - -// ֽ SHA256 -function SHA256Bytes(Data: TBytes): TCnSHA256Digest; -var - Context: TCnSHA256Context; -begin - SHA256Init(Context); - SHA256Update(Context, PAnsiChar(@Data[0]), Length(Data)); - SHA256Final(Context, Result); -end; - -// ֽ SHA384 -function SHA384Bytes(Data: TBytes): TCnSHA384Digest; -var - Context: TCnSHA384Context; -begin - SHA384Init(Context); - SHA384Update(Context, PAnsiChar(@Data[0]), Length(Data)); - SHA384Final(Context, Result); -end; - -// ֽ SHA512 -function SHA512Bytes(Data: TBytes): TCnSHA512Digest; -var - Context: TCnSHA512Context; -begin - SHA512Init(Context); - SHA512Update(Context, PAnsiChar(@Data[0]), Length(Data)); - SHA512Final(Context, Result); -end; - -// String ݽ SHA224 -function SHA224String(const Str: string): TCnSHA224Digest; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := SHA224StringA(AStr); -end; - -// String ݽ SHA256 -function SHA256String(const Str: string): TCnSHA256Digest; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := SHA256StringA(AStr); -end; - -// String ݽ SHA384 -function SHA384String(const Str: string): TCnSHA384Digest; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := SHA384StringA(AStr); -end; - -// String ݽ SHA512 -function SHA512String(const Str: string): TCnSHA512Digest; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := SHA512StringA(AStr); -end; - -// UnicodeString ݽֱӵ SHA224 㣬ת -{$IFDEF UNICODE} -function SHA224UnicodeString(const Str: string): TCnSHA224Digest; -{$ELSE} -function SHA224UnicodeString(const Str: WideString): TCnSHA224Digest; -{$ENDIF} -var - Context: TCnSHA224Context; -begin - SHA224Init(Context); - SHA224Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - SHA224Final(Context, Result); -end; - -// UnicodeString ݽֱӵ SHA256 㣬ת -{$IFDEF UNICODE} -function SHA256UnicodeString(const Str: string): TCnSHA256Digest; -{$ELSE} -function SHA256UnicodeString(const Str: WideString): TCnSHA256Digest; -{$ENDIF} -var - Context: TCnSHA256Context; -begin - SHA256Init(Context); - SHA256Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - SHA256Final(Context, Result); -end; - -// UnicodeString ݽֱӵ SHA384 㣬ת -{$IFDEF UNICODE} -function SHA384UnicodeString(const Str: string): TCnSHA384Digest; -{$ELSE} -function SHA384UnicodeString(const Str: WideString): TCnSHA384Digest; -{$ENDIF} -var - Context: TCnSHA384Context; -begin - SHA384Init(Context); - SHA384Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - SHA384Final(Context, Result); -end; - -// UnicodeString ݽֱӵ SHA512 㣬ת -{$IFDEF UNICODE} -function SHA512UnicodeString(const Str: string): TCnSHA512Digest; -{$ELSE} -function SHA512UnicodeString(const Str: WideString): TCnSHA512Digest; -{$ENDIF} -var - Context: TCnSHA512Context; -begin - SHA512Init(Context); - SHA512Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - SHA512Final(Context, Result); -end; - -// AnsiString ݽ SHA224 -function SHA224StringA(const Str: AnsiString): TCnSHA224Digest; -var - Context: TCnSHA224Context; -begin - SHA224Init(Context); - SHA224Update(Context, PAnsiChar(Str), Length(Str)); - SHA224Final(Context, Result); -end; - -// WideString ݽ SHA224 -function SHA224StringW(const Str: WideString): TCnSHA224Digest; -var - Context: TCnSHA224Context; -begin - SHA224Init(Context); - SHA224UpdateW(Context, PWideChar(Str), Length(Str)); - SHA224Final(Context, Result); -end; - -// AnsiString ݽ SHA256 -function SHA256StringA(const Str: AnsiString): TCnSHA256Digest; -var - Context: TCnSHA256Context; -begin - SHA256Init(Context); - SHA256Update(Context, PAnsiChar(Str), Length(Str)); - SHA256Final(Context, Result); -end; - -// WideString ݽ SHA256 -function SHA256StringW(const Str: WideString): TCnSHA256Digest; -var - Context: TCnSHA256Context; -begin - SHA256Init(Context); - SHA256UpdateW(Context, PWideChar(Str), Length(Str)); - SHA256Final(Context, Result); -end; - -// AnsiString ݽ SHA384 -function SHA384StringA(const Str: AnsiString): TCnSHA384Digest; -var - Context: TCnSHA384Context; -begin - SHA384Init(Context); - SHA384Update(Context, PAnsiChar(Str), Length(Str)); - SHA384Final(Context, Result); -end; - -// WideString ݽ SHA384 -function SHA384StringW(const Str: WideString): TCnSHA384Digest; -var - Context: TCnSHA384Context; -begin - SHA384Init(Context); - SHA384UpdateW(Context, PWideChar(Str), Length(Str)); - SHA384Final(Context, Result); -end; - -// AnsiString ݽ SHA512 -function SHA512StringA(const Str: AnsiString): TCnSHA512Digest; -var - Context: TCnSHA512Context; -begin - SHA512Init(Context); - SHA512Update(Context, PAnsiChar(Str), Length(Str)); - SHA512Final(Context, Result); -end; - -// WideString ݽ SHA512 -function SHA512StringW(const Str: WideString): TCnSHA512Digest; -var - Context: TCnSHA512Context; -begin - SHA512Init(Context); - SHA512UpdateW(Context, PWideChar(Str), Length(Str)); - SHA512Final(Context, Result); -end; - -function InternalSHAStream(Stream: TStream; const BufSize: Cardinal; var D: - TCnSHAGeneralDigest; SHA2Type: TSHA2Type; CallBack: TCnSHACalcProgressFunc = nil): Boolean; -var - Buf: PAnsiChar; - BufLen: Cardinal; - Size: Int64; - ReadBytes: Cardinal; - TotalBytes: Int64; - SavePos: Int64; - CancelCalc: Boolean; - - Context224: TCnSHA224Context; - Context256: TCnSHA256Context; - Context384: TCnSHA384Context; - Context512: TCnSHA512Context; - Dig224: TCnSHA224Digest; - Dig256: TCnSHA256Digest; - Dig384: TCnSHA384Digest; - Dig512: TCnSHA512Digest; - - procedure _SHAInit; - begin - case SHA2Type of - stSHA2_224: - SHA224Init(Context224); - stSHA2_256: - SHA256Init(Context256); - stSHA2_384: - SHA384Init(Context384); - stSHA2_512: - SHA512Init(Context512); - end; - end; - - procedure _SHAUpdate; - begin - case SHA2Type of - stSHA2_224: - SHA224Update(Context224, Buf, ReadBytes); - stSHA2_256: - SHA256Update(Context256, Buf, ReadBytes); - stSHA2_384: - SHA384Update(Context384, Buf, ReadBytes); - stSHA2_512: - SHA512Update(Context512, Buf, ReadBytes); - end; - end; - - procedure _SHAFinal; - begin - case SHA2Type of - stSHA2_224: - SHA224Final(Context224, Dig224); - stSHA2_256: - SHA256Final(Context256, Dig256); - stSHA2_384: - SHA384Final(Context384, Dig384); - stSHA2_512: - SHA512Final(Context512, Dig512); - end; - end; - - procedure _CopyResult; - begin - case SHA2Type of - stSHA2_224: - Move(Dig224[0], D[0], SizeOf(TCnSHA224Digest)); - stSHA2_256: - Move(Dig256[0], D[0], SizeOf(TCnSHA256Digest)); - stSHA2_384: - Move(Dig384[0], D[0], SizeOf(TCnSHA384Digest)); - stSHA2_512: - Move(Dig512[0], D[0], SizeOf(TCnSHA512Digest)); - end; - end; - -begin - Result := False; - Size := Stream.Size; - SavePos := Stream.Position; - TotalBytes := 0; - if Size = 0 then - Exit; - if Size < BufSize then - BufLen := Size - else - BufLen := BufSize; - - CancelCalc := False; - _SHAInit; - - GetMem(Buf, BufLen); - try - Stream.Position := 0; - repeat - ReadBytes := Stream.Read(Buf^, BufLen); - if ReadBytes <> 0 then - begin - Inc(TotalBytes, ReadBytes); - _SHAUpdate; - - if Assigned(CallBack) then - begin - CallBack(Size, TotalBytes, CancelCalc); - if CancelCalc then - Exit; - end; - end; - until (ReadBytes = 0) or (TotalBytes = Size); - _SHAFinal; - _CopyResult; - Result := True; - finally - FreeMem(Buf, BufLen); - Stream.Position := SavePos; - end; -end; - -// ָ SHA224 -function SHA224Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): - TCnSHA224Digest; -var - Dig: TCnSHAGeneralDigest; -begin - InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_224, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA224Digest)); -end; - -// ָ SHA256 -function SHA256Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): - TCnSHA256Digest; -var - Dig: TCnSHAGeneralDigest; -begin - InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_256, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA256Digest)); -end; - -// ָ SHA384 -function SHA384Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): - TCnSHA384Digest; -var - Dig: TCnSHAGeneralDigest; -begin - InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_384, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA384Digest)); -end; - -// ָ SHA512 -function SHA512Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): - TCnSHA512Digest; -var - Dig: TCnSHAGeneralDigest; -begin - InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_512, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA512Digest)); -end; - -function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; -{$IFDEF MSWINDOWS} -var - H: THandle; - Info: BY_HANDLE_FILE_INFORMATION; - Rec: Int64Rec; -{$ENDIF} - begin -{$IFDEF MSWINDOWS} - Result := False; - IsEmpty := False; - H := CreateFile(PChar(AFileName), GENERIC_READ, FILE_SHARE_READ, nil, - OPEN_EXISTING, 0, 0); - if H = INVALID_HANDLE_VALUE then - Exit; - try - if not GetFileInformationByHandle(H, Info) then - Exit; - finally - CloseHandle(H); - end; - Rec.Lo := Info.nFileSizeLow; - Rec.Hi := Info.nFileSizeHigh; - Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); - IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); -{$ELSE} - Result := True; // Windows ƽ̨ Trueʾ Mapping -{$ENDIF} -end; - -function InternalSHAFile(const FileName: string; SHA2Type: TSHA2Type; - CallBack: TCnSHACalcProgressFunc): TCnSHAGeneralDigest; -var - Context224: TCnSHA224Context; - Context256: TCnSHA256Context; - Context384: TCnSHA384Context; - Context512: TCnSHA512Context; - Dig224: TCnSHA224Digest; - Dig256: TCnSHA256Digest; - Dig384: TCnSHA384Digest; - Dig512: TCnSHA512Digest; - -{$IFDEF MSWINDOWS} - FileHandle: THandle; - MapHandle: THandle; - ViewPointer: Pointer; -{$ENDIF} - Stream: TStream; - FileIsZeroSize: Boolean; - - procedure _SHAInit; - begin - case SHA2Type of - stSHA2_224: - SHA224Init(Context224); - stSHA2_256: - SHA256Init(Context256); - stSHA2_384: - SHA384Init(Context384); - stSHA2_512: - SHA512Init(Context512); - end; - end; - -{$IFDEF MSWINDOWS} - procedure _SHAUpdate; - begin - case SHA2Type of - stSHA2_224: - SHA224Update(Context224, ViewPointer, GetFileSize(FileHandle, nil)); - stSHA2_256: - SHA256Update(Context256, ViewPointer, GetFileSize(FileHandle, nil)); - stSHA2_384: - SHA384Update(Context384, ViewPointer, GetFileSize(FileHandle, nil)); - stSHA2_512: - SHA512Update(Context512, ViewPointer, GetFileSize(FileHandle, nil)); - end; - end; -{$ENDIF} - - procedure _SHAFinal; - begin - case SHA2Type of - stSHA2_224: - SHA224Final(Context224, Dig224); - stSHA2_256: - SHA256Final(Context256, Dig256); - stSHA2_384: - SHA384Final(Context384, Dig384); - stSHA2_512: - SHA512Final(Context512, Dig512); - end; - end; - - procedure _CopyResult(var D: TCnSHAGeneralDigest); - begin - case SHA2Type of - stSHA2_224: - Move(Dig224[0], D[0], SizeOf(TCnSHA224Digest)); - stSHA2_256: - Move(Dig256[0], D[0], SizeOf(TCnSHA256Digest)); - stSHA2_384: - Move(Dig384[0], D[0], SizeOf(TCnSHA384Digest)); - stSHA2_512: - Move(Dig512[0], D[0], SizeOf(TCnSHA512Digest)); - end; - end; - -begin - FileIsZeroSize := False; - if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then - begin - // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ - Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try - InternalSHAStream(Stream, 4096 * 1024, Result, SHA2Type, CallBack); - finally - Stream.Free; - end; - end - else - begin -{$IFDEF MSWINDOWS} - _SHAInit; - FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or - FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or - FILE_FLAG_SEQUENTIAL_SCAN, 0); - if FileHandle <> INVALID_HANDLE_VALUE then - begin - try - MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); - if MapHandle <> 0 then - begin - try - ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); - if ViewPointer <> nil then - begin - try - _SHAUpdate; - finally - UnmapViewOfFile(ViewPointer); - end; - end - else - begin - raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); - end; - finally - CloseHandle(MapHandle); - end; - end - else - begin - if not FileIsZeroSize then - raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); - end; - finally - CloseHandle(FileHandle); - end; - end; - _SHAFinal; - _CopyResult(Result); -{$ENDIF} - end; -end; - -// ָļݽ SHA224 -function SHA224File(const FileName: string; CallBack: TCnSHACalcProgressFunc): - TCnSHA224Digest; -var - Dig: TCnSHAGeneralDigest; -begin - Dig := InternalSHAFile(FileName, stSHA2_224, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA224Digest)); -end; - -// ָļݽ SHA256 -function SHA256File(const FileName: string; CallBack: TCnSHACalcProgressFunc): - TCnSHA256Digest; -var - Dig: TCnSHAGeneralDigest; -begin - Dig := InternalSHAFile(FileName, stSHA2_256, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA256Digest)); -end; - -// ָļݽ SHA384 -function SHA384File(const FileName: string; CallBack: TCnSHACalcProgressFunc): - TCnSHA384Digest; -var - Dig: TCnSHAGeneralDigest; -begin - Dig := InternalSHAFile(FileName, stSHA2_384, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA384Digest)); -end; - -// ָļݽ SHA512 -function SHA512File(const FileName: string; CallBack: TCnSHACalcProgressFunc): - TCnSHA512Digest; -var - Dig: TCnSHAGeneralDigest; -begin - Dig := InternalSHAFile(FileName, stSHA2_512, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA512Digest)); -end; - -// ʮƸʽ SHA224 Ӵֵ -function SHA224Print(const Digest: TCnSHA224Digest): string; -begin - Result := DataToHex(@Digest[0], SizeOf(TCnSHA224Digest)); -end; - -// ʮƸʽ SHA256 Ӵֵ -function SHA256Print(const Digest: TCnSHA256Digest): string; -begin - Result := DataToHex(@Digest[0], SizeOf(TCnSHA256Digest)); -end; - -// ʮƸʽ SHA384 Ӵֵ -function SHA384Print(const Digest: TCnSHA384Digest): string; -begin - Result := DataToHex(@Digest[0], SizeOf(TCnSHA384Digest)); -end; - -// ʮƸʽ SHA512 Ӵֵ -function SHA512Print(const Digest: TCnSHA512Digest): string; -begin - Result := DataToHex(@Digest[0], SizeOf(TCnSHA512Digest)); -end; - -// Ƚ SHA224 ӴֵǷ -function SHA224Match(const D1, D2: TCnSHA224Digest): Boolean; -var - I: Integer; -begin - I := 0; - Result := True; - while Result and (I < 28) do - begin - Result := D1[I] = D2[I]; - Inc(I); - end; -end; - -// Ƚ SHA256 ӴֵǷ -function SHA256Match(const D1, D2: TCnSHA256Digest): Boolean; -var - I: Integer; -begin - I := 0; - Result := True; - while Result and (I < 32) do - begin - Result := D1[I] = D2[I]; - Inc(I); - end; -end; - -// Ƚ SHA384 ӴֵǷ -function SHA384Match(const D1, D2: TCnSHA384Digest): Boolean; -var - I: Integer; -begin - I := 0; - Result := True; - while Result and (I < 48) do - begin - Result := D1[I] = D2[I]; - Inc(I); - end; -end; - -// Ƚ SHA512 ӴֵǷ -function SHA512Match(const D1, D2: TCnSHA512Digest): Boolean; -var - I: Integer; -begin - I := 0; - Result := True; - while Result and (I < 64) do - begin - Result := D1[I] = D2[I]; - Inc(I); - end; -end; - -// SHA224 Ӵֵת string -function SHA224DigestToStr(const Digest: TCnSHA224Digest): string; -begin - Result := MemoryToString(@Digest[0], SizeOf(TCnSHA224Digest)); -end; - -// SHA256 Ӵֵת string -function SHA256DigestToStr(const Digest: TCnSHA256Digest): string; -begin - Result := MemoryToString(@Digest[0], SizeOf(TCnSHA256Digest)); -end; - -// SHA384 Ӵֵת string -function SHA384DigestToStr(const Digest: TCnSHA384Digest): string; -begin - Result := MemoryToString(@Digest[0], SizeOf(TCnSHA384Digest)); -end; - -// SHA512 Ӵֵת string -function SHA512DigestToStr(const Digest: TCnSHA512Digest): string; -begin - Result := MemoryToString(@Digest[0], SizeOf(TCnSHA512Digest)); -end; - -procedure SHA224HmacInit(var Context: TCnSHA224Context; Key: PAnsiChar; KeyLength: Integer); -var - I: Integer; - Sum: TCnSHA224Digest; -begin - if KeyLength > HMAC_SHA2_224_256_BLOCK_SIZE_BYTE then - begin - Sum := SHA224Buffer(Key, KeyLength); - KeyLength := HMAC_SHA2_224_OUTPUT_LENGTH_BYTE; - Key := @(Sum[0]); - end; - - FillChar(Context.Ipad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $36); - FillChar(Context.Opad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $5C); - - for I := 0 to KeyLength - 1 do - begin - Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); - Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); - end; - - SHA224Init(Context); - SHA224Update(Context, @(Context.Ipad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); -end; - -procedure SHA224HmacUpdate(var Context: TCnSHA224Context; Input: PAnsiChar; Length: - Cardinal); -begin - SHA224Update(Context, Input, Length); -end; - -procedure SHA224HmacFinal(var Context: TCnSHA224Context; var Output: TCnSHA224Digest); -var - Len: Integer; - TmpBuf: TCnSHA224Digest; -begin - Len := HMAC_SHA2_224_OUTPUT_LENGTH_BYTE; - SHA224Final(Context, TmpBuf); - SHA224Init(Context); - SHA224Update(Context, @(Context.Opad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); - SHA224Update(Context, @(TmpBuf[0]), Len); - SHA224Final(Context, Output); -end; - -procedure SHA256HmacInit(var Context: TCnSHA256Context; Key: PAnsiChar; KeyLength: Integer); -var - I: Integer; - Sum: TCnSHA256Digest; -begin - if KeyLength > HMAC_SHA2_224_256_BLOCK_SIZE_BYTE then - begin - Sum := SHA256Buffer(Key, KeyLength); - KeyLength := HMAC_SHA2_256_OUTPUT_LENGTH_BYTE; - Key := @(Sum[0]); - end; - - FillChar(Context.Ipad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $36); - FillChar(Context.Opad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $5C); - - for I := 0 to KeyLength - 1 do - begin - Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); - Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); - end; - - SHA256Init(Context); - SHA256Update(Context, @(Context.Ipad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); -end; - -procedure SHA256HmacUpdate(var Context: TCnSHA256Context; Input: PAnsiChar; Length: - Cardinal); -begin - SHA256Update(Context, Input, Length); -end; - -procedure SHA256HmacFinal(var Context: TCnSHA256Context; var Output: TCnSHA256Digest); -var - Len: Integer; - TmpBuf: TCnSHA256Digest; -begin - Len := HMAC_SHA2_256_OUTPUT_LENGTH_BYTE; - SHA256Final(Context, TmpBuf); - SHA256Init(Context); - SHA256Update(Context, @(Context.Opad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); - SHA256Update(Context, @(TmpBuf[0]), Len); - SHA256Final(Context, Output); -end; - -procedure SHA224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA224Digest); -var - Context: TCnSHA224Context; -begin - SHA224HmacInit(Context, Key, KeyByteLength); - SHA224HmacUpdate(Context, Input, ByteLength); - SHA224HmacFinal(Context, Output); -end; - -procedure SHA256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA256Digest); -var - Context: TCnSHA256Context; -begin - SHA256HmacInit(Context, Key, KeyByteLength); - SHA256HmacUpdate(Context, Input, ByteLength); - SHA256HmacFinal(Context, Output); -end; - -procedure SHA384HmacInit(var Context: TCnSHA384Context; Key: PAnsiChar; KeyLength: Integer); -var - I: Integer; - Sum: TCnSHA384Digest; -begin - if KeyLength > HMAC_SHA2_384_512_BLOCK_SIZE_BYTE then - begin - Sum := SHA384Buffer(Key, KeyLength); - KeyLength := HMAC_SHA2_384_OUTPUT_LENGTH_BYTE; - Key := @(Sum[0]); - end; - - FillChar(Context.Ipad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $36); - FillChar(Context.Opad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $5C); - - for I := 0 to KeyLength - 1 do - begin - Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); - Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); - end; - - SHA384Init(Context); - SHA384Update(Context, @(Context.Ipad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); -end; - -procedure SHA384HmacUpdate(var Context: TCnSHA384Context; Input: PAnsiChar; - Length: Cardinal); -begin - SHA384Update(Context, Input, Length); -end; - -procedure SHA384HmacFinal(var Context: TCnSHA384Context; var Output: TCnSHA384Digest); -var - Len: Integer; - TmpBuf: TCnSHA384Digest; -begin - Len := HMAC_SHA2_384_OUTPUT_LENGTH_BYTE; - SHA384Final(Context, TmpBuf); - SHA384Init(Context); - SHA384Update(Context, @(Context.Opad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); - SHA384Update(Context, @(TmpBuf[0]), Len); - SHA384Final(Context, Output); -end; - -procedure SHA384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA384Digest); -var - Context: TCnSHA384Context; -begin - SHA384HmacInit(Context, Key, KeyByteLength); - SHA384HmacUpdate(Context, Input, ByteLength); - SHA384HmacFinal(Context, Output); -end; - -procedure SHA512HmacInit(var Context: TCnSHA512Context; Key: PAnsiChar; KeyLength: Integer); -var - I: Integer; - Sum: TCnSHA512Digest; -begin - if KeyLength > HMAC_SHA2_384_512_BLOCK_SIZE_BYTE then - begin - Sum := SHA512Buffer(Key, KeyLength); - KeyLength := HMAC_SHA2_512_OUTPUT_LENGTH_BYTE; - Key := @(Sum[0]); - end; - - FillChar(Context.Ipad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $36); - FillChar(Context.Opad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $5C); - - for I := 0 to KeyLength - 1 do - begin - Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); - Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); - end; - - SHA512Init(Context); - SHA512Update(Context, @(Context.Ipad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); -end; - -procedure SHA512HmacUpdate(var Context: TCnSHA512Context; Input: PAnsiChar; - Length: Cardinal); -begin - SHA512Update(Context, Input, Length); -end; - -procedure SHA512HmacFinal(var Context: TCnSHA512Context; var Output: TCnSHA512Digest); -var - Len: Integer; - TmpBuf: TCnSHA512Digest; -begin - Len := HMAC_SHA2_512_OUTPUT_LENGTH_BYTE; - SHA512Final(Context, TmpBuf); - SHA512Init(Context); - SHA512Update(Context, @(Context.Opad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); - SHA512Update(Context, @(TmpBuf[0]), Len); - SHA512Final(Context, Output); -end; - -procedure SHA512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA512Digest); -var - Context: TCnSHA512Context; -begin - SHA512HmacInit(Context, Key, KeyByteLength); - SHA512HmacUpdate(Context, Input, ByteLength); - SHA512HmacFinal(Context, Output); -end; - -end. +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnSHA2; +{* |
+================================================================================
+* ƣ
+* ԪƣSHA2 Ӵ㷨ʵֵԪ
+* ԪߣCnPack  (master@cnpack.org)
+*           / C  Pascal ֲ䲿ֹܡ
+*     עԪʵ SHA2 ϵӴ㷨Ӧ HMAC 㷨 SHA224/256/384/512
+*           עDelphi 5/6/7 Ԫз Int64 ޷ UInt64  SHA512/384
+*           ԭǻڲ޷ļӼλԼƵȶͬΨһ
+*           ͬDZȽϣԪûƵıȽϡ
+* ƽ̨PWinXP + Delphi 5.0
+* ݲԣPWinXP/7 + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2022.04.26 V1.4
+*               ޸ LongWord  Integer ַת֧ MacOS64
+*           2019.04.15 V1.3
+*               ֧ Win32/Win64/MacOS32
+*           2017.10.31 V1.2
+*                SHA512/384 HMAC 
+*           2016.09.30 V1.1
+*               ʵ SHA512/384D567з Int64 ޷ UInt64
+*           2016.09.27 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, CnNative, CnConsts; + +type + PCnSHAGeneralDigest = ^TCnSHAGeneralDigest; + TCnSHAGeneralDigest = array[0..63] of Byte; + + PCnSHA224Digest = ^TCnSHA224Digest; + TCnSHA224Digest = array[0..27] of Byte; + {* SHA224 Ӵս28 ֽ} + + PCnSHA256Digest = ^TCnSHA256Digest; + TCnSHA256Digest = array[0..31] of Byte; + {* SHA256 Ӵս32 ֽ} + + PCnSHA384Digest = ^TCnSHA384Digest; + TCnSHA384Digest = array[0..47] of Byte; + {* SHA384 Ӵս48 ֽ} + + PCnSHA512Digest = ^TCnSHA512Digest; + TCnSHA512Digest = array[0..63] of Byte; + {* SHA512 Ӵս64 ֽ} + + TCnSHA256Context = packed record + {* SHA256 Ľṹ} + DataLen: Cardinal; + Data: array[0..63] of Byte; + BitLen: Int64; + State: array[0..7] of Cardinal; + Ipad: array[0..63] of Byte; {!< HMAC: inner padding } + Opad: array[0..63] of Byte; {!< HMAC: outer padding } + end; + + TCnSHA224Context = TCnSHA256Context; + {* SHA224 Ľṹ} + + TCnSHA512Context = packed record + {* SHA512 Ľṹ} + DataLen: Cardinal; + Data: array[0..127] of Byte; + TotalLen: Int64; + State: array[0..7] of Int64; + Ipad: array[0..127] of Byte; {!< HMAC: inner padding } + Opad: array[0..127] of Byte; {!< HMAC: outer padding } + end; + + TCnSHA384Context = TCnSHA512Context; + {* SHA512 Ľṹ} + + TCnSHACalcProgressFunc = procedure(ATotal, AProgress: Int64; var Cancel: + Boolean) of object; + {* SHA2 ϵӴսȻص¼} + +function SHA224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA224Digest; +{* ݿ SHA224 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA256Digest; +{* ݿ SHA256 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA384Digest; +{* ݿ SHA384 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA512Digest; +{* ݿ SHA512 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA224Buffer(const Buffer; Count: Cardinal): TCnSHA224Digest; +{* ݿ SHA224 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256Buffer(const Buffer; Count: Cardinal): TCnSHA256Digest; +{* ݿ SHA256 㡣 + + + const Buffer - ݿַ + Count: Cardinal - + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384Buffer(const Buffer; Count: Cardinal): TCnSHA384Digest; +{* ݿ SHA384 㡣 + + + const Buffer - ݿַ + Count: Cardinal - + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512Buffer(const Buffer; Count: Cardinal): TCnSHA512Digest; +{* ݿ SHA512 㡣 + + + const Buffer - ݿַ + Count: Cardinal - + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA224Bytes(Data: TBytes): TCnSHA224Digest; +{* ֽ SHA224 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256Bytes(Data: TBytes): TCnSHA256Digest; +{* ֽ SHA256 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384Bytes(Data: TBytes): TCnSHA384Digest; +{* ֽ SHA384 㡣 + + Data: TBytes - ֽ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512Bytes(Data: TBytes): TCnSHA512Digest; +{* ֽ SHA512 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA224String(const Str: string): TCnSHA224Digest; +{* String ݽ SHA224 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256String(const Str: string): TCnSHA256Digest; +{* String ݽ SHA256 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384String(const Str: string): TCnSHA384Digest; +{* String ݽ SHA384 㣬ע D2009ϰ汾string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512String(const Str: string): TCnSHA512Digest; +{* String ݽ SHA512 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + + +function SHA224StringA(const Str: AnsiString): TCnSHA224Digest; +{* AnsiString ݽ SHA224 㡣 + + + const Str: AnsiString - + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA224StringW(const Str: WideString): TCnSHA224Digest; +{* WideString ݽ SHA224 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256StringA(const Str: AnsiString): TCnSHA256Digest; +{* AnsiString ݽ SHA256 㡣 + + + const Str: AnsiString - + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA256StringW(const Str: WideString): TCnSHA256Digest; +{* WideString ݽ SHA256 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384StringA(const Str: AnsiString): TCnSHA384Digest; +{* AnsiString ݽ SHA384 㡣 + + + const Str: AnsiString - + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA384StringW(const Str: WideString): TCnSHA384Digest; +{* WideString ݽ SHA384 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512StringA(const Str: AnsiString): TCnSHA512Digest; +{* AnsiString ݽ SHA512 㡣 + + + const Str: AnsiString - + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA512StringW(const Str: WideString): TCnSHA512Digest; +{* WideString ݽ SHA512 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +{$IFDEF UNICODE} + +function SHA224UnicodeString(const Str: string): TCnSHA224Digest; +{* UnicodeString ݽֱӵ SHA224 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256UnicodeString(const Str: string): TCnSHA256Digest; +{* UnicodeString ݽֱӵ SHA256 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384UnicodeString(const Str: string): TCnSHA384Digest; +{* UnicodeString ݽֱӵ SHA384 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512UnicodeString(const Str: string): TCnSHA512Digest; +{* UnicodeString ݽֱӵ SHA512 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +{$ELSE} + +function SHA224UnicodeString(const Str: WideString): TCnSHA224Digest; +{* UnicodeString ݽֱӵ SHA224 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256UnicodeString(const Str: WideString): TCnSHA256Digest; +{* UnicodeString ݽֱӵ SHA256 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384UnicodeString(const Str: WideString): TCnSHA384Digest; +{* UnicodeString ݽֱӵ SHA384 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512UnicodeString(const Str: WideString): TCnSHA512Digest; +{* UnicodeString ݽֱӵ SHA512 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +{$ENDIF} + +function SHA224File(const FileName: string; CallBack: TCnSHACalcProgressFunc = + nil): TCnSHA224Digest; +{* ָļݽ SHA256 㡣 + + + const FileName: string - ļ + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA224Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA224Digest; +{* ָݽ SHA224 㡣 + + + Stream: TStream - + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256File(const FileName: string; CallBack: TCnSHACalcProgressFunc = + nil): TCnSHA256Digest; +{* ָļݽ SHA256 㡣 + + + const FileName: string - ļ + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA256Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA256Digest; +{* ָݽ SHA256 㡣 + + + Stream: TStream - + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384File(const FileName: string; CallBack: TCnSHACalcProgressFunc = + nil): TCnSHA384Digest; +{* ָļݽ SHA384 㡣 + + + const FileName: string - ļ + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA384Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA384Digest; +{* ָݽ SHA384 㡣 + + + Stream: TStream - + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512File(const FileName: string; CallBack: TCnSHACalcProgressFunc = + nil): TCnSHA512Digest; +{* ָļݽ SHA512 㡣 + + + const FileName: string - ļ + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA512Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA512Digest; +{* ָݽ SHA512 㡣 + + + Stream: TStream - + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +// ⲿݽɢ SHA224 㣬SHA224Update ɶα + +procedure SHA224Init(var Context: TCnSHA224Context); +{* ʼһ SHA224 ģ׼ SHA224 + + + var Context: TCnSHA224Context - ʼ SHA224 + + ֵޣ +} + +procedure SHA224Update(var Context: TCnSHA224Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA224 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA224Context - SHA224 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA224Final(var Context: TCnSHA224Context; var Digest: TCnSHA224Digest); +{* ּ㣬 SHA224 Digest С + + + var Context: TCnSHA224Context - SHA224 + var Digest: TCnSHA224Digest - ص SHA224 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA256 㣬SHA256Update ɶα + +procedure SHA256Init(var Context: TCnSHA256Context); +{* ʼһ SHA256 ģ׼ SHA256 + + + var Context: TCnSHA256Context - ʼ SHA256 + + ֵޣ +} + +procedure SHA256Update(var Context: TCnSHA256Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA256 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA256Context - SHA256 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA256Final(var Context: TCnSHA256Context; var Digest: TCnSHA256Digest); +{* ּ㣬 SHA256 Digest С + + + var Context: TCnSHA256Context - SHA256 + var Digest: TCnSHA256Digest - ص SHA256 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA384 㣬SHA384Update ɶα + +procedure SHA384Init(var Context: TCnSHA384Context); +{* ʼһ SHA384 ģ׼ SHA384 + + + var Context: TCnSHA384Context - ʼ SHA384 + + ֵޣ +} + +procedure SHA384Update(var Context: TCnSHA384Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA384 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA384Context - SHA384 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA384Final(var Context: TCnSHA384Context; var Digest: TCnSHA384Digest); +{* ּ㣬 SHA384 Digest С + + + var Context: TCnSHA384Context - SHA384 + var Digest: TCnSHA384Digest - ص SHA384 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA512 㣬SHA512Update ɶα + +procedure SHA512Init(var Context: TCnSHA512Context); +{* ʼһ SHA512 ģ׼ SHA512 + + + var Context: TCnSHA512Context - ʼ SHA512 + + ֵޣ +} + +procedure SHA512Update(var Context: TCnSHA512Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA512 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA512Context - SHA512 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA512Final(var Context: TCnSHA512Context; var Digest: TCnSHA512Digest); +{* ּ㣬 SHA512 Digest + + + var Context: TCnSHA512Context - SHA512 + var Digest: TCnSHA512Digest - ص SHA512 Ӵֵ + + ֵޣ +} + +function SHA224Print(const Digest: TCnSHA224Digest): string; +{* ʮƸʽ SHA224 Ӵֵ + + + const Digest: TCnSHA224Digest - ָ SHA224 Ӵֵ + + ֵstring - ʮַ +} + +function SHA256Print(const Digest: TCnSHA256Digest): string; +{* ʮƸʽ SHA256 Ӵֵ + + + const Digest: TCnSHA256Digest - ָ SHA256 Ӵֵ + + ֵstring - ʮַ +} + +function SHA384Print(const Digest: TCnSHA384Digest): string; +{* ʮƸʽ SHA384 Ӵֵ + + + const Digest: TCnSHA384Digest - ָ SHA384 Ӵֵ + + ֵstring - ʮַ +} + +function SHA512Print(const Digest: TCnSHA512Digest): string; +{* ʮƸʽ SHA512 Ӵֵ + + + const Digest: TCnSHA512Digest - ָ SHA512 Ӵֵ + + ֵstring - ʮַ +} + +function SHA224Match(const D1: TCnSHA224Digest; const D2: TCnSHA224Digest): Boolean; +{* Ƚ SHA224 ӴֵǷȡ + + + const D1: TCnSHA224Digest - Ƚϵ SHA224 Ӵֵһ + const D2: TCnSHA224Digest - Ƚϵ SHA224 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA256Match(const D1: TCnSHA256Digest; const D2: TCnSHA256Digest): Boolean; +{* Ƚ SHA256 ӴֵǷȡ + + + const D1: TCnSHA256Digest - Ƚϵ SHA256 Ӵֵһ + const D2: TCnSHA256Digest - Ƚϵ SHA256 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA384Match(const D1: TCnSHA384Digest; const D2: TCnSHA384Digest): Boolean; +{* Ƚ SHA384 ӴֵǷȡ + + + const D1: TCnSHA384Digest - Ƚϵ SHA384 Ӵֵһ + const D2: TCnSHA384Digest - Ƚϵ SHA384 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA512Match(const D1: TCnSHA512Digest; const D2: TCnSHA512Digest): Boolean; +{* Ƚ SHA512 ӴֵǷȡ + + + const D1: TCnSHA512Digest - Ƚϵ SHA512 Ӵֵһ + const D2: TCnSHA512Digest - Ƚϵ SHA512 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA224DigestToStr(const Digest: TCnSHA224Digest): string; +{* SHA224 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA224Digest - ת SHA224 Ӵֵ + + ֵstring - صַ +} + +function SHA256DigestToStr(const Digest: TCnSHA256Digest): string; +{* SHA256 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA256Digest - ת SHA256 Ӵֵ + + ֵstring - صַ +} + +function SHA384DigestToStr(const Digest: TCnSHA384Digest): string; +{* SHA384 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA384Digest - ת SHA384 Ӵֵ + + ֵstring - صַ +} + +function SHA512DigestToStr(const Digest: TCnSHA512Digest): string; +{* SHA512 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA512Digest - ת SHA512 Ӵֵ + + ֵstring - صַ +} + +procedure SHA224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA224Digest); +{* SHA224 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA224 Կݿַ + KeyByteLength: Integer - SHA224 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA224Digest - ص SHA224 Ӵֵ + + ֵޣ +} + +procedure SHA256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA256Digest); +{* SHA256 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA256 Կݿַ + KeyByteLength: Integer - SHA256 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA256Digest - ص SHA256 Ӵֵ + + ֵޣ +} + +procedure SHA384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA384Digest); +{* SHA384 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA384 Կݿַ + KeyByteLength: Integer - SHA384 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA384Digest - ص SHA384 Ӵֵ + + ֵޣ +} + +procedure SHA512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA512Digest); +{* SHA512 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA512 Կݿַ + KeyByteLength: Integer - SHA512 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA512Digest - ص SHA512 Ӵֵ + + ֵޣ +} + +implementation + +const + HMAC_SHA2_224_256_BLOCK_SIZE_BYTE = 64; + HMAC_SHA2_384_512_BLOCK_SIZE_BYTE = 128; + + HMAC_SHA2_224_OUTPUT_LENGTH_BYTE = 28; + HMAC_SHA2_256_OUTPUT_LENGTH_BYTE = 32; + HMAC_SHA2_384_OUTPUT_LENGTH_BYTE = 48; + HMAC_SHA2_512_OUTPUT_LENGTH_BYTE = 64; + +type + TSHA2Type = (stSHA2_224, stSHA2_256, stSHA2_384, stSHA2_512); + +const + MAX_FILE_SIZE = 512 * 1024 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + KEYS256: array[0..63] of Cardinal = ($428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, + $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5, $D807AA98, $12835B01, $243185BE, + $550C7DC3, $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, $E49B69C1, $EFBE4786, + $0FC19DC6, $240CA1CC, $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA, $983E5152, + $A831C66D, $B00327C8, $BF597FC7, $C6E00BF3, $D5A79147, $06CA6351, $14292967, + $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, $650A7354, $766A0ABB, $81C2C92E, + $92722C85, $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, $D192E819, $D6990624, + $F40E3585, $106AA070, $19A4C116, $1E376C08, $2748774C, $34B0BCB5, $391C0CB3, + $4ED8AA4A, $5B9CCA4F, $682E6FF3, $748F82EE, $78A5636F, $84C87814, $8CC70208, + $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2); + + KEYS512: array[0..79] of TUInt64 = ($428A2F98D728AE22, $7137449123EF65CD, + $B5C0FBCFEC4D3B2F, $E9B5DBA58189DBBC, $3956C25BF348B538, $59F111F1B605D019, + $923F82A4AF194F9B, $AB1C5ED5DA6D8118, $D807AA98A3030242, $12835B0145706FBE, + $243185BE4EE4B28C, $550C7DC3D5FFB4E2, $72BE5D74F27B896F, $80DEB1FE3B1696B1, + $9BDC06A725C71235, $C19BF174CF692694, $E49B69C19EF14AD2, $EFBE4786384F25E3, + $0FC19DC68B8CD5B5, $240CA1CC77AC9C65, $2DE92C6F592B0275, $4A7484AA6EA6E483, + $5CB0A9DCBD41FBD4, $76F988DA831153B5, $983E5152EE66DFAB, $A831C66D2DB43210, + $B00327C898FB213F, $BF597FC7BEEF0EE4, $C6E00BF33DA88FC2, $D5A79147930AA725, + $06CA6351E003826F, $142929670A0E6E70, $27B70A8546D22FFC, $2E1B21385C26C926, + $4D2C6DFC5AC42AED, $53380D139D95B3DF, $650A73548BAF63DE, $766A0ABB3C77B2A8, + $81C2C92E47EDAEE6, $92722C851482353B, $A2BFE8A14CF10364, $A81A664BBC423001, + $C24B8B70D0F89791, $C76C51A30654BE30, $D192E819D6EF5218, $D69906245565A910, + $F40E35855771202A, $106AA07032BBD1B8, $19A4C116B8D2D0C8, $1E376C085141AB53, + $2748774CDF8EEB99, $34B0BCB5E19B48A8, $391C0CB3C5C95A63, $4ED8AA4AE3418ACB, + $5B9CCA4F7763E373, $682E6FF3D6B2B8A3, $748F82EE5DEFB2FC, $78A5636F43172F60, + $84C87814A1F0AB72, $8CC702081A6439EC, $90BEFFFA23631E28, $A4506CEBDE82BDE9, + $BEF9A3F7B2C67915, $C67178F2E372532B, $CA273ECEEA26619C, $D186B8C721C0C207, + $EADA7DD6CDE0EB1E, $F57D4F7FEE6ED178, $06F067AA72176FBA, $0A637DC5A2C898A6, + $113F9804BEF90DAE, $1B710B35131C471B, $28DB77F523047D84, $32CAAB7B40C72493, + $3C9EBE0A15C9BEBC, $431D67C49C100D4C, $4CC5D4BECB3E42B6, $597F299CFC657E2A, + $5FCB6FAB3AD6FAEC, $6C44198C4A475817); + +function ROTRight256(A, B: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (A shr B) or (A shl (32 - B)); +end; + +function ROTRight512(X: TUInt64; Y: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X shr Y) or (X shl (64 - Y)); +end; + +function SHR512(X: TUInt64; Y: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and $FFFFFFFFFFFFFFFF) shr Y; +end; + +function CH256(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and Y) xor ((not X) and Z); +end; + +function CH512(X, Y, Z: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (((Y xor Z) and X) xor Z); +end; + +function MAJ256(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and Y) xor (X and Z) xor (Y and Z); +end; + +function MAJ512(X, Y, Z: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ((X or Y) and Z) or (X and Y); +end; + +function EP0256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight256(X, 2) xor ROTRight256(X, 13) xor ROTRight256(X, 22); +end; + +function EP1256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight256(X, 6) xor ROTRight256(X, 11) xor ROTRight256(X, 25); +end; + +function SIG0256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight256(X, 7) xor ROTRight256(X, 18) xor (X shr 3); +end; + +function SIG1256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight256(X, 17) xor ROTRight256(X, 19) xor (X shr 10); +end; + +function SIG0512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight512(X, 28) xor ROTRight512(X, 34) xor ROTRight512(X, 39); +end; + +function SIG1512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight512(X, 14) xor ROTRight512(X, 18) xor ROTRight512(X, 41); +end; + +function Gamma0512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight512(X, 1) xor ROTRight512(X, 8) xor SHR512(X, 7); +end; + +function Gamma1512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight512(X, 19) xor ROTRight512(X, 61) xor SHR512(X, 6); +end; + +procedure SHA256Transform(var Context: TCnSHA256Context; Data: PAnsiChar); +var + A, B, C, D, E, F, G, H, T1, T2: Cardinal; + M: array[0..63] of Cardinal; + I, J: Integer; +begin + I := 0; + J := 0; + while I < 16 do + begin + M[I] := (Cardinal(Data[J]) shl 24) or (Cardinal(Data[J + 1]) shl 16) or (Cardinal(Data + [J + 2]) shl 8) or Cardinal(Data[J + 3]); + Inc(I); + Inc(J, 4); + end; + + while I < 64 do + begin + M[I] := SIG1256(M[I - 2]) + M[I - 7] + SIG0256(M[I - 15]) + M[I - 16]; + Inc(I); + end; + + A := Context.State[0]; + B := Context.State[1]; + C := Context.State[2]; + D := Context.State[3]; + E := Context.State[4]; + F := Context.State[5]; + G := Context.State[6]; + H := Context.State[7]; + + I := 0; + while I < 64 do + begin + T1 := H + EP1256(E) + CH256(E, F, G) + KEYS256[I] + M[I]; + T2 := EP0256(A) + MAJ256(A, B, C); + H := G; + G := F; + F := E; + E := D + T1; + D := C; + C := B; + B := A; + A := T1 + T2; + Inc(I); + end; + + Context.State[0] := Context.State[0] + A; + Context.State[1] := Context.State[1] + B; + Context.State[2] := Context.State[2] + C; + Context.State[3] := Context.State[3] + D; + Context.State[4] := Context.State[4] + E; + Context.State[5] := Context.State[5] + F; + Context.State[6] := Context.State[6] + G; + Context.State[7] := Context.State[7] + H; +end; + +{$WARNINGS OFF} + +procedure SHA512Transform(var Context: TCnSHA512Context; Data: PAnsiChar; BlockCount: Integer); +var + A, B, C, D, E, F, G, H, T1, T2: TUInt64; + M: array[0..79] of TUInt64; + I, J, K: Integer; + OrigData: PAnsiChar; +begin + OrigData := Data; + for K := 0 to BlockCount - 1 do + begin + Data := PAnsiChar(TCnNativeInt(OrigData) + (K shl 7)); + + I := 0; + J := 0; + while I < 16 do + begin + M[I] := (TUInt64(Data[J]) shl 56) or (TUInt64(Data[J + 1]) shl 48) or + (TUInt64(Data[J + 2]) shl 40) or (TUInt64(Data[J + 3]) shl 32) or + (TUInt64(Data[J + 4]) shl 24) or (TUInt64(Data[J + 5]) shl 16) or + (TUInt64(Data[J + 6]) shl 8) or TUInt64(Data[J + 7]); + Inc(I); + Inc(J, 8); + end; + + while I < 80 do + begin + M[I] := Gamma1512(M[I - 2]) + M[I - 7] + Gamma0512(M[I - 15]) + M[I - 16]; + Inc(I); + end; + + A := Context.State[0]; + B := Context.State[1]; + C := Context.State[2]; + D := Context.State[3]; + E := Context.State[4]; + F := Context.State[5]; + G := Context.State[6]; + H := Context.State[7]; + + I := 0; + while I < 80 do + begin + T1 := H + SIG1512(E) + CH512(E, F, G) + KEYS512[I] + M[I]; + T2 := SIG0512(A) + MAJ512(A, B, C); + H := G; + G := F; + F := E; + E := D + T1; + D := C; + C := B; + B := A; + A := T1 + T2; + Inc(I); + end; + + // з޷ WarningӰ + Context.State[0] := Context.State[0] + A; + Context.State[1] := Context.State[1] + B; + Context.State[2] := Context.State[2] + C; + Context.State[3] := Context.State[3] + D; + Context.State[4] := Context.State[4] + E; + Context.State[5] := Context.State[5] + F; + Context.State[6] := Context.State[6] + G; + Context.State[7] := Context.State[7] + H; + end; +end; + +{$WARNINGS ON} + +procedure SHA224Init(var Context: TCnSHA224Context); +begin + Context.DataLen := 0; + Context.BitLen := 0; + Context.State[0] := $C1059ED8; + Context.State[1] := $367CD507; + Context.State[2] := $3070DD17; + Context.State[3] := $F70E5939; + Context.State[4] := $FFC00B31; + Context.State[5] := $68581511; + Context.State[6] := $64F98FA7; + Context.State[7] := $BEFA4FA4; + FillChar(Context.Data, SizeOf(Context.Data), 0); +end; + +procedure SHA224Update(var Context: TCnSHA224Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA256Update(Context, Input, ByteLength); +end; + +procedure SHA256UpdateW(var Context: TCnSHA256Context; Input: PWideChar; CharLength: Cardinal); forward; + +procedure SHA224UpdateW(var Context: TCnSHA224Context; Input: PWideChar; CharLength: Cardinal); +begin + SHA256UpdateW(Context, Input, CharLength); +end; + +procedure SHA224Final(var Context: TCnSHA224Context; var Digest: TCnSHA224Digest); +var + Dig: TCnSHA256Digest; +begin + SHA256Final(Context, Dig); + Move(Dig[0], Digest[0], SizeOf(TCnSHA224Digest)); +end; + +procedure SHA256Init(var Context: TCnSHA256Context); +begin + Context.DataLen := 0; + Context.BitLen := 0; + Context.State[0] := $6A09E667; + Context.State[1] := $BB67AE85; + Context.State[2] := $3C6EF372; + Context.State[3] := $A54FF53A; + Context.State[4] := $510E527F; + Context.State[5] := $9B05688C; + Context.State[6] := $1F83D9AB; + Context.State[7] := $5BE0CD19; + FillChar(Context.Data, SizeOf(Context.Data), 0); +end; + +procedure SHA256Update(var Context: TCnSHA256Context; Input: PAnsiChar; ByteLength: Cardinal); +var + I: Integer; +begin + for I := 0 to ByteLength - 1 do + begin + Context.Data[Context.DataLen] := Byte(Input[I]); + Inc(Context.DataLen); + if Context.DataLen = 64 then + begin + SHA256Transform(Context, @Context.Data[0]); + Context.BitLen := Context.BitLen + 512; + Context.DataLen := 0; + end; + end; +end; + +procedure SHA256UpdateW(var Context: TCnSHA256Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + Content: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(Content, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(Content), CharLength * SizeOf(WideChar), nil, nil); + SHA256Update(Context, Content, iLen); + finally + FreeMem(Content); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SHA256Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +procedure SHA256Final(var Context: TCnSHA256Context; var Digest: TCnSHA256Digest); +var + I: Integer; +begin + I := Context.DataLen; + Context.Data[I] := $80; + Inc(I); + + if Context.Datalen < 56 then + begin + while I < 56 do + begin + Context.Data[I] := 0; + Inc(I); + end; + end + else + begin + while I < 64 do + begin + Context.Data[I] := 0; + Inc(I); + end; + + SHA256Transform(Context, @(Context.Data[0])); + FillChar(Context.Data, 56, 0); + end; + + Context.BitLen := Context.BitLen + Context.DataLen * 8; + Context.Data[63] := Context.Bitlen; + Context.Data[62] := Context.Bitlen shr 8; + Context.Data[61] := Context.Bitlen shr 16; + Context.Data[60] := Context.Bitlen shr 24; + Context.Data[59] := Context.Bitlen shr 32; + Context.Data[58] := Context.Bitlen shr 40; + Context.Data[57] := Context.Bitlen shr 48; + Context.Data[56] := Context.Bitlen shr 56; + SHA256Transform(Context, @(Context.Data[0])); + + for I := 0 to 3 do + begin + Digest[I] := (Context.State[0] shr (24 - I * 8)) and $000000FF; + Digest[I + 4] := (Context.State[1] shr (24 - I * 8)) and $000000FF; + Digest[I + 8] := (Context.State[2] shr (24 - I * 8)) and $000000FF; + Digest[I + 12] := (Context.State[3] shr (24 - I * 8)) and $000000FF; + Digest[I + 16] := (Context.State[4] shr (24 - I * 8)) and $000000FF; + Digest[I + 20] := (Context.State[5] shr (24 - I * 8)) and $000000FF; + Digest[I + 24] := (Context.State[6] shr (24 - I * 8)) and $000000FF; + Digest[I + 28] := (Context.State[7] shr (24 - I * 8)) and $000000FF; + end; +end; + +{$WARNINGS OFF} + +procedure SHA384Init(var Context: TCnSHA384Context); +begin + Context.DataLen := 0; + Context.TotalLen := 0; + Context.State[0] := $CBBB9D5DC1059ED8; + Context.State[1] := $629A292A367CD507; + Context.State[2] := $9159015A3070DD17; + Context.State[3] := $152FECD8F70E5939; + Context.State[4] := $67332667FFC00B31; + Context.State[5] := $8EB44A8768581511; + Context.State[6] := $DB0C2E0D64F98FA7; + Context.State[7] := $47B5481DBEFA4FA4; + FillChar(Context.Data, SizeOf(Context.Data), 0); +end; + +{$WARNINGS ON} + +procedure SHA384Update(var Context: TCnSHA384Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA512Update(Context, Input, ByteLength); +end; + +procedure SHA512UpdateW(var Context: TCnSHA512Context; Input: PWideChar; CharLength: Cardinal); forward; + +procedure SHA384UpdateW(var Context: TCnSHA384Context; Input: PWideChar; CharLength: Cardinal); +begin + SHA512UpdateW(Context, Input, CharLength); +end; + +procedure SHA384Final(var Context: TCnSHA384Context; var Digest: TCnSHA384Digest); +var + Dig: TCnSHA512Digest; +begin + SHA512Final(Context, Dig); + Move(Dig[0], Digest[0], SizeOf(TCnSHA384Digest)); +end; + +{$WARNINGS OFF} + +procedure SHA512Init(var Context: TCnSHA512Context); +begin + Context.DataLen := 0; + Context.TotalLen := 0; + Context.State[0] := $6A09E667F3BCC908; + Context.State[1] := $BB67AE8584CAA73B; + Context.State[2] := $3C6EF372FE94F82B; + Context.State[3] := $A54FF53A5F1D36F1; + Context.State[4] := $510E527FADE682D1; + Context.State[5] := $9B05688C2B3E6C1F; + Context.State[6] := $1F83D9ABFB41BD6B; + Context.State[7] := $5BE0CD19137E2179; + FillChar(Context.Data, SizeOf(Context.Data), 0); +end; + +{$WARNINGS ON} + +procedure SHA512Update(var Context: TCnSHA512Context; Input: PAnsiChar; ByteLength: Cardinal); +var + TempLength, RemainLength, NewLength, BlockCount: Cardinal; +begin + TempLength := 128 - Context.DataLen; + if ByteLength < TempLength then + RemainLength := ByteLength + else + RemainLength := TempLength; + + Move(Input^, Context.Data[Context.DataLen], RemainLength); + if Context.DataLen + ByteLength < 128 then + begin + Inc(Context.DataLen, ByteLength); + Exit; + end; + + NewLength := Cardinal(ByteLength) - RemainLength; + BlockCount := NewLength div 128; + Input := PAnsiChar(TCnNativeUInt(Input) + RemainLength); + + SHA512Transform(Context, @Context.Data[0], 1); + SHA512Transform(Context, Input, BlockCount); + + RemainLength := NewLength mod 128; + Input := PAnsiChar(TCnNativeUInt(Input) + (BlockCount shl 7)); + Move(Input^, Context.Data[Context.DataLen], RemainLength); + + Context.DataLen := RemainLength; + Inc(Context.TotalLen, (BlockCount + 1) shl 7); +end; + +procedure SHA512UpdateW(var Context: TCnSHA512Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + Content: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(Content, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(Content), CharLength * SizeOf(WideChar), nil, nil); + SHA512Update(Context, Content, iLen); + finally + FreeMem(Content); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SHA512Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +procedure SHA512Final(var Context: TCnSHA512Context; var Digest: TCnSHA512Digest); +var + I: Integer; + BlockCount, BitLength, PmLength: Cardinal; +begin + if (Context.DataLen mod 128) > 111 then + BlockCount := 2 + else + BlockCount := 1; + + BitLength := (Context.TotalLen + Context.DataLen) shl 3; + PmLength := BlockCount shl 7; + FillChar(Context.Data[Context.DataLen], PmLength - Context.DataLen, 0); + Context.Data[Context.DataLen] := $80; + + Context.Data[PmLength - 1] := Byte(BitLength); + Context.Data[PmLength - 2] := Byte(BitLength shr 8); + Context.Data[PmLength - 3] := Byte(BitLength shr 16); + Context.Data[PmLength - 4] := Byte(BitLength shr 24); + + SHA512Transform(Context, @(Context.Data[0]), BlockCount); + + for I := 0 to 7 do + begin + Digest[I] := (Context.State[0] shr (56 - I * 8)) and $000000FF; + Digest[I + 8] := (Context.State[1] shr (56 - I * 8)) and $000000FF; + Digest[I + 16] := (Context.State[2] shr (56 - I * 8)) and $000000FF; + Digest[I + 24] := (Context.State[3] shr (56 - I * 8)) and $000000FF; + Digest[I + 32] := (Context.State[4] shr (56 - I * 8)) and $000000FF; + Digest[I + 40] := (Context.State[5] shr (56 - I * 8)) and $000000FF; + Digest[I + 48] := (Context.State[6] shr (56 - I * 8)) and $000000FF; + Digest[I + 56] := (Context.State[7] shr (56 - I * 8)) and $000000FF; + end; +end; + +// ݿ SHA224 +function SHA224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, Input, ByteLength); + SHA224Final(Context, Result); +end; + +// ݿ SHA256 +function SHA256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, Input, ByteLength); + SHA256Final(Context, Result); +end; + +// ݿ SHA384 +function SHA384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, Input, ByteLength); + SHA384Final(Context, Result); +end; + +// ݿ SHA512 +function SHA512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, Input, ByteLength); + SHA512Final(Context, Result); +end; + +// ݿ SHA224 +function SHA224Buffer(const Buffer; Count: Cardinal): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, PAnsiChar(Buffer), Count); + SHA224Final(Context, Result); +end; + +// ݿ SHA256 +function SHA256Buffer(const Buffer; Count: Cardinal): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, PAnsiChar(Buffer), Count); + SHA256Final(Context, Result); +end; + +// ݿ SHA384 +function SHA384Buffer(const Buffer; Count: Cardinal): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, PAnsiChar(Buffer), Count); + SHA384Final(Context, Result); +end; + +// ݿ SHA512 +function SHA512Buffer(const Buffer; Count: Cardinal): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, PAnsiChar(Buffer), Count); + SHA512Final(Context, Result); +end; + +// ֽ SHA224 +function SHA224Bytes(Data: TBytes): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA224Final(Context, Result); +end; + +// ֽ SHA256 +function SHA256Bytes(Data: TBytes): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA256Final(Context, Result); +end; + +// ֽ SHA384 +function SHA384Bytes(Data: TBytes): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA384Final(Context, Result); +end; + +// ֽ SHA512 +function SHA512Bytes(Data: TBytes): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA512Final(Context, Result); +end; + +// String ݽ SHA224 +function SHA224String(const Str: string): TCnSHA224Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA224StringA(AStr); +end; + +// String ݽ SHA256 +function SHA256String(const Str: string): TCnSHA256Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA256StringA(AStr); +end; + +// String ݽ SHA384 +function SHA384String(const Str: string): TCnSHA384Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA384StringA(AStr); +end; + +// String ݽ SHA512 +function SHA512String(const Str: string): TCnSHA512Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA512StringA(AStr); +end; + +// UnicodeString ݽֱӵ SHA224 㣬ת +{$IFDEF UNICODE} +function SHA224UnicodeString(const Str: string): TCnSHA224Digest; +{$ELSE} +function SHA224UnicodeString(const Str: WideString): TCnSHA224Digest; +{$ENDIF} +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA224Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SHA256 㣬ת +{$IFDEF UNICODE} +function SHA256UnicodeString(const Str: string): TCnSHA256Digest; +{$ELSE} +function SHA256UnicodeString(const Str: WideString): TCnSHA256Digest; +{$ENDIF} +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA256Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SHA384 㣬ת +{$IFDEF UNICODE} +function SHA384UnicodeString(const Str: string): TCnSHA384Digest; +{$ELSE} +function SHA384UnicodeString(const Str: WideString): TCnSHA384Digest; +{$ENDIF} +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA384Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SHA512 㣬ת +{$IFDEF UNICODE} +function SHA512UnicodeString(const Str: string): TCnSHA512Digest; +{$ELSE} +function SHA512UnicodeString(const Str: WideString): TCnSHA512Digest; +{$ENDIF} +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA512Final(Context, Result); +end; + +// AnsiString ݽ SHA224 +function SHA224StringA(const Str: AnsiString): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, PAnsiChar(Str), Length(Str)); + SHA224Final(Context, Result); +end; + +// WideString ݽ SHA224 +function SHA224StringW(const Str: WideString): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224UpdateW(Context, PWideChar(Str), Length(Str)); + SHA224Final(Context, Result); +end; + +// AnsiString ݽ SHA256 +function SHA256StringA(const Str: AnsiString): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, PAnsiChar(Str), Length(Str)); + SHA256Final(Context, Result); +end; + +// WideString ݽ SHA256 +function SHA256StringW(const Str: WideString): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256UpdateW(Context, PWideChar(Str), Length(Str)); + SHA256Final(Context, Result); +end; + +// AnsiString ݽ SHA384 +function SHA384StringA(const Str: AnsiString): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, PAnsiChar(Str), Length(Str)); + SHA384Final(Context, Result); +end; + +// WideString ݽ SHA384 +function SHA384StringW(const Str: WideString): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384UpdateW(Context, PWideChar(Str), Length(Str)); + SHA384Final(Context, Result); +end; + +// AnsiString ݽ SHA512 +function SHA512StringA(const Str: AnsiString): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, PAnsiChar(Str), Length(Str)); + SHA512Final(Context, Result); +end; + +// WideString ݽ SHA512 +function SHA512StringW(const Str: WideString): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512UpdateW(Context, PWideChar(Str), Length(Str)); + SHA512Final(Context, Result); +end; + +function InternalSHAStream(Stream: TStream; const BufSize: Cardinal; var D: + TCnSHAGeneralDigest; SHA2Type: TSHA2Type; CallBack: TCnSHACalcProgressFunc = nil): Boolean; +var + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; + + Context224: TCnSHA224Context; + Context256: TCnSHA256Context; + Context384: TCnSHA384Context; + Context512: TCnSHA512Context; + Dig224: TCnSHA224Digest; + Dig256: TCnSHA256Digest; + Dig384: TCnSHA384Digest; + Dig512: TCnSHA512Digest; + + procedure _SHAInit; + begin + case SHA2Type of + stSHA2_224: + SHA224Init(Context224); + stSHA2_256: + SHA256Init(Context256); + stSHA2_384: + SHA384Init(Context384); + stSHA2_512: + SHA512Init(Context512); + end; + end; + + procedure _SHAUpdate; + begin + case SHA2Type of + stSHA2_224: + SHA224Update(Context224, Buf, ReadBytes); + stSHA2_256: + SHA256Update(Context256, Buf, ReadBytes); + stSHA2_384: + SHA384Update(Context384, Buf, ReadBytes); + stSHA2_512: + SHA512Update(Context512, Buf, ReadBytes); + end; + end; + + procedure _SHAFinal; + begin + case SHA2Type of + stSHA2_224: + SHA224Final(Context224, Dig224); + stSHA2_256: + SHA256Final(Context256, Dig256); + stSHA2_384: + SHA384Final(Context384, Dig384); + stSHA2_512: + SHA512Final(Context512, Dig512); + end; + end; + + procedure _CopyResult; + begin + case SHA2Type of + stSHA2_224: + Move(Dig224[0], D[0], SizeOf(TCnSHA224Digest)); + stSHA2_256: + Move(Dig256[0], D[0], SizeOf(TCnSHA256Digest)); + stSHA2_384: + Move(Dig384[0], D[0], SizeOf(TCnSHA384Digest)); + stSHA2_512: + Move(Dig512[0], D[0], SizeOf(TCnSHA512Digest)); + end; + end; + +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then + Exit; + if Size < BufSize then + BufLen := Size + else + BufLen := BufSize; + + CancelCalc := False; + _SHAInit; + + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + _SHAUpdate; + + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then + Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + _SHAFinal; + _CopyResult; + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ָ SHA224 +function SHA224Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA224Digest; +var + Dig: TCnSHAGeneralDigest; +begin + InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_224, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA224Digest)); +end; + +// ָ SHA256 +function SHA256Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA256Digest; +var + Dig: TCnSHAGeneralDigest; +begin + InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_256, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA256Digest)); +end; + +// ָ SHA384 +function SHA384Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA384Digest; +var + Dig: TCnSHAGeneralDigest; +begin + InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_384, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA384Digest)); +end; + +// ָ SHA512 +function SHA512Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA512Digest; +var + Dig: TCnSHAGeneralDigest; +begin + InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_512, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA512Digest)); +end; + +function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} +var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec: Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(AFileName), GENERIC_READ, FILE_SHARE_READ, nil, + OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then + Exit; + try + if not GetFileInformationByHandle(H, Info) then + Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} +end; + +function InternalSHAFile(const FileName: string; SHA2Type: TSHA2Type; + CallBack: TCnSHACalcProgressFunc): TCnSHAGeneralDigest; +var + Context224: TCnSHA224Context; + Context256: TCnSHA256Context; + Context384: TCnSHA384Context; + Context512: TCnSHA512Context; + Dig224: TCnSHA224Digest; + Dig256: TCnSHA256Digest; + Dig384: TCnSHA384Digest; + Dig512: TCnSHA512Digest; + +{$IFDEF MSWINDOWS} + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; + + procedure _SHAInit; + begin + case SHA2Type of + stSHA2_224: + SHA224Init(Context224); + stSHA2_256: + SHA256Init(Context256); + stSHA2_384: + SHA384Init(Context384); + stSHA2_512: + SHA512Init(Context512); + end; + end; + +{$IFDEF MSWINDOWS} + procedure _SHAUpdate; + begin + case SHA2Type of + stSHA2_224: + SHA224Update(Context224, ViewPointer, GetFileSize(FileHandle, nil)); + stSHA2_256: + SHA256Update(Context256, ViewPointer, GetFileSize(FileHandle, nil)); + stSHA2_384: + SHA384Update(Context384, ViewPointer, GetFileSize(FileHandle, nil)); + stSHA2_512: + SHA512Update(Context512, ViewPointer, GetFileSize(FileHandle, nil)); + end; + end; +{$ENDIF} + + procedure _SHAFinal; + begin + case SHA2Type of + stSHA2_224: + SHA224Final(Context224, Dig224); + stSHA2_256: + SHA256Final(Context256, Dig256); + stSHA2_384: + SHA384Final(Context384, Dig384); + stSHA2_512: + SHA512Final(Context512, Dig512); + end; + end; + + procedure _CopyResult(var D: TCnSHAGeneralDigest); + begin + case SHA2Type of + stSHA2_224: + Move(Dig224[0], D[0], SizeOf(TCnSHA224Digest)); + stSHA2_256: + Move(Dig256[0], D[0], SizeOf(TCnSHA256Digest)); + stSHA2_384: + Move(Dig384[0], D[0], SizeOf(TCnSHA384Digest)); + stSHA2_512: + Move(Dig512[0], D[0], SizeOf(TCnSHA512Digest)); + end; + end; + +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSHAStream(Stream, 4096 * 1024, Result, SHA2Type, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + _SHAInit; + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + _SHAUpdate; + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + _SHAFinal; + _CopyResult(Result); +{$ENDIF} + end; +end; + +// ָļݽ SHA224 +function SHA224File(const FileName: string; CallBack: TCnSHACalcProgressFunc): + TCnSHA224Digest; +var + Dig: TCnSHAGeneralDigest; +begin + Dig := InternalSHAFile(FileName, stSHA2_224, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA224Digest)); +end; + +// ָļݽ SHA256 +function SHA256File(const FileName: string; CallBack: TCnSHACalcProgressFunc): + TCnSHA256Digest; +var + Dig: TCnSHAGeneralDigest; +begin + Dig := InternalSHAFile(FileName, stSHA2_256, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA256Digest)); +end; + +// ָļݽ SHA384 +function SHA384File(const FileName: string; CallBack: TCnSHACalcProgressFunc): + TCnSHA384Digest; +var + Dig: TCnSHAGeneralDigest; +begin + Dig := InternalSHAFile(FileName, stSHA2_384, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA384Digest)); +end; + +// ָļݽ SHA512 +function SHA512File(const FileName: string; CallBack: TCnSHACalcProgressFunc): + TCnSHA512Digest; +var + Dig: TCnSHAGeneralDigest; +begin + Dig := InternalSHAFile(FileName, stSHA2_512, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA512Digest)); +end; + +// ʮƸʽ SHA224 Ӵֵ +function SHA224Print(const Digest: TCnSHA224Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA224Digest)); +end; + +// ʮƸʽ SHA256 Ӵֵ +function SHA256Print(const Digest: TCnSHA256Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA256Digest)); +end; + +// ʮƸʽ SHA384 Ӵֵ +function SHA384Print(const Digest: TCnSHA384Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA384Digest)); +end; + +// ʮƸʽ SHA512 Ӵֵ +function SHA512Print(const Digest: TCnSHA512Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA512Digest)); +end; + +// Ƚ SHA224 ӴֵǷ +function SHA224Match(const D1, D2: TCnSHA224Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 28) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// Ƚ SHA256 ӴֵǷ +function SHA256Match(const D1, D2: TCnSHA256Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 32) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// Ƚ SHA384 ӴֵǷ +function SHA384Match(const D1, D2: TCnSHA384Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 48) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// Ƚ SHA512 ӴֵǷ +function SHA512Match(const D1, D2: TCnSHA512Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 64) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// SHA224 Ӵֵת string +function SHA224DigestToStr(const Digest: TCnSHA224Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA224Digest)); +end; + +// SHA256 Ӵֵת string +function SHA256DigestToStr(const Digest: TCnSHA256Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA256Digest)); +end; + +// SHA384 Ӵֵת string +function SHA384DigestToStr(const Digest: TCnSHA384Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA384Digest)); +end; + +// SHA512 Ӵֵת string +function SHA512DigestToStr(const Digest: TCnSHA512Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA512Digest)); +end; + +procedure SHA224HmacInit(var Context: TCnSHA224Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA224Digest; +begin + if KeyLength > HMAC_SHA2_224_256_BLOCK_SIZE_BYTE then + begin + Sum := SHA224Buffer(Key, KeyLength); + KeyLength := HMAC_SHA2_224_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA224Init(Context); + SHA224Update(Context, @(Context.Ipad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); +end; + +procedure SHA224HmacUpdate(var Context: TCnSHA224Context; Input: PAnsiChar; Length: + Cardinal); +begin + SHA224Update(Context, Input, Length); +end; + +procedure SHA224HmacFinal(var Context: TCnSHA224Context; var Output: TCnSHA224Digest); +var + Len: Integer; + TmpBuf: TCnSHA224Digest; +begin + Len := HMAC_SHA2_224_OUTPUT_LENGTH_BYTE; + SHA224Final(Context, TmpBuf); + SHA224Init(Context); + SHA224Update(Context, @(Context.Opad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); + SHA224Update(Context, @(TmpBuf[0]), Len); + SHA224Final(Context, Output); +end; + +procedure SHA256HmacInit(var Context: TCnSHA256Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA256Digest; +begin + if KeyLength > HMAC_SHA2_224_256_BLOCK_SIZE_BYTE then + begin + Sum := SHA256Buffer(Key, KeyLength); + KeyLength := HMAC_SHA2_256_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA256Init(Context); + SHA256Update(Context, @(Context.Ipad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); +end; + +procedure SHA256HmacUpdate(var Context: TCnSHA256Context; Input: PAnsiChar; Length: + Cardinal); +begin + SHA256Update(Context, Input, Length); +end; + +procedure SHA256HmacFinal(var Context: TCnSHA256Context; var Output: TCnSHA256Digest); +var + Len: Integer; + TmpBuf: TCnSHA256Digest; +begin + Len := HMAC_SHA2_256_OUTPUT_LENGTH_BYTE; + SHA256Final(Context, TmpBuf); + SHA256Init(Context); + SHA256Update(Context, @(Context.Opad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); + SHA256Update(Context, @(TmpBuf[0]), Len); + SHA256Final(Context, Output); +end; + +procedure SHA224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA224Digest); +var + Context: TCnSHA224Context; +begin + SHA224HmacInit(Context, Key, KeyByteLength); + SHA224HmacUpdate(Context, Input, ByteLength); + SHA224HmacFinal(Context, Output); +end; + +procedure SHA256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA256Digest); +var + Context: TCnSHA256Context; +begin + SHA256HmacInit(Context, Key, KeyByteLength); + SHA256HmacUpdate(Context, Input, ByteLength); + SHA256HmacFinal(Context, Output); +end; + +procedure SHA384HmacInit(var Context: TCnSHA384Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA384Digest; +begin + if KeyLength > HMAC_SHA2_384_512_BLOCK_SIZE_BYTE then + begin + Sum := SHA384Buffer(Key, KeyLength); + KeyLength := HMAC_SHA2_384_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA384Init(Context); + SHA384Update(Context, @(Context.Ipad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); +end; + +procedure SHA384HmacUpdate(var Context: TCnSHA384Context; Input: PAnsiChar; + Length: Cardinal); +begin + SHA384Update(Context, Input, Length); +end; + +procedure SHA384HmacFinal(var Context: TCnSHA384Context; var Output: TCnSHA384Digest); +var + Len: Integer; + TmpBuf: TCnSHA384Digest; +begin + Len := HMAC_SHA2_384_OUTPUT_LENGTH_BYTE; + SHA384Final(Context, TmpBuf); + SHA384Init(Context); + SHA384Update(Context, @(Context.Opad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); + SHA384Update(Context, @(TmpBuf[0]), Len); + SHA384Final(Context, Output); +end; + +procedure SHA384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA384Digest); +var + Context: TCnSHA384Context; +begin + SHA384HmacInit(Context, Key, KeyByteLength); + SHA384HmacUpdate(Context, Input, ByteLength); + SHA384HmacFinal(Context, Output); +end; + +procedure SHA512HmacInit(var Context: TCnSHA512Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA512Digest; +begin + if KeyLength > HMAC_SHA2_384_512_BLOCK_SIZE_BYTE then + begin + Sum := SHA512Buffer(Key, KeyLength); + KeyLength := HMAC_SHA2_512_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA512Init(Context); + SHA512Update(Context, @(Context.Ipad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); +end; + +procedure SHA512HmacUpdate(var Context: TCnSHA512Context; Input: PAnsiChar; + Length: Cardinal); +begin + SHA512Update(Context, Input, Length); +end; + +procedure SHA512HmacFinal(var Context: TCnSHA512Context; var Output: TCnSHA512Digest); +var + Len: Integer; + TmpBuf: TCnSHA512Digest; +begin + Len := HMAC_SHA2_512_OUTPUT_LENGTH_BYTE; + SHA512Final(Context, TmpBuf); + SHA512Init(Context); + SHA512Update(Context, @(Context.Opad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); + SHA512Update(Context, @(TmpBuf[0]), Len); + SHA512Final(Context, Output); +end; + +procedure SHA512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA512Digest); +var + Context: TCnSHA512Context; +begin + SHA512HmacInit(Context, Key, KeyByteLength); + SHA512HmacUpdate(Context, Input, ByteLength); + SHA512HmacFinal(Context, Output); +end; + +end. diff --git a/CnPack/Crypto/CnSHA3.pas b/CnPack/Crypto/CnSHA3.pas index 3e0ade0..95bcf0e 100644 --- a/CnPack/Crypto/CnSHA3.pas +++ b/CnPack/Crypto/CnSHA3.pas @@ -1,2700 +1,2700 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -unit CnSHA3; -{* |
-================================================================================
-* ƣ
-* ԪƣSHA3 Ӵ㷨ʵֵԪ
-* ԪߣCnPack  (master@cnpack.org)
-*           / Keccak C  Pascal ֲ䲿ֹܡ
-*     עԪʵ SHA3 ϵӴ㷨Ӧ HMAC 㷨 SHA3-224/256/384/512
-*           ɱ䳤ժҪ SHAKE128/SHAKE256ȡ
-*           SHA3 淶 NIST.FIPS.202
-*           SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
-*           жⶨ Bit  Byte ת
-*           ֮ Bit ܹ 8 ʱÿ 8  Bit λþһֽڣֽڼ˳򱣳ֲ䡣
-*
-* ƽ̨PWinXP + Delphi 5.0
-* ݲԣPWinXP/7 + Delphi 5/6
-*   õԪеַϱػʽ
-* ޸ļ¼2023.08.02 V1.4
-*                SHAKE128/SHAKE256 Ŀɱ䳤ժҪļ
-*           2022.04.26 V1.3
-*               ޸ LongWord  Integer ַת֧ MacOS64
-*           2019.12.12 V1.2
-*               ֧ TBytes
-*           2019.04.15 V1.1
-*               ֧ Win32/Win64/MacOS
-*           2017.11.10 V1.0
-*               Ԫ
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - SysUtils, Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, CnNative, CnConsts; - -const - CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH = 32; - {* SHAKE128 ĬӴսֽڳ} - - CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH = 64; - {* SHAKE256 ĬӴսֽڳ} - -type - PCnSHA3GeneralDigest = ^TCnSHA3GeneralDigest; - TCnSHA3GeneralDigest = array[0..63] of Byte; - {* SHA3 ϵͨõӴս 64 ֽΪ׼} - - PCnSHA3_224Digest = ^TCnSHA3_224Digest; - TCnSHA3_224Digest = array[0..27] of Byte; - {* SHA3_224 Ӵս28 ֽ} - - PCnSHA3_256Digest = ^TCnSHA3_256Digest; - TCnSHA3_256Digest = array[0..31] of Byte; - {* SHA3_256 Ӵս32 ֽ} - - PCnSHA3_384Digest = ^TCnSHA3_384Digest; - TCnSHA3_384Digest = array[0..47] of Byte; - {* SHA3_384 Ӵս48 ֽ} - - PCnSHA3_512Digest = ^TCnSHA3_512Digest; - TCnSHA3_512Digest = array[0..63] of Byte; - {* SHA3_512 Ӵս64 ֽ} - - TCnSHA3Context = packed record - {* SHA3 ϵͨõĽṹ} - State: array[0..24] of Int64; - Index: Cardinal; - DigestLen: Cardinal; - Round: Cardinal; - BlockLen: Cardinal; - Block: array[0..255] of Byte; - Ipad: array[0..143] of Byte; {!< HMAC: inner padding } - Opad: array[0..143] of Byte; {!< HMAC: outer padding } - end; - - TCnSHA3CalcProgressFunc = procedure(ATotal, AProgress: Int64; var Cancel: - Boolean) of object; - {* SHA3 ϵͨõļȻص¼} - -function SHA3_224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_224Digest; -{* ݿ SHA3_224 㡣 - - - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ -} - -function SHA3_256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_256Digest; -{* ݿ SHA3_256 㡣 - - - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ -} - -function SHA3_384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_384Digest; -{* ݿ SHA3_384 㡣 - - - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ -} - -function SHA3_512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_512Digest; -{* ݿ SHA3_512 㡣 - - - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ -} - -function SHA3_224Buffer(const Buffer; Count: Cardinal): TCnSHA3_224Digest; -{* ݿ SHA3_224 㡣 - - - const Buffer - ݿַ - Count: Cardinal - ݿֽڳ - - ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ -} - -function SHA3_256Buffer(const Buffer; Count: Cardinal): TCnSHA3_256Digest; -{* ݿ SHA3_256 㡣 - - - const Buffer - ݿַ - Count: Cardinal - ݿֽڳ - - ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ -} - -function SHA3_384Buffer(const Buffer; Count: Cardinal): TCnSHA3_384Digest; -{* ݿ SHA3_384 㡣 - - - const Buffer - ݿַ - Count: Cardinal - ݿֽڳ - - ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ -} - -function SHA3_512Buffer(const Buffer; Count: Cardinal): TCnSHA3_512Digest; -{* ݿ SHA3_512 㡣 - - - const Buffer - ݿַ - Count: Cardinal - ݿֽڳ - - ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ -} - -function SHAKE128Buffer(const Buffer; Count: Cardinal; - DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* ݿӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս - - - const Buffer - ݿַ - Count: Cardinal - ݿֽڳ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE128 Ӵֵ -} - -function SHAKE256Buffer(const Buffer; Count: Cardinal; - DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* ݿӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս - - - const Buffer - ݿַ - Count: Cardinal - ݿֽڳ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE256 Ӵֵ -} - -function SHA3_224Bytes(Data: TBytes): TCnSHA3_224Digest; -{* ֽ SHA3_224 㡣 - - - Data: TBytes - ֽ - - ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ -} - -function SHA3_256Bytes(Data: TBytes): TCnSHA3_256Digest; -{* ֽ SHA3_256 㡣 - - - Data: TBytes - ֽ - - ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ -} - -function SHA3_384Bytes(Data: TBytes): TCnSHA3_384Digest; -{* ֽ SHA3_384 㡣 - - - Data: TBytes - ֽ - - ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ -} - -function SHA3_512Bytes(Data: TBytes): TCnSHA3_512Digest; -{* ֽ SHA3_512 㡣 - - - Data: TBytes - ֽ - - ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ -} - -function SHAKE128Bytes(Data: TBytes; DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* ֽӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս - - - Data: TBytes - ֽ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE128 Ӵֵ -} - -function SHAKE256Bytes(Data: TBytes; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* ֽӴճȿɱ SHAKE256 㣬سΪ DigestByteLength ֽΪӴս - - - Data: TBytes - ֽ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE256 Ӵֵ -} - -function SHA3_224String(const Str: string): TCnSHA3_224Digest; -{* String ݽ SHA3_224 㣬ע D2009 ϰ汾 string Ϊ UnicodeString - лὫǿת AnsiString м㡣 - - - const Str: string - ַ - - ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ -} - -function SHA3_256String(const Str: string): TCnSHA3_256Digest; -{* String ݽ SHA3_256 㣬ע D2009 ϰ汾 string Ϊ UnicodeString - лὫǿת AnsiString м㡣 - - - const Str: string - ַ - - ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ -} - -function SHA3_384String(const Str: string): TCnSHA3_384Digest; -{* String ݽ SHA3_384 㣬ע D2009 ϰ汾 string Ϊ UnicodeString - лὫǿת AnsiString м㡣 - - - const Str: string - ַ - - ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ -} - -function SHA3_512String(const Str: string): TCnSHA3_512Digest; -{* String ݽ SHA3_512 㣬ע D2009 ϰ汾 string Ϊ UnicodeString - лὫǿת AnsiString м㡣 - - - const Str: string - ַ - - ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ -} - -function SHAKE128String(const Str: string; DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* String ݽӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս - ע D2009 ϰ汾 string Ϊ UnicodeStringлὫǿת AnsiString м㡣 - - - const Str: string - ַ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE128 Ӵֵ -} - -function SHAKE256String(const Str: string; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* String ݽӴճȿɱ SHAKE256 㣬سΪ DigestByteLength ֽΪӴս - ע D2009 ϰ汾 string Ϊ UnicodeStringлὫǿת AnsiString м㡣 - - - const Str: string - ַ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE256 Ӵֵ -} - -function SHA3_224StringA(const Str: AnsiString): TCnSHA3_224Digest; -{* AnsiString ݽ SHA3_224 㡣 - - - const Str: AnsiString - ַ - - ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ -} - -function SHA3_224StringW(const Str: WideString): TCnSHA3_224Digest; -{* WideString ݽ SHA3_224 㡣 - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - - ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ -} - -function SHA3_256StringA(const Str: AnsiString): TCnSHA3_256Digest; -{* AnsiString ݽ SHA3_256 㡣 - - - const Str: AnsiString - ַ - - ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ -} - -function SHA3_256StringW(const Str: WideString): TCnSHA3_256Digest; -{* WideStringݽ SHA3_256 㡣 - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - - ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ -} - -function SHA3_384StringA(const Str: AnsiString): TCnSHA3_384Digest; -{* AnsiString ݽ SHA3_384 㡣 - - - const Str: AnsiString - ַ - - ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ -} - -function SHA3_384StringW(const Str: WideString): TCnSHA3_384Digest; -{* WideString ݽ SHA3_384 㡣 - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - - ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ -} - -function SHA3_512StringA(const Str: AnsiString): TCnSHA3_512Digest; -{* AnsiString ݽ SHA3_512 㡣 - - - const Str: AnsiString - ַ - - ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ -} - -function SHA3_512StringW(const Str: WideString): TCnSHA3_512Digest; -{* WideString ݽ SHA512 㡣 - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - - ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ -} - -function SHAKE128StringA(const Str: AnsiString; - DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* AnsiString ݽӴճȿɱֱ SHAKE128 㣬 - سΪ DigestByteLength ֽΪӴս - - - const Str: AnsiString - ַ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE128 Ӵֵ -} - -function SHAKE128StringW(const Str: WideString; - DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* WideString ݽӴճȿɱֱ SHAKE128 㣬 - سΪ DigestByteLength ֽΪӴս - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE128 Ӵֵ -} - -function SHAKE256StringA(const Str: AnsiString; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* AnsiString ݽӴճȿɱֱ SHAKE128 㣬 - سΪ DigestByteLength ֽΪӴս - - - const Str: AnsiString - ַ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE256 Ӵֵ -} - -function SHAKE256StringW(const Str: WideString; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* WideString ݽӴճȿɱֱ SHAKE256 㣬 - سΪ DigestByteLength ֽΪӴս - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE256 Ӵֵ -} - -{$IFDEF UNICODE} - -function SHA3_224UnicodeString(const Str: string): TCnSHA3_224Digest; -{* UnicodeString ݽֱӵ SHA3_224 㣬ֱӼڲ UTF16 ݣת - - - const Str: string - Ŀַ - - ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ -} - -function SHA3_256UnicodeString(const Str: string): TCnSHA3_256Digest; -{* UnicodeString ݽֱӵ SHA3_256 㣬ֱӼڲ UTF16 ݣת - - - const Str: string - Ŀַ - - ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ -} - -function SHA3_384UnicodeString(const Str: string): TCnSHA3_384Digest; -{* UnicodeString ݽֱӵ SHA3_384 㣬ֱӼڲ UTF16 ݣת - - - const Str: string - Ŀַ - - ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ -} - -function SHA3_512UnicodeString(const Str: string): TCnSHA3_512Digest; -{* UnicodeString ݽֱӵ SHA3_512 㣬ֱӼڲ UTF16 ݣת - - - const Str: string - Ŀַ - - ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ -} - -function SHAKE128UnicodeString(const Str: string; - DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* UnicodeString ݽӴճȿɱֱ SHAKE128 㣬ֱӼڲ UTF16 ݣת - سΪ DigestByteLength ֽΪӴս - - - const Str: string - Ŀַ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE128 Ӵֵ -} - -function SHAKE256UnicodeString(const Str: string; - DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* UnicodeString ݽӴճȿɱֱ SHAKE256 㣬ֱӼڲ UTF16 ݣת - سΪ DigestByteLength ֽΪӴս - - - const Str: string - Ŀַ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE256 Ӵֵ -} - -{$ELSE} - -function SHA3_224UnicodeString(const Str: WideString): TCnSHA3_224Digest; -{* UnicodeString ݽֱӵ SHA3_224 㣬ֱӼڲ UTF16 ݣת - - - const Str: WideString - Ŀַ - - ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ -} - -function SHA3_256UnicodeString(const Str: WideString): TCnSHA3_256Digest; -{* UnicodeString ݽֱӵ SHA3_256 㣬ֱӼڲ UTF16 ݣת - - - const Str: WideString - Ŀַ - - ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ -} - -function SHA3_384UnicodeString(const Str: WideString): TCnSHA3_384Digest; -{* UnicodeString ݽֱӵ SHA3_384 㣬ֱӼڲ UTF16 ݣת - - - const Str: WideString - Ŀַ - - ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ -} - -function SHA3_512UnicodeString(const Str: WideString): TCnSHA3_512Digest; -{* UnicodeString ݽֱӵ SHA3_512 㣬ֱӼڲ UTF16 ݣת - - - const Str: WideString - Ŀַ - - ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ -} - -function SHAKE128UnicodeString(const Str: WideString; - DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* UnicodeString ݽӴճȿɱֱ SHAKE128 㣬ֱӼڲ UTF16 ݣת - سΪ DigestByteLength ֽΪӴս - - - const Str: WideString - Ŀַ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE128 Ӵֵ -} - -function SHAKE256UnicodeString(const Str: WideString; - DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; -{* UnicodeString ݽӴճȿɱֱ SHAKE256 㣬ֱӼڲ UTF16 ݣת - سΪ DigestByteLength ֽΪӴս - - - const Str: WideString - Ŀַ - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵTBytes - SHAKE256 Ӵֵ -} - -{$ENDIF} - -function SHA3_224File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = - nil): TCnSHA3_224Digest; -{* ָļݽ SHA3_224 㡣 - - - const FileName: string - ļ - CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ - - ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ -} - -function SHA3_224Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): - TCnSHA3_224Digest; -{* ָݽ SHA3_224 㡣 - - - Stream: TStream - - CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ - - ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ -} - -function SHA3_256File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = - nil): TCnSHA3_256Digest; -{* ָļݽ SHA3_256 㡣 - - - const FileName: string - ļ - CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ - - ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ -} - -function SHA3_256Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): - TCnSHA3_256Digest; -{* ָݽ SHA3_256 㡣 - - - Stream: TStream - - CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ - - ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ -} - -function SHA3_384File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = - nil): TCnSHA3_384Digest; -{* ָļݽ SHA3_384 㡣 - - - const FileName: string - ļ - CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ - - ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ -} - -function SHA3_384Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): - TCnSHA3_384Digest; -{* ָݽ SHA3_384 㡣 - - - Stream: TStream - - CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ - - ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ -} - -function SHA3_512File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = - nil): TCnSHA3_512Digest; -{* ָļݽ SHA3_512 㡣 - - - const FileName: string - ļ - CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ - - ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ -} - -function SHA3_512Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): - TCnSHA3_512Digest; -{* ָݽ SHA3_512 㡣 - - - Stream: TStream - - CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ - - ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ -} - -function SHAKE128File(const FileName: string; - DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH; - CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; -{* ָļݽӴճȿɱ SHAKE128 㣬 - سΪ DigestByteLength ֽΪӴս - - - const FileName: string - ļ - DigestByteLength: Cardinal - Ӵսֽڳ - CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ - - ֵTBytes - SHAKE128Ӵֵ -} - -function SHAKE128Stream(Stream: TStream; - DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH; - CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; -{* ָӴճȿɱ SHAKE128 㣬 - سΪ DigestByteLength ֽΪӴս - - - Stream: TStream - - DigestByteLength: Cardinal - Ӵսֽڳ - CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ - - ֵTBytes - SHAKE128 Ӵֵ -} - -function SHAKE256File(const FileName: string; - DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH; - CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; -{* ָļݽӴճȿɱ SHAKE256 㣬 - سΪ DigestByteLength ֽΪӴս - - - const FileName: string - ļ - DigestByteLength: Cardinal - Ӵսֽڳ - CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ - - ֵTBytes - SHAKE256 Ӵֵ -} - -function SHAKE256Stream(Stream: TStream; - DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH; - CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; -{* ָӴճȿɱ SHAKE256 㣬 - سΪ DigestByteLength ֽΪӴս - - - Stream: TStream - - DigestByteLength: Cardinal - Ӵսֽڳ - CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ - - ֵTBytes - SHAKE256 Ӵֵ -} - -// ⲿݽɢ SHA3_224 㣬SHA3_224Update ɶα - -procedure SHA3_224Init(var Context: TCnSHA3Context); -{* ʼһ SHA3_224 ģ׼ SHA3_224 - - - var Context: TCnSHA3Context - ʼͨ SHA3 - - ֵޣ -} - -procedure SHA3_224Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -{* ԳʼĶһݽ SHA3_224 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnSHA3Context - ͨ SHA3 - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵޣ -} - -procedure SHA3_224Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_224Digest); -{* ּ㣬 SHA3_224 Digest С - - - var Context: TCnSHA3Context - ͨ SHA3 - var Digest: TCnSHA3_224Digest - ص SHA3_224 Ӵֵ - - ֵޣ -} - -// ⲿݽɢ SHA3_256 㣬SHA3_256Update ɶα - -procedure SHA3_256Init(var Context: TCnSHA3Context); -{* ʼһ SHA3_256 ģ׼ SHA3_256 - - - var Context: TCnSHA3Context - ʼͨ SHA3 - - ֵޣ -} - -procedure SHA3_256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -{* ԳʼĶһݽ SHA3_256 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnSHA3Context - ͨ SHA3 - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵޣ -} - -procedure SHA3_256Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_256Digest); -{* ּ㣬 SHA3_256 Digest С - - - var Context: TCnSHA3Context - ͨ SHA3 - var Digest: TCnSHA3_256Digest - ص SHA3_256 Ӵֵ - - ֵޣ -} - -// ⲿݽɢ SHA3_384 㣬SHA3_384Update ɶα - -procedure SHA3_384Init(var Context: TCnSHA3Context); -{* ʼһ SHA3_384 ģ׼ SHA3_384 - - - var Context: TCnSHA3Context - ʼͨ SHA3 - - ֵޣ -} - -procedure SHA3_384Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -{* ԳʼĶһݽ SHA3_384 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnSHA3Context - ͨ SHA3 - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵޣ -} - -procedure SHA3_384Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_384Digest); -{* ּ㣬 SHA3_384 Digest С - - - var Context: TCnSHA3Context - ͨ SHA3 - var Digest: TCnSHA3_384Digest - ص SHA3_384 Ӵֵ - - ֵޣ -} - -// ⲿݽɢ SHA3_512 㣬SHA3_512Update ɶα - -procedure SHA3_512Init(var Context: TCnSHA3Context); -{* ʼһ SHA3_512 ģ׼ SHA3_512 - - - var Context: TCnSHA3Context - ʼͨ SHA3 - - ֵޣ -} - -procedure SHA3_512Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -{* ԳʼĶһݽ SHA3_512 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnSHA3Context - ͨ SHA3 - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵޣ -} - -procedure SHA3_512Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_512Digest); -{* ּ㣬 SHA3_512 Digest С - - - var Context: TCnSHA3Context - ͨ SHA3 - var Digest: TCnSHA3_512Digest - ص SHA3_512 Ӵֵ - - ֵޣ -} - -// ⲿݽɢ SHAKE128 㣬SHAKE128Update ɶα - -procedure SHAKE128Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH); -{* ʼһ SHAKE128 ģ׼ SHAKE128 - DigestByteLength ΪӴյֽڳȡ - - - var Context: TCnSHA3Context - ʼͨ SHA3 - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵޣ -} - -procedure SHAKE128Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -{* ԳʼĶһݽ SHAKE128 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnSHA3Context - ͨ SHA3 - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵޣ -} - -procedure SHAKE128Final(var Context: TCnSHA3Context; out Digest: TBytes); -{* ּ㣬 SHAKE128 Digest С - - - var Context: TCnSHA3Context - ͨ SHA3 - out Digest: TBytes - ص SHAKE128 Ӵֵ - - ֵޣ -} - -// ⲿݽɢ SHAKE128 㣬SHAKE128Update ɶα - -procedure SHAKE256Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH); -{* ʼһ SHAKE256 ģ׼ SHAKE256 - DigestByteLength ΪӴյֽڳȡ - - - var Context: TCnSHA3Context - ʼͨ SHA3 - DigestByteLength: Cardinal - Ӵսֽڳ - - ֵޣ -} - -procedure SHAKE256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -{* ԳʼĶһݽ SHAKE256 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnSHA3Context - ͨ SHA3 - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵޣ -} - -procedure SHAKE256Final(var Context: TCnSHA3Context; out Digest: TBytes); -{* ּ㣬 SHAKE256 Digest С - - - var Context: TCnSHA3Context - ͨ SHA3 - out Digest: TBytes - ص SHAKE256 Ӵֵ - - ֵޣ -} - -function SHA3_224Print(const Digest: TCnSHA3_224Digest): string; -{* ʮƸʽ SHA3_224 Ӵֵ - - - const Digest: TCnSHA3_224Digest - ָ SHA3_224 Ӵֵ - - ֵstring - ʮַ -} - -function SHA3_256Print(const Digest: TCnSHA3_256Digest): string; -{* ʮƸʽ SHA3_256 Ӵֵ - - - const Digest: TCnSHA3_256Digest - ָ SHA3_256 Ӵֵ - - ֵstring - ʮַ -} - -function SHA3_384Print(const Digest: TCnSHA3_384Digest): string; -{* ʮƸʽ SHA3_384 Ӵֵ - - const Digest: TCnSHA3_384Digest - ָ SHA3_384 Ӵֵ - - ֵstring - ʮַ -} - -function SHA3_512Print(const Digest: TCnSHA3_512Digest): string; -{* ʮƸʽ SHA3_512 Ӵֵ - - - const Digest: TCnSHA3_512Digest - ָ SHA3_512 Ӵֵ - - ֵstring - ʮַ -} - -function SHAKE128Print(const Digest: TBytes): string; -{* ʮƸʽ SHAKE128 Ӵֵ - - - const Digest: TBytes - ָ SHAKE128 Ӵֵ - - ֵstring - ʮַ -} - -function SHAKE256Print(const Digest: TBytes): string; -{* ʮƸʽ SHAKE256 Ӵֵ - - - const Digest: TBytes - ָ SHAKE128 Ӵֵ - - ֵstring - ʮַ -} - -function SHA3_224Match(const D1: TCnSHA3_224Digest; const D2: TCnSHA3_224Digest): Boolean; -{* Ƚ SHA3_224 ӴֵǷȡ - - - const D1: TCnSHA3_224Digest - Ƚϵ SHA3_224 Ӵֵһ - const D2: TCnSHA3_224Digest - Ƚϵ SHA3_224 Ӵֵ - - ֵBoolean - Ƿ -} - -function SHA3_256Match(const D1: TCnSHA3_256Digest; const D2: TCnSHA3_256Digest): Boolean; -{* Ƚ SHA3_256 ӴֵǷȡ - - - const D1: TCnSHA3_256Digest - Ƚϵ SHA3_256 Ӵֵһ - const D2: TCnSHA3_256Digest - Ƚϵ SHA3_256 Ӵֵ - - ֵBoolean - Ƿ -} - -function SHA3_384Match(const D1: TCnSHA3_384Digest; const D2: TCnSHA3_384Digest): Boolean; -{* Ƚ SHA3_384 ӴֵǷȡ - - - const D1: TCnSHA3_384Digest - Ƚϵ SHA3_384 Ӵֵһ - const D2: TCnSHA3_384Digest - Ƚϵ SHA3_384 Ӵֵ - - ֵBoolean - Ƿ -} - -function SHA3_512Match(const D1: TCnSHA3_512Digest; const D2: TCnSHA3_512Digest): Boolean; -{* Ƚ SHA3_512 ӴֵǷȡ - - - const D1: TCnSHA3_512Digest - Ƚϵ SHA3_512 Ӵֵһ - const D2: TCnSHA3_512Digest - Ƚϵ SHA3_512 Ӵֵ - - ֵBoolean - Ƿ -} - -function SHAKE128Match(const D1: TBytes; const D2: TBytes): Boolean; -{* Ƚ SHAKE128 ӴֵǷȡ - - - const D1: TBytes - Ƚϵ SHAKE128 Ӵֵһ - const D2: TBytes - Ƚϵ SHAKE128 Ӵֵ - - ֵBoolean - Ƿ -} - -function SHAKE256Match(const D1: TBytes; const D2: TBytes): Boolean; -{* Ƚ SHAKE256 ӴֵǷȡ - - - const D1: TBytes - Ƚϵ SHAKE256 Ӵֵһ - const D2: TBytes - Ƚϵ SHAKE256 Ӵֵ - - ֵBoolean - Ƿ -} - -function SHA3_224DigestToStr(const Digest: TCnSHA3_224Digest): string; -{* SHA3_224 Ӵֱֵת stringÿֽڶӦһַ - - - const Digest: TCnSHA3_224Digest - ת SHA3_224 Ӵֵ - - ֵstring - صַ -} - -function SHA3_256DigestToStr(const Digest: TCnSHA3_256Digest): string; -{* SHA3_256 Ӵֱֵת stringÿֽڶӦһַ - |
-   Digest: TSHA3_256Digest   - Ҫ
- |
- - - const Digest: TCnSHA3_256Digest - ת SHA3_256 Ӵֵ - - ֵstring - صַ -} - -function SHA3_384DigestToStr(const Digest: TCnSHA3_384Digest): string; -{* SHA3_384 Ӵֱֵת stringÿֽڶӦһַ - - - const Digest: TCnSHA3_384Digest - ת SHA3_384 Ӵֵ - - ֵstring - صַ -} - -function SHA3_512DigestToStr(const Digest: TCnSHA3_512Digest): string; -{* SHA3_512 Ӵֱֵת stringÿֽڶӦһַ - - - const Digest: TCnSHA3_512Digest - ת SHA3_512 Ӵֵ - - ֵstring - صַ -} - -function SHAKE128DigestToStr(const Digest: TBytes): string; -{* SHAKE128 Ӵֱֵת stringÿֽڶӦһַ - - - const Digest: TBytes - ת SHAKE128 Ӵֵ - - ֵstring - صַ -} - -function SHAKE256DigestToStr(const Digest: TBytes): string; -{* SHAKE256 Ӵֱֵת stringÿֽڶӦһַ - - - const Digest: TBytes - ת SHAKE256 Ӵֵ - - ֵstring - صַ -} - -procedure SHA3_224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA3_224Digest); -{* SHA3_224 HMACHash-based Message Authentication Code㣬 - ͨݵļϼԿĸҲмΡ - - - Key: PAnsiChar - SHA3_224 Կݿַ - KeyByteLength: Integer - SHA3_224 Կݿֽڳ - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - var Output: TCnSHA3_224Digest - ص SHA3_224 Ӵֵ - - ֵޣ -} - -procedure SHA3_256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA3_256Digest); -{* SHA3_256 HMACHash-based Message Authentication Code㣬 - ͨݵļϼԿĸҲмΡ - - - Key: PAnsiChar - SHA3_256 Կݿַ - KeyByteLength: Integer - SHA3_256 Կݿֽڳ - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - var Output: TCnSHA3_256Digest - ص SHA3_256 Ӵֵ - - ֵޣ -} - -procedure SHA3_384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA3_384Digest); -{* SHA3_384 HMACHash-based Message Authentication Code㣬 - ͨݵļϼԿĸҲмΡ - - - Key: PAnsiChar - SHA3_384 Կݿַ - KeyByteLength: Integer - SHA3_384 Կݿֽڳ - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - var Output: TCnSHA3_384Digest - ص SHA3_384 Ӵֵ - - ֵޣ -} - -procedure SHA3_512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA3_512Digest); -{* SHA3_512 HMACHash-based Message Authentication Code㣬 - ͨݵļϼԿĸҲмΡ - - - Key: PAnsiChar - SHA3_512 Կݿַ - KeyByteLength: Integer - SHA3_512 Կݿֽڳ - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - var Output: TCnSHA3_512Digest - ص SHA3_512 Ӵֵ - - ֵޣ -} - -implementation - -type - TSHA3Type = (stSHA3_224, stSHA3_256, stSHA3_384, stSHA3_512, stSHAKE128, stSHAKE256); - -const - MAX_FILE_SIZE = 512 * 1024 * 1024; - STREAM_BUF_SIZE = 4096 * 1024; - // If file size <= this size (bytes), using Mapping, else stream - - SHA3_ROUNDS = 24; - SHA3_STATE_LEN = 25; - - SHA3_224_OUTPUT_LENGTH_BYTE = 28; - SHA3_256_OUTPUT_LENGTH_BYTE = 32; - SHA3_384_OUTPUT_LENGTH_BYTE = 48; - SHA3_512_OUTPUT_LENGTH_BYTE = 64; - - SHA3_224_BLOCK_SIZE_BYTE = 144; - SHA3_256_BLOCK_SIZE_BYTE = 136; - SHA3_384_BLOCK_SIZE_BYTE = 104; - SHA3_512_BLOCK_SIZE_BYTE = 72; - - SHAKE128_BLOCK_SIZE_BYTE = 168; - SHAKE256_BLOCK_SIZE_BYTE = 136; - - HMAC_SHA3_224_BLOCK_SIZE_BYTE = SHA3_224_BLOCK_SIZE_BYTE; - HMAC_SHA3_256_BLOCK_SIZE_BYTE = SHA3_256_BLOCK_SIZE_BYTE; - HMAC_SHA3_384_BLOCK_SIZE_BYTE = SHA3_384_BLOCK_SIZE_BYTE; - HMAC_SHA3_512_BLOCK_SIZE_BYTE = SHA3_512_BLOCK_SIZE_BYTE; - - HMAC_SHA3_224_OUTPUT_LENGTH_BYTE = SHA3_224_OUTPUT_LENGTH_BYTE; - HMAC_SHA3_256_OUTPUT_LENGTH_BYTE = SHA3_256_OUTPUT_LENGTH_BYTE; - HMAC_SHA3_384_OUTPUT_LENGTH_BYTE = SHA3_384_OUTPUT_LENGTH_BYTE; - HMAC_SHA3_512_OUTPUT_LENGTH_BYTE = SHA3_512_OUTPUT_LENGTH_BYTE; - - KECCAKF_ROUND_CONSTS: array[0..23] of TUInt64 = ( - $0000000000000001, $0000000000008082, $800000000000808A, - $8000000080008000, $000000000000808B, $0000000080000001, - $8000000080008081, $8000000000008009, $000000000000008A, - $0000000000000088, $0000000080008009, $000000008000000A, - $000000008000808B, $800000000000008B, $8000000000008089, - $8000000000008003, $8000000000008002, $8000000000000080, - $000000000000800A, $800000008000000A, $8000000080008081, - $8000000000008080, $0000000080000001, $8000000080008008 - ); - - KECCAKF_ROT_CONSTS: array[0..23] of Integer = ( - 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, - 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 - ); - - KECCAKF_PILN: array[0..23] of Integer = ( - 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, - 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 - ); - -function ROTL64(Q: TUInt64; N: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (Q shl N) xor (Q shr (64 - N)); -end; - -// һ SHA3 㣬 Block ݣ State -procedure SHA3_Transform(var Context: TCnSHA3Context); -type - PUInt64Array = ^TUInt64Array; - TUInt64Array = array[0..4095] of TUInt64; -var - I, J, R, L: Integer; - P: PUInt64Array; - T: TUInt64; - BC: array[0..4] of TUInt64; -begin - P := PUInt64Array(@(Context.Block[0])); - I := 0; - L := Integer(Context.BlockLen div 8); - while I < L do - begin - Context.State[I] := Context.State[I] xor P^[I]; - Inc(I); - end; - - for R := 0 to Context.Round - 1 do - begin - // Theta - for I := 0 to 4 do - begin - BC[I] := Context.State[I] xor Context.State[I + 5] xor Context.State[I + 10] - xor Context.State[I + 15] xor Context.State[I + 20]; - end; - for I := 0 to 4 do - begin - T := BC[(I + 4) mod 5] xor ROTL64(BC[(I + 1) mod 5], 1); - for J := 0 to 4 do - Context.State[5 * J + I] := Context.State[5 * J + I] xor T; - end; - - // Rho Pi - T := Context.State[1]; - for I := 0 to 23 do - begin - J := KECCAKF_PILN[I]; - BC[0] := Context.State[J]; - Context.State[J] := ROTL64(T, KECCAKF_ROT_CONSTS[I]); - T := BC[0]; - end; - - // Chi - for J := 0 to 4 do - begin - for I := 0 to 4 do - BC[I] := Context.State[5 * J + I]; - - for I := 0 to 4 do - Context.State[5 * J + I] := Context.State[5 * J + I] xor - ((not BC[(I + 1) mod 5]) and BC[(I + 2) mod 5]); - end; - - // Iota - Context.State[0] := Context.State[0] xor KECCAKF_ROUND_CONSTS[R]; - end; -end; - -procedure SHA3Init(var Context: TCnSHA3Context; SHA3Type: TSHA3Type; - DigestByteLength: Cardinal = 0); -begin - FillChar(Context.State, SizeOf(Context.State), 0); - FillChar(Context.Block, SizeOf(Context.Block), 0); - Context.Index := 0; - Context.Round := SHA3_ROUNDS; - - case SHA3Type of - stSHA3_224: - begin - Context.BlockLen := SHA3_224_BLOCK_SIZE_BYTE; - Context.DigestLen := SHA3_224_OUTPUT_LENGTH_BYTE; - end; - stSHA3_256: - begin - Context.BlockLen := SHA3_256_BLOCK_SIZE_BYTE; - Context.DigestLen := SHA3_256_OUTPUT_LENGTH_BYTE; - end; - stSHA3_384: - begin - Context.BlockLen := SHA3_384_BLOCK_SIZE_BYTE; - Context.DigestLen := SHA3_384_OUTPUT_LENGTH_BYTE; - end; - stSHA3_512: - begin - Context.BlockLen := SHA3_512_BLOCK_SIZE_BYTE; - Context.DigestLen := SHA3_512_OUTPUT_LENGTH_BYTE; - end; - stSHAKE128: - begin - Context.BlockLen := SHAKE128_BLOCK_SIZE_BYTE; - Context.DigestLen := DigestByteLength; - end; - stSHAKE256: - begin - Context.BlockLen := SHAKE256_BLOCK_SIZE_BYTE; - Context.DigestLen := DigestByteLength; - end; - end; -end; - -procedure SHA3Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -var - R, Idx: Cardinal; -begin - Idx := Context.Index; // Index Block еijʼλָ - repeat - if ByteLength < Context.BlockLen - Idx then - R := ByteLength //  - else - R := Context.BlockLen - Idx; // ܻʣ - - FillChar(Context.Block[Idx], SizeOf(Context.Block) - Idx, 0); // ȷβΪ 0 - Move(Input^, Context.Block[Idx], R); // Block ǰ벿ֲ - - if (Idx + R) < Context.BlockLen then // ûֲ - begin // ֻ Index λָ - Idx := Idx + R; - Break; - end; - - SHA3_Transform(Context); - Dec(ByteLength, R); - Idx := 0; - Inc(Input, R); - until False; - Context.Index := Idx; -end; - -procedure SHA3UpdateW(var Context: TCnSHA3Context; Input: PWideChar; CharLength: Cardinal); -var -{$IFDEF MSWINDOWS} - Content: PAnsiChar; - Len: Cardinal; -{$ELSE} - S: string; // UnicodeString - A: AnsiString; -{$ENDIF} -begin -{$IFDEF MSWINDOWS} - GetMem(Content, CharLength * SizeOf(WideChar)); - try - Len := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 - PAnsiChar(Content), CharLength * SizeOf(WideChar), nil, nil); - SHA3Update(Context, Content, Len); - finally - FreeMem(Content); - end; -{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ - S := StrNew(Input); - A := AnsiString(S); - SHA3Update(Context, @A[1], Length(A)); -{$ENDIF} -end; - -// SHA3_224/256/384/512 ר -procedure SHA3Final(var Context: TCnSHA3Context; var Digest: TCnSHA3GeneralDigest); overload; -begin - Context.Block[Context.Index] := 6; - Context.Block[Context.BlockLen - 1] := Context.Block[Context.BlockLen - 1] or $80; - SHA3_Transform(Context); - Move(Context.State[0], Digest[0], Context.DigestLen); -end; - -// SHAKE128 SHAKE256 ר -procedure SHA3Final(var Context: TCnSHA3Context; out Digest: TBytes); overload; -var - Idx, DL: Cardinal; -begin - Context.Block[Context.Index] := $1F; - Context.Block[Context.BlockLen - 1] := Context.Block[Context.BlockLen - 1] or $80; - SHA3_Transform(Context); - - SetLength(Digest, Context.DigestLen); - if Context.DigestLen <= Context.BlockLen then - Move(Context.State[0], Digest[0], Context.DigestLen) - else - begin - DL := Context.DigestLen; - Idx := 0; - - while DL >= Context.BlockLen do - begin - Move(Context.State[0], Digest[Idx], Context.BlockLen); - Inc(Idx, Context.BlockLen); - Dec(DL, Context.BlockLen); - - if DL > 0 then - begin - FillChar(Context.Block[0], SizeOf(Context.Block), 0); - SHA3_Transform(Context); - end; - end; - - if DL > 0 then - Move(Context.State[0], Digest[Idx], DL); - end; -end; - -procedure SHA3_224Init(var Context: TCnSHA3Context); -begin - SHA3Init(Context, stSHA3_224); -end; - -procedure SHA3_224Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -begin - SHA3Update(Context, Input, ByteLength); -end; - -procedure SHA3_224Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_224Digest); -var - Res: TCnSHA3GeneralDigest; -begin - SHA3Final(Context, Res); - Move(Res[0], Digest[0], SHA3_224_OUTPUT_LENGTH_BYTE); -end; - -procedure SHA3_256Init(var Context: TCnSHA3Context); -begin - SHA3Init(Context, stSHA3_256); -end; - -procedure SHA3_256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -begin - SHA3Update(Context, Input, ByteLength); -end; - -procedure SHA3_256Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_256Digest); -var - Res: TCnSHA3GeneralDigest; -begin - SHA3Final(Context, Res); - Move(Res[0], Digest[0], SHA3_256_OUTPUT_LENGTH_BYTE); -end; - -procedure SHA3_384Init(var Context: TCnSHA3Context); -begin - SHA3Init(Context, stSHA3_384); -end; - -procedure SHA3_384Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -begin - SHA3Update(Context, Input, ByteLength); -end; - -procedure SHA3_384Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_384Digest); -var - Res: TCnSHA3GeneralDigest; -begin - SHA3Final(Context, Res); - Move(Res[0], Digest[0], SHA3_384_OUTPUT_LENGTH_BYTE); -end; - -procedure SHA3_512Init(var Context: TCnSHA3Context); -begin - SHA3Init(Context, stSHA3_512); -end; - -procedure SHA3_512Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -begin - SHA3Update(Context, Input, ByteLength); -end; - -procedure SHA3_512Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_512Digest); -var - Res: TCnSHA3GeneralDigest; -begin - SHA3Final(Context, Res); - Move(Res[0], Digest[0], SHA3_512_OUTPUT_LENGTH_BYTE); -end; - -procedure SHAKE128Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal); -begin - SHA3Init(Context, stSHAKE128, DigestByteLength); -end; - -procedure SHAKE128Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -begin - SHA3Update(Context, Input, ByteLength); -end; - -procedure SHAKE128Final(var Context: TCnSHA3Context; out Digest: TBytes); -begin - SHA3Final(Context, Digest); -end; - -procedure SHAKE256Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal); -begin - SHA3Init(Context, stSHAKE256, DigestByteLength); -end; - -procedure SHAKE256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); -begin - SHA3Update(Context, Input, ByteLength); -end; - -procedure SHAKE256Final(var Context: TCnSHA3Context; out Digest: TBytes); -begin - SHA3Final(Context, Digest); -end; - -// ݿ SHA3_224λ -function SHA3_224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_224Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_224); - SHA3Update(Context, Input, ByteLength); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); -end; - -// ݿ SHA3_256λ -function SHA3_256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_256Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_256); - SHA3Update(Context, Input, ByteLength); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); -end; - -// ݿ SHA3_384λ -function SHA3_384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_384Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_384); - SHA3Update(Context, Input, ByteLength); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); -end; - -// ݿ SHA3_512λ -function SHA3_512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_512Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_512); - SHA3Update(Context, Input, ByteLength); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); -end; - -// ݿ SHA3_224 -function SHA3_224Buffer(const Buffer; Count: Cardinal): TCnSHA3_224Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_224); - SHA3Update(Context, PAnsiChar(Buffer), Count); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); -end; - -// ݿ SHA3_256 -function SHA3_256Buffer(const Buffer; Count: Cardinal): TCnSHA3_256Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_256); - SHA3Update(Context, PAnsiChar(Buffer), Count); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); -end; - -// ݿ SHA3_384 -function SHA3_384Buffer(const Buffer; Count: Cardinal): TCnSHA3_384Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_384); - SHA3Update(Context, PAnsiChar(Buffer), Count); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); -end; - -// ݿ SHA3_512 -function SHA3_512Buffer(const Buffer; Count: Cardinal): TCnSHA3_512Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_512); - SHA3Update(Context, PAnsiChar(Buffer), Count); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); -end; - -// ݿ SHAKE128 -function SHAKE128Buffer(const Buffer; Count: Cardinal; DigestByteLength: Cardinal): TBytes; -var - Context: TCnSHA3Context; -begin - SHAKE128Init(Context, DigestByteLength); - SHAKE128Update(Context, PAnsiChar(Buffer), Count); - SHAKE128Final(Context, Result); -end; - -// ݿ SHAKE256 -function SHAKE256Buffer(const Buffer; Count: Cardinal; DigestByteLength: Cardinal): TBytes; -var - Context: TCnSHA3Context; -begin - SHAKE256Init(Context, DigestByteLength); - SHAKE256Update(Context, PAnsiChar(Buffer), Count); - SHAKE256Final(Context, Result); -end; - -// ֽ SHA3_224 -function SHA3_224Bytes(Data: TBytes): TCnSHA3_224Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_224); - SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); -end; - -// ֽ SHA3_256 -function SHA3_256Bytes(Data: TBytes): TCnSHA3_256Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_256); - SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); -end; - -// ֽ SHA3_384 -function SHA3_384Bytes(Data: TBytes): TCnSHA3_384Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_384); - SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); -end; - -// ֽ SHA3_512 -function SHA3_512Bytes(Data: TBytes): TCnSHA3_512Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_512); - SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); -end; - -// ֽ SHAKE128 -function SHAKE128Bytes(Data: TBytes; DigestByteLength: Cardinal): TBytes; -var - Context: TCnSHA3Context; -begin - SHAKE128Init(Context, DigestByteLength); - SHAKE128Update(Context, PAnsiChar(@Data[0]), Length(Data)); - SHAKE128Final(Context, Result); -end; - -// ֽ SHAKE256 -function SHAKE256Bytes(Data: TBytes; DigestByteLength: Cardinal): TBytes; -var - Context: TCnSHA3Context; -begin - SHAKE256Init(Context, DigestByteLength); - SHAKE256Update(Context, PAnsiChar(@Data[0]), Length(Data)); - SHAKE256Final(Context, Result); -end; - -// String ݽ SHA3_224 -function SHA3_224String(const Str: string): TCnSHA3_224Digest; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := SHA3_224StringA(AStr); -end; - -// String ݽ SHA3_256 -function SHA3_256String(const Str: string): TCnSHA3_256Digest; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := SHA3_256StringA(AStr); -end; - -// String ݽ SHA3_384 -function SHA3_384String(const Str: string): TCnSHA3_384Digest; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := SHA3_384StringA(AStr); -end; - -// String ݽ SHA3_512 -function SHA3_512String(const Str: string): TCnSHA3_512Digest; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := SHA3_512StringA(AStr); -end; - -// String ݽ SHAKE128 -function SHAKE128String(const Str: string; DigestByteLength: Cardinal): TBytes; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := SHAKE128StringA(AStr, DigestByteLength); -end; - -// String ݽ SHAKE256 -function SHAKE256String(const Str: string; DigestByteLength: Cardinal): TBytes; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := SHAKE256StringA(AStr, DigestByteLength); -end; - -// UnicodeString ݽֱӵ SHA3_224 㣬ת -{$IFDEF UNICODE} -function SHA3_224UnicodeString(const Str: string): TCnSHA3_224Digest; -{$ELSE} -function SHA3_224UnicodeString(const Str: WideString): TCnSHA3_224Digest; -{$ENDIF} -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_224); - SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); -end; - -// UnicodeString ݽֱӵ SHA3_256 㣬ת -{$IFDEF UNICODE} -function SHA3_256UnicodeString(const Str: string): TCnSHA3_256Digest; -{$ELSE} -function SHA3_256UnicodeString(const Str: WideString): TCnSHA3_256Digest; -{$ENDIF} -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_256); - SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); -end; - -// UnicodeString ݽֱӵ SHA3_384 㣬ת -{$IFDEF UNICODE} -function SHA3_384UnicodeString(const Str: string): TCnSHA3_384Digest; -{$ELSE} -function SHA3_384UnicodeString(const Str: WideString): TCnSHA3_384Digest; -{$ENDIF} -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_384); - SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); -end; - -// UnicodeString ݽֱӵ SHA3_512 㣬ת -{$IFDEF UNICODE} -function SHA3_512UnicodeString(const Str: string): TCnSHA3_512Digest; -{$ELSE} -function SHA3_512UnicodeString(const Str: WideString): TCnSHA3_512Digest; -{$ENDIF} -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_512); - SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); -end; - -// UnicodeString ݽֱӵ SHAKE128 㣬ת -{$IFDEF UNICODE} -function SHAKE128UnicodeString(const Str: string; DigestByteLength: Cardinal): TBytes; -{$ELSE} -function SHAKE128UnicodeString(const Str: WideString; DigestByteLength: Cardinal): TBytes; -{$ENDIF} -var - Context: TCnSHA3Context; -begin - SHAKE128Init(Context, DigestByteLength); - SHAKE128Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - SHAKE128Final(Context, Result); -end; - -// UnicodeString ݽֱӵ SHAKE256 㣬ת -{$IFDEF UNICODE} -function SHAKE256UnicodeString(const Str: string; DigestByteLength: Cardinal): TBytes; -{$ELSE} -function SHAKE256UnicodeString(const Str: WideString; DigestByteLength: Cardinal): TBytes; -{$ENDIF} -var - Context: TCnSHA3Context; -begin - SHAKE256Init(Context, DigestByteLength); - SHAKE256Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - SHAKE256Final(Context, Result); -end; - -// AnsiString ݽSHA224 -function SHA3_224StringA(const Str: AnsiString): TCnSHA3_224Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_224); - SHA3Update(Context, PAnsiChar(Str), Length(Str)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); -end; - -// WideString ݽ SHA3_224 -function SHA3_224StringW(const Str: WideString): TCnSHA3_224Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_224); - SHA3UpdateW(Context, PWideChar(Str), Length(Str)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); -end; - -// AnsiString ݽ SHA3_256 -function SHA3_256StringA(const Str: AnsiString): TCnSHA3_256Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_256); - SHA3Update(Context, PAnsiChar(Str), Length(Str)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); -end; - -// WideString ݽ SHA3_256 -function SHA3_256StringW(const Str: WideString): TCnSHA3_256Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_256); - SHA3UpdateW(Context, PWideChar(Str), Length(Str)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); -end; - -// AnsiString ݽ SHA3_384 -function SHA3_384StringA(const Str: AnsiString): TCnSHA3_384Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_384); - SHA3Update(Context, PAnsiChar(Str), Length(Str)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); -end; - -// WideString ݽ SHA3_384 -function SHA3_384StringW(const Str: WideString): TCnSHA3_384Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_384); - SHA3UpdateW(Context, PWideChar(Str), Length(Str)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); -end; - -// AnsiString ݽ SHA3_512 -function SHA3_512StringA(const Str: AnsiString): TCnSHA3_512Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_512); - SHA3Update(Context, PAnsiChar(Str), Length(Str)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); -end; - -// WideString ݽ SHA3_512 -function SHA3_512StringW(const Str: WideString): TCnSHA3_512Digest; -var - Context: TCnSHA3Context; - Res: TCnSHA3GeneralDigest; -begin - SHA3Init(Context, stSHA3_512); - SHA3UpdateW(Context, PWideChar(Str), Length(Str)); - SHA3Final(Context, Res); - Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); -end; - -// AnsiString ݽ SHAKE128 -function SHAKE128StringA(const Str: AnsiString; DigestByteLength: Cardinal): TBytes; -var - Context: TCnSHA3Context; -begin - SHAKE128Init(Context, DigestByteLength); - SHAKE128Update(Context, PAnsiChar(Str), Length(Str)); - SHAKE128Final(Context, Result); -end; - -// WideString ݽ SHAKE128 -function SHAKE128StringW(const Str: WideString; DigestByteLength: Cardinal): TBytes; -var - Context: TCnSHA3Context; -begin - SHAKE128Init(Context, DigestByteLength); - SHA3UpdateW(Context, PWideChar(Str), Length(Str)); // SHAKE128UpdateW = SHA3UpdateW - SHAKE128Final(Context, Result); -end; - -// AnsiString ݽ SHAKE256 -function SHAKE256StringA(const Str: AnsiString; DigestByteLength: Cardinal): TBytes; -var - Context: TCnSHA3Context; -begin - SHAKE256Init(Context, DigestByteLength); - SHAKE256Update(Context, PAnsiChar(Str), Length(Str)); - SHAKE256Final(Context, Result); -end; - -// WideString ݽ SHAKE256 -function SHAKE256StringW(const Str: WideString; DigestByteLength: Cardinal): TBytes; -var - Context: TCnSHA3Context; -begin - SHAKE256Init(Context, DigestByteLength); - SHA3UpdateW(Context, PWideChar(Str), Length(Str)); // SHAKE256UpdateW = SHA3UpdateW - SHAKE256Final(Context, Result); -end; - -// SHA3Type ֻ stSHA3_224, stSHA3_256, stSHA3_384, stSHA3_512 -function InternalSHA3Stream(Stream: TStream; const BufSize: Cardinal; var D: - TCnSHA3GeneralDigest; SHA3Type: TSHA3Type; CallBack: TCnSHA3CalcProgressFunc): Boolean; overload; -var - Buf: PAnsiChar; - BufLen: Cardinal; - Size: Int64; - ReadBytes: Cardinal; - TotalBytes: Int64; - SavePos: Int64; - CancelCalc: Boolean; - Context: TCnSHA3Context; -begin - Result := False; - Size := Stream.Size; - SavePos := Stream.Position; - TotalBytes := 0; - if Size = 0 then - Exit; - if Size < BufSize then - BufLen := Size - else - BufLen := BufSize; - - CancelCalc := False; - SHA3Init(Context, SHA3Type); - - GetMem(Buf, BufLen); - try - Stream.Position := 0; - repeat - ReadBytes := Stream.Read(Buf^, BufLen); - if ReadBytes <> 0 then - begin - Inc(TotalBytes, ReadBytes); - SHA3Update(Context, Buf, ReadBytes); - - if Assigned(CallBack) then - begin - CallBack(Size, TotalBytes, CancelCalc); - if CancelCalc then - Exit; - end; - end; - until (ReadBytes = 0) or (TotalBytes = Size); - SHA3Final(Context, D); - Result := True; - finally - FreeMem(Buf, BufLen); - Stream.Position := SavePos; - end; -end; - -// SHA3Type ֻ stSHAKE128 stSHAKE256 -function InternalSHA3Stream(Stream: TStream; const BufSize: Cardinal; - SHA3Type: TSHA3Type; DigestByteLength: Cardinal; out D: TBytes; - CallBack: TCnSHA3CalcProgressFunc): Boolean; overload; -var - Buf: PAnsiChar; - BufLen: Cardinal; - Size: Int64; - ReadBytes: Cardinal; - TotalBytes: Int64; - SavePos: Int64; - CancelCalc: Boolean; - Context: TCnSHA3Context; -begin - Result := False; - Size := Stream.Size; - SavePos := Stream.Position; - TotalBytes := 0; - if Size = 0 then - Exit; - if Size < BufSize then - BufLen := Size - else - BufLen := BufSize; - - CancelCalc := False; - SHA3Init(Context, SHA3Type, DigestByteLength); - - GetMem(Buf, BufLen); - try - Stream.Position := 0; - repeat - ReadBytes := Stream.Read(Buf^, BufLen); - if ReadBytes <> 0 then - begin - Inc(TotalBytes, ReadBytes); - SHA3Update(Context, Buf, ReadBytes); - - if Assigned(CallBack) then - begin - CallBack(Size, TotalBytes, CancelCalc); - if CancelCalc then - Exit; - end; - end; - until (ReadBytes = 0) or (TotalBytes = Size); - SHA3Final(Context, D); - Result := True; - finally - FreeMem(Buf, BufLen); - Stream.Position := SavePos; - end; -end; - -// ָ SHA3_224 -function SHA3_224Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): - TCnSHA3_224Digest; -var - Dig: TCnSHA3GeneralDigest; -begin - InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_224, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA3_224Digest)); -end; - -// ָ SHA3_256 -function SHA3_256Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): - TCnSHA3_256Digest; -var - Dig: TCnSHA3GeneralDigest; -begin - InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_256, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA3_256Digest)); -end; - -// ָ SHA3_384 -function SHA3_384Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): - TCnSHA3_384Digest; -var - Dig: TCnSHA3GeneralDigest; -begin - InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_384, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA3_384Digest)); -end; - -// ָ SHA3_512 -function SHA3_512Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): - TCnSHA3_512Digest; -var - Dig: TCnSHA3GeneralDigest; -begin - InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_512, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA3_512Digest)); -end; - -// ָӴճȿɱ SHAKE128 -function SHAKE128Stream(Stream: TStream; DigestByteLength: Cardinal; - CallBack: TCnSHA3CalcProgressFunc): TBytes; -begin - InternalSHA3Stream(Stream, STREAM_BUF_SIZE, stSHAKE128, DigestByteLength, Result, CallBack); -end; - -// ָӴճȿɱ SHAKE256 -function SHAKE256Stream(Stream: TStream; DigestByteLength: Cardinal; - CallBack: TCnSHA3CalcProgressFunc): TBytes; -begin - InternalSHA3Stream(Stream, STREAM_BUF_SIZE, stSHAKE256, DigestByteLength, Result, CallBack); -end; - -function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; -{$IFDEF MSWINDOWS} -var - H: THandle; - Info: BY_HANDLE_FILE_INFORMATION; - Rec: Int64Rec; -{$ENDIF} - begin -{$IFDEF MSWINDOWS} - Result := False; - IsEmpty := False; - H := CreateFile(PChar(AFileName), GENERIC_READ, FILE_SHARE_READ, nil, - OPEN_EXISTING, 0, 0); - if H = INVALID_HANDLE_VALUE then - Exit; - try - if not GetFileInformationByHandle(H, Info) then - Exit; - finally - CloseHandle(H); - end; - Rec.Lo := Info.nFileSizeLow; - Rec.Hi := Info.nFileSizeHigh; - Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); - IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); -{$ELSE} - Result := True; // Windows ƽ̨ Trueʾ Mapping -{$ENDIF} -end; - -function InternalSHA3File(const FileName: string; SHA3Type: TSHA3Type; - CallBack: TCnSHA3CalcProgressFunc): TCnSHA3GeneralDigest; overload; -var -{$IFDEF MSWINDOWS} - Context: TCnSHA3Context; - FileHandle: THandle; - MapHandle: THandle; - ViewPointer: Pointer; -{$ENDIF} - Stream: TStream; - FileIsZeroSize: Boolean; -begin - FileIsZeroSize := False; - if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then - begin - // 2G ļ Map ʧܣʽѭ - Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try - InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Result, SHA3Type, CallBack); - finally - Stream.Free; - end; - end - else - begin -{$IFDEF MSWINDOWS} - SHA3Init(Context, SHA3Type); - FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or - FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or - FILE_FLAG_SEQUENTIAL_SCAN, 0); - if FileHandle <> INVALID_HANDLE_VALUE then - begin - try - MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); - if MapHandle <> 0 then - begin - try - ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); - if ViewPointer <> nil then - begin - try - SHA3Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); - finally - UnmapViewOfFile(ViewPointer); - end; - end - else - begin - raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); - end; - finally - CloseHandle(MapHandle); - end; - end - else - begin - if not FileIsZeroSize then - raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); - end; - finally - CloseHandle(FileHandle); - end; - end; - SHA3Final(Context, Result); -{$ENDIF} - end; -end; - -function InternalSHA3File(const FileName: string; SHA3Type: TSHA3Type; - DigestByteLength: Cardinal; CallBack: TCnSHA3CalcProgressFunc): TBytes; overload; -var -{$IFDEF MSWINDOWS} - Context: TCnSHA3Context; - FileHandle: THandle; - MapHandle: THandle; - ViewPointer: Pointer; -{$ENDIF} - Stream: TStream; - FileIsZeroSize: Boolean; -begin - FileIsZeroSize := False; - if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then - begin - // 2G ļ Map ʧܣʽѭ - Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try - InternalSHA3Stream(Stream, STREAM_BUF_SIZE, SHA3Type, DigestByteLength, Result, CallBack); - finally - Stream.Free; - end; - end - else - begin -{$IFDEF MSWINDOWS} - SHA3Init(Context, SHA3Type, DigestByteLength); - FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or - FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or - FILE_FLAG_SEQUENTIAL_SCAN, 0); - if FileHandle <> INVALID_HANDLE_VALUE then - begin - try - MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); - if MapHandle <> 0 then - begin - try - ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); - if ViewPointer <> nil then - begin - try - SHA3Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); - finally - UnmapViewOfFile(ViewPointer); - end; - end - else - begin - raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); - end; - finally - CloseHandle(MapHandle); - end; - end - else - begin - if not FileIsZeroSize then - raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); - end; - finally - CloseHandle(FileHandle); - end; - end; - SHA3Final(Context, Result); -{$ENDIF} - end; -end; - -// ָļݽ SHA3_224 -function SHA3_224File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): - TCnSHA3_224Digest; -var - Dig: TCnSHA3GeneralDigest; -begin - Dig := InternalSHA3File(FileName, stSHA3_224, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA3_224Digest)); -end; - -// ָļݽ SHA3_256 -function SHA3_256File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): - TCnSHA3_256Digest; -var - Dig: TCnSHA3GeneralDigest; -begin - Dig := InternalSHA3File(FileName, stSHA3_256, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA3_256Digest)); -end; - -// ָļݽ SHA3_384 -function SHA3_384File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): - TCnSHA3_384Digest; -var - Dig: TCnSHA3GeneralDigest; -begin - Dig := InternalSHA3File(FileName, stSHA3_384, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA3_384Digest)); -end; - -// ָļݽ SHA3_512 -function SHA3_512File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): - TCnSHA3_512Digest; -var - Dig: TCnSHA3GeneralDigest; -begin - Dig := InternalSHA3File(FileName, stSHA3_512, CallBack); - Move(Dig[0], Result[0], SizeOf(TCnSHA3_512Digest)); -end; - -// ָļݽӴճȿɱ SHAKE128 -function SHAKE128File(const FileName: string; DigestByteLength: Cardinal; - CallBack: TCnSHA3CalcProgressFunc): TBytes; -begin - Result := InternalSHA3File(FileName, stSHAKE128, DigestByteLength, CallBack); -end; - -// ָļݽӴճȿɱ SHAKE256 -function SHAKE256File(const FileName: string; DigestByteLength: Cardinal; - CallBack: TCnSHA3CalcProgressFunc): TBytes; -begin - Result := InternalSHA3File(FileName, stSHAKE256, DigestByteLength, CallBack); -end; - -// ʮƸʽ SHA3_224 Ӵֵ -function SHA3_224Print(const Digest: TCnSHA3_224Digest): string; -begin - Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_224Digest)); -end; - -// ʮƸʽ SHA3_256 Ӵֵ -function SHA3_256Print(const Digest: TCnSHA3_256Digest): string; -begin - Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_256Digest)); -end; - -// ʮƸʽ SHA3_384 Ӵֵ -function SHA3_384Print(const Digest: TCnSHA3_384Digest): string; -begin - Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_384Digest)); -end; - -// ʮƸʽ SHA3_512 Ӵֵ -function SHA3_512Print(const Digest: TCnSHA3_512Digest): string; -begin - Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_512Digest)); -end; - -// ʮƸʽ SHAKE128 Ӵֵ -function SHAKE128Print(const Digest: TBytes): string; -begin - Result := BytesToHex(Digest); -end; - -// ʮƸʽ SHAKE256 Ӵֵ -function SHAKE256Print(const Digest: TBytes): string; -begin - Result := BytesToHex(Digest); -end; - -// Ƚ SHA3_224 ӴֵǷ -function SHA3_224Match(const D1, D2: TCnSHA3_224Digest): Boolean; -begin - Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_224Digest)); -end; - -// Ƚ SHA3_256 ӴֵǷ -function SHA3_256Match(const D1, D2: TCnSHA3_256Digest): Boolean; -begin - Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_256Digest)); -end; - -// Ƚ SHA3_384 ӴֵǷ -function SHA3_384Match(const D1, D2: TCnSHA3_384Digest): Boolean; -begin - Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_384Digest)); -end; - -// Ƚ SHA3_512 ӴֵǷ -function SHA3_512Match(const D1, D2: TCnSHA3_512Digest): Boolean; -begin - Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_512Digest));; -end; - -// Ƚ SHAKE128 ӴֵǷ -function SHAKE128Match(const D1, D2: TBytes): Boolean; -begin - Result := CompareBytes(D1, D2); -end; - -// Ƚ SHAKE256 ӴֵǷ -function SHAKE256Match(const D1, D2: TBytes): Boolean; -begin - Result := CompareBytes(D1, D2); -end; - -// SHA3_224 Ӵֵת string -function SHA3_224DigestToStr(const Digest: TCnSHA3_224Digest): string; -begin - Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_224Digest)); -end; - -// SHA3_256 Ӵֵת string -function SHA3_256DigestToStr(const Digest: TCnSHA3_256Digest): string; -begin - Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_256Digest));; -end; - -// SHA3_384 Ӵֵת string -function SHA3_384DigestToStr(const Digest: TCnSHA3_384Digest): string; -begin - Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_384Digest)); -end; - -// SHA3_512 Ӵֵת string -function SHA3_512DigestToStr(const Digest: TCnSHA3_512Digest): string; -begin - Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_512Digest)); -end; - -// SHAKE128 Ӵֵת string -function SHAKE128DigestToStr(const Digest: TBytes): string; -begin - Result := BytesToString(Digest); -end; - -// SHAKE256 Ӵֵת string -function SHAKE256DigestToStr(const Digest: TBytes): string; -begin - Result := BytesToString(Digest); -end; - -procedure SHA3_224HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); -var - I: Integer; - Sum: TCnSHA3_224Digest; -begin - if KeyLength > HMAC_SHA3_224_BLOCK_SIZE_BYTE then - begin - Sum := SHA3_224Buffer(Key, KeyLength); - KeyLength := HMAC_SHA3_224_OUTPUT_LENGTH_BYTE; - Key := @(Sum[0]); - end; - - FillChar(Context.Ipad, HMAC_SHA3_224_BLOCK_SIZE_BYTE, $36); - FillChar(Context.Opad, HMAC_SHA3_224_BLOCK_SIZE_BYTE, $5C); - - for I := 0 to KeyLength - 1 do - begin - Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); - Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); - end; - - SHA3Init(Context, stSHA3_224); - SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_224_BLOCK_SIZE_BYTE); -end; - -procedure SHA3_256HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); -var - I: Integer; - Sum: TCnSHA3_256Digest; -begin - if KeyLength > HMAC_SHA3_256_BLOCK_SIZE_BYTE then - begin - Sum := SHA3_256Buffer(Key, KeyLength); - KeyLength := HMAC_SHA3_256_OUTPUT_LENGTH_BYTE; - Key := @(Sum[0]); - end; - - FillChar(Context.Ipad, HMAC_SHA3_256_BLOCK_SIZE_BYTE, $36); - FillChar(Context.Opad, HMAC_SHA3_256_BLOCK_SIZE_BYTE, $5C); - - for I := 0 to KeyLength - 1 do - begin - Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); - Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); - end; - - SHA3Init(Context, stSHA3_256); - SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_256_BLOCK_SIZE_BYTE); -end; - -procedure SHA3_384HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); -var - I: Integer; - Sum: TCnSHA3_384Digest; -begin - if KeyLength > HMAC_SHA3_384_BLOCK_SIZE_BYTE then - begin - Sum := SHA3_384Buffer(Key, KeyLength); - KeyLength := HMAC_SHA3_384_OUTPUT_LENGTH_BYTE; - Key := @(Sum[0]); - end; - - FillChar(Context.Ipad, HMAC_SHA3_384_BLOCK_SIZE_BYTE, $36); - FillChar(Context.Opad, HMAC_SHA3_384_BLOCK_SIZE_BYTE, $5C); - - for I := 0 to KeyLength - 1 do - begin - Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); - Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); - end; - - SHA3Init(Context, stSHA3_384); - SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_384_BLOCK_SIZE_BYTE); -end; - -procedure SHA3_512HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); -var - I: Integer; - Sum: TCnSHA3_512Digest; -begin - if KeyLength > HMAC_SHA3_512_BLOCK_SIZE_BYTE then - begin - Sum := SHA3_512Buffer(Key, KeyLength); - KeyLength := HMAC_SHA3_512_OUTPUT_LENGTH_BYTE; - Key := @(Sum[0]); - end; - - FillChar(Context.Ipad, HMAC_SHA3_512_BLOCK_SIZE_BYTE, $36); - FillChar(Context.Opad, HMAC_SHA3_512_BLOCK_SIZE_BYTE, $5C); - - for I := 0 to KeyLength - 1 do - begin - Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); - Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); - end; - - SHA3Init(Context, stSHA3_512); - SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_512_BLOCK_SIZE_BYTE); -end; - -procedure SHA3_224HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; - ByteLength: Cardinal); -begin - SHA3Update(Context, Input, ByteLength); -end; - -procedure SHA3_256HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; - ByteLength: Cardinal); -begin - SHA3Update(Context, Input, ByteLength); -end; - -procedure SHA3_384HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; - ByteLength: Cardinal); -begin - SHA3Update(Context, Input, ByteLength); -end; - -procedure SHA3_512HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; - ByteLength: Cardinal); -begin - SHA3Update(Context, Input, ByteLength); -end; - -procedure SHA3_224HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); -var - Len: Integer; - TmpBuf: TCnSHA3GeneralDigest; -begin - Len := HMAC_SHA3_224_OUTPUT_LENGTH_BYTE; - SHA3Final(Context, TmpBuf); - SHA3Init(Context, stSHA3_224); - SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_224_BLOCK_SIZE_BYTE); - SHA3Update(Context, @(TmpBuf[0]), Len); - SHA3Final(Context, Output); -end; - -procedure SHA3_256HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); -var - Len: Integer; - TmpBuf: TCnSHA3GeneralDigest; -begin - Len := HMAC_SHA3_256_OUTPUT_LENGTH_BYTE; - SHA3Final(Context, TmpBuf); - SHA3Init(Context, stSHA3_256); - SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_256_BLOCK_SIZE_BYTE); - SHA3Update(Context, @(TmpBuf[0]), Len); - SHA3Final(Context, Output); -end; - -procedure SHA3_384HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); -var - Len: Integer; - TmpBuf: TCnSHA3GeneralDigest; -begin - Len := HMAC_SHA3_384_OUTPUT_LENGTH_BYTE; - SHA3Final(Context, TmpBuf); - SHA3Init(Context, stSHA3_384); - SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_384_BLOCK_SIZE_BYTE); - SHA3Update(Context, @(TmpBuf[0]), Len); - SHA3Final(Context, Output); -end; - -procedure SHA3_512HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); -var - Len: Integer; - TmpBuf: TCnSHA3GeneralDigest; -begin - Len := HMAC_SHA3_512_OUTPUT_LENGTH_BYTE; - SHA3Final(Context, TmpBuf); - SHA3Init(Context, stSHA3_512); - SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_512_BLOCK_SIZE_BYTE); - SHA3Update(Context, @(TmpBuf[0]), Len); - SHA3Final(Context, Output); -end; - -procedure SHA3_224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA3_224Digest); -var - Context: TCnSHA3Context; - Dig: TCnSHA3GeneralDigest; -begin - SHA3_224HmacInit(Context, Key, KeyByteLength); - SHA3_224HmacUpdate(Context, Input, ByteLength); - SHA3_224HmacFinal(Context, Dig); - Move(Dig[0], Output[0], Context.DigestLen); -end; - -procedure SHA3_256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA3_256Digest); -var - Context: TCnSHA3Context; - Dig: TCnSHA3GeneralDigest; -begin - SHA3_256HmacInit(Context, Key, KeyByteLength); - SHA3_256HmacUpdate(Context, Input, ByteLength); - SHA3_256HmacFinal(Context, Dig); - Move(Dig[0], Output[0], Context.DigestLen); -end; - -procedure SHA3_384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA3_384Digest); -var - Context: TCnSHA3Context; - Dig: TCnSHA3GeneralDigest; -begin - SHA3_384HmacInit(Context, Key, KeyByteLength); - SHA3_384HmacUpdate(Context, Input, ByteLength); - SHA3_384HmacFinal(Context, Dig); - Move(Dig[0], Output[0], Context.DigestLen); -end; - -procedure SHA3_512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSHA3_512Digest); -var - Context: TCnSHA3Context; - Dig: TCnSHA3GeneralDigest; -begin - SHA3_512HmacInit(Context, Key, KeyByteLength); - SHA3_512HmacUpdate(Context, Input, ByteLength); - SHA3_512HmacFinal(Context, Dig); - Move(Dig[0], Output[0], Context.DigestLen); -end; - -end. +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnSHA3; +{* |
+================================================================================
+* ƣ
+* ԪƣSHA3 Ӵ㷨ʵֵԪ
+* ԪߣCnPack  (master@cnpack.org)
+*           / Keccak C  Pascal ֲ䲿ֹܡ
+*     עԪʵ SHA3 ϵӴ㷨Ӧ HMAC 㷨 SHA3-224/256/384/512
+*           ɱ䳤ժҪ SHAKE128/SHAKE256ȡ
+*           SHA3 淶 NIST.FIPS.202
+*           SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
+*           жⶨ Bit  Byte ת
+*           ֮ Bit ܹ 8 ʱÿ 8  Bit λþһֽڣֽڼ˳򱣳ֲ䡣
+*
+* ƽ̨PWinXP + Delphi 5.0
+* ݲԣPWinXP/7 + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2023.08.02 V1.4
+*                SHAKE128/SHAKE256 Ŀɱ䳤ժҪļ
+*           2022.04.26 V1.3
+*               ޸ LongWord  Integer ַת֧ MacOS64
+*           2019.12.12 V1.2
+*               ֧ TBytes
+*           2019.04.15 V1.1
+*               ֧ Win32/Win64/MacOS
+*           2017.11.10 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, CnNative, CnConsts; + +const + CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH = 32; + {* SHAKE128 ĬӴսֽڳ} + + CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH = 64; + {* SHAKE256 ĬӴսֽڳ} + +type + PCnSHA3GeneralDigest = ^TCnSHA3GeneralDigest; + TCnSHA3GeneralDigest = array[0..63] of Byte; + {* SHA3 ϵͨõӴս 64 ֽΪ׼} + + PCnSHA3_224Digest = ^TCnSHA3_224Digest; + TCnSHA3_224Digest = array[0..27] of Byte; + {* SHA3_224 Ӵս28 ֽ} + + PCnSHA3_256Digest = ^TCnSHA3_256Digest; + TCnSHA3_256Digest = array[0..31] of Byte; + {* SHA3_256 Ӵս32 ֽ} + + PCnSHA3_384Digest = ^TCnSHA3_384Digest; + TCnSHA3_384Digest = array[0..47] of Byte; + {* SHA3_384 Ӵս48 ֽ} + + PCnSHA3_512Digest = ^TCnSHA3_512Digest; + TCnSHA3_512Digest = array[0..63] of Byte; + {* SHA3_512 Ӵս64 ֽ} + + TCnSHA3Context = packed record + {* SHA3 ϵͨõĽṹ} + State: array[0..24] of Int64; + Index: Cardinal; + DigestLen: Cardinal; + Round: Cardinal; + BlockLen: Cardinal; + Block: array[0..255] of Byte; + Ipad: array[0..143] of Byte; {!< HMAC: inner padding } + Opad: array[0..143] of Byte; {!< HMAC: outer padding } + end; + + TCnSHA3CalcProgressFunc = procedure(ATotal, AProgress: Int64; var Cancel: + Boolean) of object; + {* SHA3 ϵͨõļȻص¼} + +function SHA3_224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_224Digest; +{* ݿ SHA3_224 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_256Digest; +{* ݿ SHA3_256 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_384Digest; +{* ݿ SHA3_384 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_512Digest; +{* ݿ SHA3_512 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHA3_224Buffer(const Buffer; Count: Cardinal): TCnSHA3_224Digest; +{* ݿ SHA3_224 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256Buffer(const Buffer; Count: Cardinal): TCnSHA3_256Digest; +{* ݿ SHA3_256 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384Buffer(const Buffer; Count: Cardinal): TCnSHA3_384Digest; +{* ݿ SHA3_384 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512Buffer(const Buffer; Count: Cardinal): TCnSHA3_512Digest; +{* ݿ SHA3_512 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128Buffer(const Buffer; Count: Cardinal; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* ݿӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256Buffer(const Buffer; Count: Cardinal; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* ݿӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHA3_224Bytes(Data: TBytes): TCnSHA3_224Digest; +{* ֽ SHA3_224 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256Bytes(Data: TBytes): TCnSHA3_256Digest; +{* ֽ SHA3_256 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384Bytes(Data: TBytes): TCnSHA3_384Digest; +{* ֽ SHA3_384 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512Bytes(Data: TBytes): TCnSHA3_512Digest; +{* ֽ SHA3_512 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128Bytes(Data: TBytes; DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* ֽӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս + + + Data: TBytes - ֽ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256Bytes(Data: TBytes; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* ֽӴճȿɱ SHAKE256 㣬سΪ DigestByteLength ֽΪӴս + + + Data: TBytes - ֽ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHA3_224String(const Str: string): TCnSHA3_224Digest; +{* String ݽ SHA3_224 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256String(const Str: string): TCnSHA3_256Digest; +{* String ݽ SHA3_256 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384String(const Str: string): TCnSHA3_384Digest; +{* String ݽ SHA3_384 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512String(const Str: string): TCnSHA3_512Digest; +{* String ݽ SHA3_512 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128String(const Str: string; DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* String ݽӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս + ע D2009 ϰ汾 string Ϊ UnicodeStringлὫǿת AnsiString м㡣 + + + const Str: string - ַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256String(const Str: string; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* String ݽӴճȿɱ SHAKE256 㣬سΪ DigestByteLength ֽΪӴս + ע D2009 ϰ汾 string Ϊ UnicodeStringлὫǿת AnsiString м㡣 + + + const Str: string - ַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHA3_224StringA(const Str: AnsiString): TCnSHA3_224Digest; +{* AnsiString ݽ SHA3_224 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_224StringW(const Str: WideString): TCnSHA3_224Digest; +{* WideString ݽ SHA3_224 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256StringA(const Str: AnsiString): TCnSHA3_256Digest; +{* AnsiString ݽ SHA3_256 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_256StringW(const Str: WideString): TCnSHA3_256Digest; +{* WideStringݽ SHA3_256 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384StringA(const Str: AnsiString): TCnSHA3_384Digest; +{* AnsiString ݽ SHA3_384 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_384StringW(const Str: WideString): TCnSHA3_384Digest; +{* WideString ݽ SHA3_384 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512StringA(const Str: AnsiString): TCnSHA3_512Digest; +{* AnsiString ݽ SHA3_512 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHA3_512StringW(const Str: WideString): TCnSHA3_512Digest; +{* WideString ݽ SHA512 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128StringA(const Str: AnsiString; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* AnsiString ݽӴճȿɱֱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + + + const Str: AnsiString - ַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE128StringW(const Str: WideString; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* WideString ݽӴճȿɱֱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256StringA(const Str: AnsiString; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* AnsiString ݽӴճȿɱֱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + + + const Str: AnsiString - ַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHAKE256StringW(const Str: WideString; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* WideString ݽӴճȿɱֱ SHAKE256 㣬 + سΪ DigestByteLength ֽΪӴս + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +{$IFDEF UNICODE} + +function SHA3_224UnicodeString(const Str: string): TCnSHA3_224Digest; +{* UnicodeString ݽֱӵ SHA3_224 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256UnicodeString(const Str: string): TCnSHA3_256Digest; +{* UnicodeString ݽֱӵ SHA3_256 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384UnicodeString(const Str: string): TCnSHA3_384Digest; +{* UnicodeString ݽֱӵ SHA3_384 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512UnicodeString(const Str: string): TCnSHA3_512Digest; +{* UnicodeString ݽֱӵ SHA3_512 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128UnicodeString(const Str: string; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* UnicodeString ݽӴճȿɱֱ SHAKE128 㣬ֱӼڲ UTF16 ݣת + سΪ DigestByteLength ֽΪӴս + + + const Str: string - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256UnicodeString(const Str: string; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* UnicodeString ݽӴճȿɱֱ SHAKE256 㣬ֱӼڲ UTF16 ݣת + سΪ DigestByteLength ֽΪӴս + + + const Str: string - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +{$ELSE} + +function SHA3_224UnicodeString(const Str: WideString): TCnSHA3_224Digest; +{* UnicodeString ݽֱӵ SHA3_224 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256UnicodeString(const Str: WideString): TCnSHA3_256Digest; +{* UnicodeString ݽֱӵ SHA3_256 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384UnicodeString(const Str: WideString): TCnSHA3_384Digest; +{* UnicodeString ݽֱӵ SHA3_384 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512UnicodeString(const Str: WideString): TCnSHA3_512Digest; +{* UnicodeString ݽֱӵ SHA3_512 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128UnicodeString(const Str: WideString; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* UnicodeString ݽӴճȿɱֱ SHAKE128 㣬ֱӼڲ UTF16 ݣת + سΪ DigestByteLength ֽΪӴս + + + const Str: WideString - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256UnicodeString(const Str: WideString; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* UnicodeString ݽӴճȿɱֱ SHAKE256 㣬ֱӼڲ UTF16 ݣת + سΪ DigestByteLength ֽΪӴս + + + const Str: WideString - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +{$ENDIF} + +function SHA3_224File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = + nil): TCnSHA3_224Digest; +{* ָļݽ SHA3_224 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_224Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): + TCnSHA3_224Digest; +{* ָݽ SHA3_224 㡣 + + + Stream: TStream - + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = + nil): TCnSHA3_256Digest; +{* ָļݽ SHA3_256 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_256Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): + TCnSHA3_256Digest; +{* ָݽ SHA3_256 㡣 + + + Stream: TStream - + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = + nil): TCnSHA3_384Digest; +{* ָļݽ SHA3_384 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_384Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): + TCnSHA3_384Digest; +{* ָݽ SHA3_384 㡣 + + + Stream: TStream - + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = + nil): TCnSHA3_512Digest; +{* ָļݽ SHA3_512 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHA3_512Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): + TCnSHA3_512Digest; +{* ָݽ SHA3_512 㡣 + + + Stream: TStream - + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128File(const FileName: string; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH; + CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; +{* ָļݽӴճȿɱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + + + const FileName: string - ļ + DigestByteLength: Cardinal - Ӵսֽڳ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTBytes - SHAKE128Ӵֵ +} + +function SHAKE128Stream(Stream: TStream; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH; + CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; +{* ָӴճȿɱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + + + Stream: TStream - + DigestByteLength: Cardinal - Ӵսֽڳ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256File(const FileName: string; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH; + CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; +{* ָļݽӴճȿɱ SHAKE256 㣬 + سΪ DigestByteLength ֽΪӴս + + + const FileName: string - ļ + DigestByteLength: Cardinal - Ӵսֽڳ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHAKE256Stream(Stream: TStream; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH; + CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; +{* ָӴճȿɱ SHAKE256 㣬 + سΪ DigestByteLength ֽΪӴս + + + Stream: TStream - + DigestByteLength: Cardinal - Ӵսֽڳ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTBytes - SHAKE256 Ӵֵ +} + +// ⲿݽɢ SHA3_224 㣬SHA3_224Update ɶα + +procedure SHA3_224Init(var Context: TCnSHA3Context); +{* ʼһ SHA3_224 ģ׼ SHA3_224 + + + var Context: TCnSHA3Context - ʼͨ SHA3 + + ֵޣ +} + +procedure SHA3_224Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA3_224 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA3_224Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_224Digest); +{* ּ㣬 SHA3_224 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + var Digest: TCnSHA3_224Digest - ص SHA3_224 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA3_256 㣬SHA3_256Update ɶα + +procedure SHA3_256Init(var Context: TCnSHA3Context); +{* ʼһ SHA3_256 ģ׼ SHA3_256 + + + var Context: TCnSHA3Context - ʼͨ SHA3 + + ֵޣ +} + +procedure SHA3_256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA3_256 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA3_256Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_256Digest); +{* ּ㣬 SHA3_256 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + var Digest: TCnSHA3_256Digest - ص SHA3_256 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA3_384 㣬SHA3_384Update ɶα + +procedure SHA3_384Init(var Context: TCnSHA3Context); +{* ʼһ SHA3_384 ģ׼ SHA3_384 + + + var Context: TCnSHA3Context - ʼͨ SHA3 + + ֵޣ +} + +procedure SHA3_384Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA3_384 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA3_384Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_384Digest); +{* ּ㣬 SHA3_384 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + var Digest: TCnSHA3_384Digest - ص SHA3_384 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA3_512 㣬SHA3_512Update ɶα + +procedure SHA3_512Init(var Context: TCnSHA3Context); +{* ʼһ SHA3_512 ģ׼ SHA3_512 + + + var Context: TCnSHA3Context - ʼͨ SHA3 + + ֵޣ +} + +procedure SHA3_512Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA3_512 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA3_512Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_512Digest); +{* ּ㣬 SHA3_512 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + var Digest: TCnSHA3_512Digest - ص SHA3_512 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHAKE128 㣬SHAKE128Update ɶα + +procedure SHAKE128Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH); +{* ʼһ SHAKE128 ģ׼ SHAKE128 + DigestByteLength ΪӴյֽڳȡ + + + var Context: TCnSHA3Context - ʼͨ SHA3 + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵޣ +} + +procedure SHAKE128Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHAKE128 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHAKE128Final(var Context: TCnSHA3Context; out Digest: TBytes); +{* ּ㣬 SHAKE128 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + out Digest: TBytes - ص SHAKE128 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHAKE128 㣬SHAKE128Update ɶα + +procedure SHAKE256Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH); +{* ʼһ SHAKE256 ģ׼ SHAKE256 + DigestByteLength ΪӴյֽڳȡ + + + var Context: TCnSHA3Context - ʼͨ SHA3 + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵޣ +} + +procedure SHAKE256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHAKE256 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHAKE256Final(var Context: TCnSHA3Context; out Digest: TBytes); +{* ּ㣬 SHAKE256 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + out Digest: TBytes - ص SHAKE256 Ӵֵ + + ֵޣ +} + +function SHA3_224Print(const Digest: TCnSHA3_224Digest): string; +{* ʮƸʽ SHA3_224 Ӵֵ + + + const Digest: TCnSHA3_224Digest - ָ SHA3_224 Ӵֵ + + ֵstring - ʮַ +} + +function SHA3_256Print(const Digest: TCnSHA3_256Digest): string; +{* ʮƸʽ SHA3_256 Ӵֵ + + + const Digest: TCnSHA3_256Digest - ָ SHA3_256 Ӵֵ + + ֵstring - ʮַ +} + +function SHA3_384Print(const Digest: TCnSHA3_384Digest): string; +{* ʮƸʽ SHA3_384 Ӵֵ + + const Digest: TCnSHA3_384Digest - ָ SHA3_384 Ӵֵ + + ֵstring - ʮַ +} + +function SHA3_512Print(const Digest: TCnSHA3_512Digest): string; +{* ʮƸʽ SHA3_512 Ӵֵ + + + const Digest: TCnSHA3_512Digest - ָ SHA3_512 Ӵֵ + + ֵstring - ʮַ +} + +function SHAKE128Print(const Digest: TBytes): string; +{* ʮƸʽ SHAKE128 Ӵֵ + + + const Digest: TBytes - ָ SHAKE128 Ӵֵ + + ֵstring - ʮַ +} + +function SHAKE256Print(const Digest: TBytes): string; +{* ʮƸʽ SHAKE256 Ӵֵ + + + const Digest: TBytes - ָ SHAKE128 Ӵֵ + + ֵstring - ʮַ +} + +function SHA3_224Match(const D1: TCnSHA3_224Digest; const D2: TCnSHA3_224Digest): Boolean; +{* Ƚ SHA3_224 ӴֵǷȡ + + + const D1: TCnSHA3_224Digest - Ƚϵ SHA3_224 Ӵֵһ + const D2: TCnSHA3_224Digest - Ƚϵ SHA3_224 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA3_256Match(const D1: TCnSHA3_256Digest; const D2: TCnSHA3_256Digest): Boolean; +{* Ƚ SHA3_256 ӴֵǷȡ + + + const D1: TCnSHA3_256Digest - Ƚϵ SHA3_256 Ӵֵһ + const D2: TCnSHA3_256Digest - Ƚϵ SHA3_256 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA3_384Match(const D1: TCnSHA3_384Digest; const D2: TCnSHA3_384Digest): Boolean; +{* Ƚ SHA3_384 ӴֵǷȡ + + + const D1: TCnSHA3_384Digest - Ƚϵ SHA3_384 Ӵֵһ + const D2: TCnSHA3_384Digest - Ƚϵ SHA3_384 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA3_512Match(const D1: TCnSHA3_512Digest; const D2: TCnSHA3_512Digest): Boolean; +{* Ƚ SHA3_512 ӴֵǷȡ + + + const D1: TCnSHA3_512Digest - Ƚϵ SHA3_512 Ӵֵһ + const D2: TCnSHA3_512Digest - Ƚϵ SHA3_512 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHAKE128Match(const D1: TBytes; const D2: TBytes): Boolean; +{* Ƚ SHAKE128 ӴֵǷȡ + + + const D1: TBytes - Ƚϵ SHAKE128 Ӵֵһ + const D2: TBytes - Ƚϵ SHAKE128 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHAKE256Match(const D1: TBytes; const D2: TBytes): Boolean; +{* Ƚ SHAKE256 ӴֵǷȡ + + + const D1: TBytes - Ƚϵ SHAKE256 Ӵֵһ + const D2: TBytes - Ƚϵ SHAKE256 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA3_224DigestToStr(const Digest: TCnSHA3_224Digest): string; +{* SHA3_224 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA3_224Digest - ת SHA3_224 Ӵֵ + + ֵstring - صַ +} + +function SHA3_256DigestToStr(const Digest: TCnSHA3_256Digest): string; +{* SHA3_256 Ӵֱֵת stringÿֽڶӦһַ + |
+   Digest: TSHA3_256Digest   - Ҫ
+ |
+ + + const Digest: TCnSHA3_256Digest - ת SHA3_256 Ӵֵ + + ֵstring - صַ +} + +function SHA3_384DigestToStr(const Digest: TCnSHA3_384Digest): string; +{* SHA3_384 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA3_384Digest - ת SHA3_384 Ӵֵ + + ֵstring - صַ +} + +function SHA3_512DigestToStr(const Digest: TCnSHA3_512Digest): string; +{* SHA3_512 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA3_512Digest - ת SHA3_512 Ӵֵ + + ֵstring - صַ +} + +function SHAKE128DigestToStr(const Digest: TBytes): string; +{* SHAKE128 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TBytes - ת SHAKE128 Ӵֵ + + ֵstring - صַ +} + +function SHAKE256DigestToStr(const Digest: TBytes): string; +{* SHAKE256 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TBytes - ת SHAKE256 Ӵֵ + + ֵstring - صַ +} + +procedure SHA3_224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_224Digest); +{* SHA3_224 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA3_224 Կݿַ + KeyByteLength: Integer - SHA3_224 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA3_224Digest - ص SHA3_224 Ӵֵ + + ֵޣ +} + +procedure SHA3_256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_256Digest); +{* SHA3_256 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA3_256 Կݿַ + KeyByteLength: Integer - SHA3_256 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA3_256Digest - ص SHA3_256 Ӵֵ + + ֵޣ +} + +procedure SHA3_384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_384Digest); +{* SHA3_384 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA3_384 Կݿַ + KeyByteLength: Integer - SHA3_384 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA3_384Digest - ص SHA3_384 Ӵֵ + + ֵޣ +} + +procedure SHA3_512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_512Digest); +{* SHA3_512 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA3_512 Կݿַ + KeyByteLength: Integer - SHA3_512 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA3_512Digest - ص SHA3_512 Ӵֵ + + ֵޣ +} + +implementation + +type + TSHA3Type = (stSHA3_224, stSHA3_256, stSHA3_384, stSHA3_512, stSHAKE128, stSHAKE256); + +const + MAX_FILE_SIZE = 512 * 1024 * 1024; + STREAM_BUF_SIZE = 4096 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + SHA3_ROUNDS = 24; + SHA3_STATE_LEN = 25; + + SHA3_224_OUTPUT_LENGTH_BYTE = 28; + SHA3_256_OUTPUT_LENGTH_BYTE = 32; + SHA3_384_OUTPUT_LENGTH_BYTE = 48; + SHA3_512_OUTPUT_LENGTH_BYTE = 64; + + SHA3_224_BLOCK_SIZE_BYTE = 144; + SHA3_256_BLOCK_SIZE_BYTE = 136; + SHA3_384_BLOCK_SIZE_BYTE = 104; + SHA3_512_BLOCK_SIZE_BYTE = 72; + + SHAKE128_BLOCK_SIZE_BYTE = 168; + SHAKE256_BLOCK_SIZE_BYTE = 136; + + HMAC_SHA3_224_BLOCK_SIZE_BYTE = SHA3_224_BLOCK_SIZE_BYTE; + HMAC_SHA3_256_BLOCK_SIZE_BYTE = SHA3_256_BLOCK_SIZE_BYTE; + HMAC_SHA3_384_BLOCK_SIZE_BYTE = SHA3_384_BLOCK_SIZE_BYTE; + HMAC_SHA3_512_BLOCK_SIZE_BYTE = SHA3_512_BLOCK_SIZE_BYTE; + + HMAC_SHA3_224_OUTPUT_LENGTH_BYTE = SHA3_224_OUTPUT_LENGTH_BYTE; + HMAC_SHA3_256_OUTPUT_LENGTH_BYTE = SHA3_256_OUTPUT_LENGTH_BYTE; + HMAC_SHA3_384_OUTPUT_LENGTH_BYTE = SHA3_384_OUTPUT_LENGTH_BYTE; + HMAC_SHA3_512_OUTPUT_LENGTH_BYTE = SHA3_512_OUTPUT_LENGTH_BYTE; + + KECCAKF_ROUND_CONSTS: array[0..23] of TUInt64 = ( + $0000000000000001, $0000000000008082, $800000000000808A, + $8000000080008000, $000000000000808B, $0000000080000001, + $8000000080008081, $8000000000008009, $000000000000008A, + $0000000000000088, $0000000080008009, $000000008000000A, + $000000008000808B, $800000000000008B, $8000000000008089, + $8000000000008003, $8000000000008002, $8000000000000080, + $000000000000800A, $800000008000000A, $8000000080008081, + $8000000000008080, $0000000080000001, $8000000080008008 + ); + + KECCAKF_ROT_CONSTS: array[0..23] of Integer = ( + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 + ); + + KECCAKF_PILN: array[0..23] of Integer = ( + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 + ); + +function ROTL64(Q: TUInt64; N: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (Q shl N) xor (Q shr (64 - N)); +end; + +// һ SHA3 㣬 Block ݣ State +procedure SHA3_Transform(var Context: TCnSHA3Context); +type + PUInt64Array = ^TUInt64Array; + TUInt64Array = array[0..4095] of TUInt64; +var + I, J, R, L: Integer; + P: PUInt64Array; + T: TUInt64; + BC: array[0..4] of TUInt64; +begin + P := PUInt64Array(@(Context.Block[0])); + I := 0; + L := Integer(Context.BlockLen div 8); + while I < L do + begin + Context.State[I] := Context.State[I] xor P^[I]; + Inc(I); + end; + + for R := 0 to Context.Round - 1 do + begin + // Theta + for I := 0 to 4 do + begin + BC[I] := Context.State[I] xor Context.State[I + 5] xor Context.State[I + 10] + xor Context.State[I + 15] xor Context.State[I + 20]; + end; + for I := 0 to 4 do + begin + T := BC[(I + 4) mod 5] xor ROTL64(BC[(I + 1) mod 5], 1); + for J := 0 to 4 do + Context.State[5 * J + I] := Context.State[5 * J + I] xor T; + end; + + // Rho Pi + T := Context.State[1]; + for I := 0 to 23 do + begin + J := KECCAKF_PILN[I]; + BC[0] := Context.State[J]; + Context.State[J] := ROTL64(T, KECCAKF_ROT_CONSTS[I]); + T := BC[0]; + end; + + // Chi + for J := 0 to 4 do + begin + for I := 0 to 4 do + BC[I] := Context.State[5 * J + I]; + + for I := 0 to 4 do + Context.State[5 * J + I] := Context.State[5 * J + I] xor + ((not BC[(I + 1) mod 5]) and BC[(I + 2) mod 5]); + end; + + // Iota + Context.State[0] := Context.State[0] xor KECCAKF_ROUND_CONSTS[R]; + end; +end; + +procedure SHA3Init(var Context: TCnSHA3Context; SHA3Type: TSHA3Type; + DigestByteLength: Cardinal = 0); +begin + FillChar(Context.State, SizeOf(Context.State), 0); + FillChar(Context.Block, SizeOf(Context.Block), 0); + Context.Index := 0; + Context.Round := SHA3_ROUNDS; + + case SHA3Type of + stSHA3_224: + begin + Context.BlockLen := SHA3_224_BLOCK_SIZE_BYTE; + Context.DigestLen := SHA3_224_OUTPUT_LENGTH_BYTE; + end; + stSHA3_256: + begin + Context.BlockLen := SHA3_256_BLOCK_SIZE_BYTE; + Context.DigestLen := SHA3_256_OUTPUT_LENGTH_BYTE; + end; + stSHA3_384: + begin + Context.BlockLen := SHA3_384_BLOCK_SIZE_BYTE; + Context.DigestLen := SHA3_384_OUTPUT_LENGTH_BYTE; + end; + stSHA3_512: + begin + Context.BlockLen := SHA3_512_BLOCK_SIZE_BYTE; + Context.DigestLen := SHA3_512_OUTPUT_LENGTH_BYTE; + end; + stSHAKE128: + begin + Context.BlockLen := SHAKE128_BLOCK_SIZE_BYTE; + Context.DigestLen := DigestByteLength; + end; + stSHAKE256: + begin + Context.BlockLen := SHAKE256_BLOCK_SIZE_BYTE; + Context.DigestLen := DigestByteLength; + end; + end; +end; + +procedure SHA3Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +var + R, Idx: Cardinal; +begin + Idx := Context.Index; // Index Block еijʼλָ + repeat + if ByteLength < Context.BlockLen - Idx then + R := ByteLength //  + else + R := Context.BlockLen - Idx; // ܻʣ + + FillChar(Context.Block[Idx], SizeOf(Context.Block) - Idx, 0); // ȷβΪ 0 + Move(Input^, Context.Block[Idx], R); // Block ǰ벿ֲ + + if (Idx + R) < Context.BlockLen then // ûֲ + begin // ֻ Index λָ + Idx := Idx + R; + Break; + end; + + SHA3_Transform(Context); + Dec(ByteLength, R); + Idx := 0; + Inc(Input, R); + until False; + Context.Index := Idx; +end; + +procedure SHA3UpdateW(var Context: TCnSHA3Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + Content: PAnsiChar; + Len: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(Content, CharLength * SizeOf(WideChar)); + try + Len := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(Content), CharLength * SizeOf(WideChar), nil, nil); + SHA3Update(Context, Content, Len); + finally + FreeMem(Content); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SHA3Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +// SHA3_224/256/384/512 ר +procedure SHA3Final(var Context: TCnSHA3Context; var Digest: TCnSHA3GeneralDigest); overload; +begin + Context.Block[Context.Index] := 6; + Context.Block[Context.BlockLen - 1] := Context.Block[Context.BlockLen - 1] or $80; + SHA3_Transform(Context); + Move(Context.State[0], Digest[0], Context.DigestLen); +end; + +// SHAKE128 SHAKE256 ר +procedure SHA3Final(var Context: TCnSHA3Context; out Digest: TBytes); overload; +var + Idx, DL: Cardinal; +begin + Context.Block[Context.Index] := $1F; + Context.Block[Context.BlockLen - 1] := Context.Block[Context.BlockLen - 1] or $80; + SHA3_Transform(Context); + + SetLength(Digest, Context.DigestLen); + if Context.DigestLen <= Context.BlockLen then + Move(Context.State[0], Digest[0], Context.DigestLen) + else + begin + DL := Context.DigestLen; + Idx := 0; + + while DL >= Context.BlockLen do + begin + Move(Context.State[0], Digest[Idx], Context.BlockLen); + Inc(Idx, Context.BlockLen); + Dec(DL, Context.BlockLen); + + if DL > 0 then + begin + FillChar(Context.Block[0], SizeOf(Context.Block), 0); + SHA3_Transform(Context); + end; + end; + + if DL > 0 then + Move(Context.State[0], Digest[Idx], DL); + end; +end; + +procedure SHA3_224Init(var Context: TCnSHA3Context); +begin + SHA3Init(Context, stSHA3_224); +end; + +procedure SHA3_224Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_224Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_224Digest); +var + Res: TCnSHA3GeneralDigest; +begin + SHA3Final(Context, Res); + Move(Res[0], Digest[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +procedure SHA3_256Init(var Context: TCnSHA3Context); +begin + SHA3Init(Context, stSHA3_256); +end; + +procedure SHA3_256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_256Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_256Digest); +var + Res: TCnSHA3GeneralDigest; +begin + SHA3Final(Context, Res); + Move(Res[0], Digest[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +procedure SHA3_384Init(var Context: TCnSHA3Context); +begin + SHA3Init(Context, stSHA3_384); +end; + +procedure SHA3_384Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_384Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_384Digest); +var + Res: TCnSHA3GeneralDigest; +begin + SHA3Final(Context, Res); + Move(Res[0], Digest[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +procedure SHA3_512Init(var Context: TCnSHA3Context); +begin + SHA3Init(Context, stSHA3_512); +end; + +procedure SHA3_512Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_512Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_512Digest); +var + Res: TCnSHA3GeneralDigest; +begin + SHA3Final(Context, Res); + Move(Res[0], Digest[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +procedure SHAKE128Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal); +begin + SHA3Init(Context, stSHAKE128, DigestByteLength); +end; + +procedure SHAKE128Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHAKE128Final(var Context: TCnSHA3Context; out Digest: TBytes); +begin + SHA3Final(Context, Digest); +end; + +procedure SHAKE256Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal); +begin + SHA3Init(Context, stSHAKE256, DigestByteLength); +end; + +procedure SHAKE256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHAKE256Final(var Context: TCnSHA3Context; out Digest: TBytes); +begin + SHA3Final(Context, Digest); +end; + +// ݿ SHA3_224λ +function SHA3_224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, Input, ByteLength); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_256λ +function SHA3_256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, Input, ByteLength); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_384λ +function SHA3_384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, Input, ByteLength); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_512λ +function SHA3_512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, Input, ByteLength); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_224 +function SHA3_224Buffer(const Buffer; Count: Cardinal): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, PAnsiChar(Buffer), Count); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_256 +function SHA3_256Buffer(const Buffer; Count: Cardinal): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, PAnsiChar(Buffer), Count); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_384 +function SHA3_384Buffer(const Buffer; Count: Cardinal): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, PAnsiChar(Buffer), Count); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_512 +function SHA3_512Buffer(const Buffer; Count: Cardinal): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, PAnsiChar(Buffer), Count); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHAKE128 +function SHAKE128Buffer(const Buffer; Count: Cardinal; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHAKE128Update(Context, PAnsiChar(Buffer), Count); + SHAKE128Final(Context, Result); +end; + +// ݿ SHAKE256 +function SHAKE256Buffer(const Buffer; Count: Cardinal; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHAKE256Update(Context, PAnsiChar(Buffer), Count); + SHAKE256Final(Context, Result); +end; + +// ֽ SHA3_224 +function SHA3_224Bytes(Data: TBytes): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// ֽ SHA3_256 +function SHA3_256Bytes(Data: TBytes): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// ֽ SHA3_384 +function SHA3_384Bytes(Data: TBytes): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// ֽ SHA3_512 +function SHA3_512Bytes(Data: TBytes): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// ֽ SHAKE128 +function SHAKE128Bytes(Data: TBytes; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHAKE128Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHAKE128Final(Context, Result); +end; + +// ֽ SHAKE256 +function SHAKE256Bytes(Data: TBytes; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHAKE256Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHAKE256Final(Context, Result); +end; + +// String ݽ SHA3_224 +function SHA3_224String(const Str: string): TCnSHA3_224Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA3_224StringA(AStr); +end; + +// String ݽ SHA3_256 +function SHA3_256String(const Str: string): TCnSHA3_256Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA3_256StringA(AStr); +end; + +// String ݽ SHA3_384 +function SHA3_384String(const Str: string): TCnSHA3_384Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA3_384StringA(AStr); +end; + +// String ݽ SHA3_512 +function SHA3_512String(const Str: string): TCnSHA3_512Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA3_512StringA(AStr); +end; + +// String ݽ SHAKE128 +function SHAKE128String(const Str: string; DigestByteLength: Cardinal): TBytes; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHAKE128StringA(AStr, DigestByteLength); +end; + +// String ݽ SHAKE256 +function SHAKE256String(const Str: string; DigestByteLength: Cardinal): TBytes; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHAKE256StringA(AStr, DigestByteLength); +end; + +// UnicodeString ݽֱӵ SHA3_224 㣬ת +{$IFDEF UNICODE} +function SHA3_224UnicodeString(const Str: string): TCnSHA3_224Digest; +{$ELSE} +function SHA3_224UnicodeString(const Str: WideString): TCnSHA3_224Digest; +{$ENDIF} +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// UnicodeString ݽֱӵ SHA3_256 㣬ת +{$IFDEF UNICODE} +function SHA3_256UnicodeString(const Str: string): TCnSHA3_256Digest; +{$ELSE} +function SHA3_256UnicodeString(const Str: WideString): TCnSHA3_256Digest; +{$ENDIF} +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// UnicodeString ݽֱӵ SHA3_384 㣬ת +{$IFDEF UNICODE} +function SHA3_384UnicodeString(const Str: string): TCnSHA3_384Digest; +{$ELSE} +function SHA3_384UnicodeString(const Str: WideString): TCnSHA3_384Digest; +{$ENDIF} +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// UnicodeString ݽֱӵ SHA3_512 㣬ת +{$IFDEF UNICODE} +function SHA3_512UnicodeString(const Str: string): TCnSHA3_512Digest; +{$ELSE} +function SHA3_512UnicodeString(const Str: WideString): TCnSHA3_512Digest; +{$ENDIF} +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// UnicodeString ݽֱӵ SHAKE128 㣬ת +{$IFDEF UNICODE} +function SHAKE128UnicodeString(const Str: string; DigestByteLength: Cardinal): TBytes; +{$ELSE} +function SHAKE128UnicodeString(const Str: WideString; DigestByteLength: Cardinal): TBytes; +{$ENDIF} +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHAKE128Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHAKE128Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SHAKE256 㣬ת +{$IFDEF UNICODE} +function SHAKE256UnicodeString(const Str: string; DigestByteLength: Cardinal): TBytes; +{$ELSE} +function SHAKE256UnicodeString(const Str: WideString; DigestByteLength: Cardinal): TBytes; +{$ENDIF} +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHAKE256Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHAKE256Final(Context, Result); +end; + +// AnsiString ݽSHA224 +function SHA3_224StringA(const Str: AnsiString): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, PAnsiChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// WideString ݽ SHA3_224 +function SHA3_224StringW(const Str: WideString): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// AnsiString ݽ SHA3_256 +function SHA3_256StringA(const Str: AnsiString): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, PAnsiChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// WideString ݽ SHA3_256 +function SHA3_256StringW(const Str: WideString): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// AnsiString ݽ SHA3_384 +function SHA3_384StringA(const Str: AnsiString): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, PAnsiChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// WideString ݽ SHA3_384 +function SHA3_384StringW(const Str: WideString): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// AnsiString ݽ SHA3_512 +function SHA3_512StringA(const Str: AnsiString): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, PAnsiChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// WideString ݽ SHA3_512 +function SHA3_512StringW(const Str: WideString): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// AnsiString ݽ SHAKE128 +function SHAKE128StringA(const Str: AnsiString; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHAKE128Update(Context, PAnsiChar(Str), Length(Str)); + SHAKE128Final(Context, Result); +end; + +// WideString ݽ SHAKE128 +function SHAKE128StringW(const Str: WideString; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); // SHAKE128UpdateW = SHA3UpdateW + SHAKE128Final(Context, Result); +end; + +// AnsiString ݽ SHAKE256 +function SHAKE256StringA(const Str: AnsiString; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHAKE256Update(Context, PAnsiChar(Str), Length(Str)); + SHAKE256Final(Context, Result); +end; + +// WideString ݽ SHAKE256 +function SHAKE256StringW(const Str: WideString; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); // SHAKE256UpdateW = SHA3UpdateW + SHAKE256Final(Context, Result); +end; + +// SHA3Type ֻ stSHA3_224, stSHA3_256, stSHA3_384, stSHA3_512 +function InternalSHA3Stream(Stream: TStream; const BufSize: Cardinal; var D: + TCnSHA3GeneralDigest; SHA3Type: TSHA3Type; CallBack: TCnSHA3CalcProgressFunc): Boolean; overload; +var + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; + Context: TCnSHA3Context; +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then + Exit; + if Size < BufSize then + BufLen := Size + else + BufLen := BufSize; + + CancelCalc := False; + SHA3Init(Context, SHA3Type); + + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + SHA3Update(Context, Buf, ReadBytes); + + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then + Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + SHA3Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// SHA3Type ֻ stSHAKE128 stSHAKE256 +function InternalSHA3Stream(Stream: TStream; const BufSize: Cardinal; + SHA3Type: TSHA3Type; DigestByteLength: Cardinal; out D: TBytes; + CallBack: TCnSHA3CalcProgressFunc): Boolean; overload; +var + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; + Context: TCnSHA3Context; +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then + Exit; + if Size < BufSize then + BufLen := Size + else + BufLen := BufSize; + + CancelCalc := False; + SHA3Init(Context, SHA3Type, DigestByteLength); + + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + SHA3Update(Context, Buf, ReadBytes); + + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then + Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + SHA3Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ָ SHA3_224 +function SHA3_224Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_224Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_224, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_224Digest)); +end; + +// ָ SHA3_256 +function SHA3_256Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_256Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_256, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_256Digest)); +end; + +// ָ SHA3_384 +function SHA3_384Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_384Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_384, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_384Digest)); +end; + +// ָ SHA3_512 +function SHA3_512Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_512Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_512, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_512Digest)); +end; + +// ָӴճȿɱ SHAKE128 +function SHAKE128Stream(Stream: TStream; DigestByteLength: Cardinal; + CallBack: TCnSHA3CalcProgressFunc): TBytes; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, stSHAKE128, DigestByteLength, Result, CallBack); +end; + +// ָӴճȿɱ SHAKE256 +function SHAKE256Stream(Stream: TStream; DigestByteLength: Cardinal; + CallBack: TCnSHA3CalcProgressFunc): TBytes; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, stSHAKE256, DigestByteLength, Result, CallBack); +end; + +function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} +var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec: Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(AFileName), GENERIC_READ, FILE_SHARE_READ, nil, + OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then + Exit; + try + if not GetFileInformationByHandle(H, Info) then + Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} +end; + +function InternalSHA3File(const FileName: string; SHA3Type: TSHA3Type; + CallBack: TCnSHA3CalcProgressFunc): TCnSHA3GeneralDigest; overload; +var +{$IFDEF MSWINDOWS} + Context: TCnSHA3Context; + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Result, SHA3Type, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + SHA3Init(Context, SHA3Type); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + SHA3Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + SHA3Final(Context, Result); +{$ENDIF} + end; +end; + +function InternalSHA3File(const FileName: string; SHA3Type: TSHA3Type; + DigestByteLength: Cardinal; CallBack: TCnSHA3CalcProgressFunc): TBytes; overload; +var +{$IFDEF MSWINDOWS} + Context: TCnSHA3Context; + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, SHA3Type, DigestByteLength, Result, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + SHA3Init(Context, SHA3Type, DigestByteLength); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + SHA3Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + SHA3Final(Context, Result); +{$ENDIF} + end; +end; + +// ָļݽ SHA3_224 +function SHA3_224File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_224Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + Dig := InternalSHA3File(FileName, stSHA3_224, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_224Digest)); +end; + +// ָļݽ SHA3_256 +function SHA3_256File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_256Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + Dig := InternalSHA3File(FileName, stSHA3_256, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_256Digest)); +end; + +// ָļݽ SHA3_384 +function SHA3_384File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_384Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + Dig := InternalSHA3File(FileName, stSHA3_384, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_384Digest)); +end; + +// ָļݽ SHA3_512 +function SHA3_512File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_512Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + Dig := InternalSHA3File(FileName, stSHA3_512, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_512Digest)); +end; + +// ָļݽӴճȿɱ SHAKE128 +function SHAKE128File(const FileName: string; DigestByteLength: Cardinal; + CallBack: TCnSHA3CalcProgressFunc): TBytes; +begin + Result := InternalSHA3File(FileName, stSHAKE128, DigestByteLength, CallBack); +end; + +// ָļݽӴճȿɱ SHAKE256 +function SHAKE256File(const FileName: string; DigestByteLength: Cardinal; + CallBack: TCnSHA3CalcProgressFunc): TBytes; +begin + Result := InternalSHA3File(FileName, stSHAKE256, DigestByteLength, CallBack); +end; + +// ʮƸʽ SHA3_224 Ӵֵ +function SHA3_224Print(const Digest: TCnSHA3_224Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_224Digest)); +end; + +// ʮƸʽ SHA3_256 Ӵֵ +function SHA3_256Print(const Digest: TCnSHA3_256Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_256Digest)); +end; + +// ʮƸʽ SHA3_384 Ӵֵ +function SHA3_384Print(const Digest: TCnSHA3_384Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_384Digest)); +end; + +// ʮƸʽ SHA3_512 Ӵֵ +function SHA3_512Print(const Digest: TCnSHA3_512Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_512Digest)); +end; + +// ʮƸʽ SHAKE128 Ӵֵ +function SHAKE128Print(const Digest: TBytes): string; +begin + Result := BytesToHex(Digest); +end; + +// ʮƸʽ SHAKE256 Ӵֵ +function SHAKE256Print(const Digest: TBytes): string; +begin + Result := BytesToHex(Digest); +end; + +// Ƚ SHA3_224 ӴֵǷ +function SHA3_224Match(const D1, D2: TCnSHA3_224Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_224Digest)); +end; + +// Ƚ SHA3_256 ӴֵǷ +function SHA3_256Match(const D1, D2: TCnSHA3_256Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_256Digest)); +end; + +// Ƚ SHA3_384 ӴֵǷ +function SHA3_384Match(const D1, D2: TCnSHA3_384Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_384Digest)); +end; + +// Ƚ SHA3_512 ӴֵǷ +function SHA3_512Match(const D1, D2: TCnSHA3_512Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_512Digest));; +end; + +// Ƚ SHAKE128 ӴֵǷ +function SHAKE128Match(const D1, D2: TBytes): Boolean; +begin + Result := CompareBytes(D1, D2); +end; + +// Ƚ SHAKE256 ӴֵǷ +function SHAKE256Match(const D1, D2: TBytes): Boolean; +begin + Result := CompareBytes(D1, D2); +end; + +// SHA3_224 Ӵֵת string +function SHA3_224DigestToStr(const Digest: TCnSHA3_224Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_224Digest)); +end; + +// SHA3_256 Ӵֵת string +function SHA3_256DigestToStr(const Digest: TCnSHA3_256Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_256Digest));; +end; + +// SHA3_384 Ӵֵת string +function SHA3_384DigestToStr(const Digest: TCnSHA3_384Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_384Digest)); +end; + +// SHA3_512 Ӵֵת string +function SHA3_512DigestToStr(const Digest: TCnSHA3_512Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_512Digest)); +end; + +// SHAKE128 Ӵֵת string +function SHAKE128DigestToStr(const Digest: TBytes): string; +begin + Result := BytesToString(Digest); +end; + +// SHAKE256 Ӵֵת string +function SHAKE256DigestToStr(const Digest: TBytes): string; +begin + Result := BytesToString(Digest); +end; + +procedure SHA3_224HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA3_224Digest; +begin + if KeyLength > HMAC_SHA3_224_BLOCK_SIZE_BYTE then + begin + Sum := SHA3_224Buffer(Key, KeyLength); + KeyLength := HMAC_SHA3_224_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA3_224_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA3_224_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_224_BLOCK_SIZE_BYTE); +end; + +procedure SHA3_256HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA3_256Digest; +begin + if KeyLength > HMAC_SHA3_256_BLOCK_SIZE_BYTE then + begin + Sum := SHA3_256Buffer(Key, KeyLength); + KeyLength := HMAC_SHA3_256_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA3_256_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA3_256_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_256_BLOCK_SIZE_BYTE); +end; + +procedure SHA3_384HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA3_384Digest; +begin + if KeyLength > HMAC_SHA3_384_BLOCK_SIZE_BYTE then + begin + Sum := SHA3_384Buffer(Key, KeyLength); + KeyLength := HMAC_SHA3_384_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA3_384_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA3_384_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_384_BLOCK_SIZE_BYTE); +end; + +procedure SHA3_512HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA3_512Digest; +begin + if KeyLength > HMAC_SHA3_512_BLOCK_SIZE_BYTE then + begin + Sum := SHA3_512Buffer(Key, KeyLength); + KeyLength := HMAC_SHA3_512_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA3_512_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA3_512_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_512_BLOCK_SIZE_BYTE); +end; + +procedure SHA3_224HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; + ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_256HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; + ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_384HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; + ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_512HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; + ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_224HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); +var + Len: Integer; + TmpBuf: TCnSHA3GeneralDigest; +begin + Len := HMAC_SHA3_224_OUTPUT_LENGTH_BYTE; + SHA3Final(Context, TmpBuf); + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_224_BLOCK_SIZE_BYTE); + SHA3Update(Context, @(TmpBuf[0]), Len); + SHA3Final(Context, Output); +end; + +procedure SHA3_256HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); +var + Len: Integer; + TmpBuf: TCnSHA3GeneralDigest; +begin + Len := HMAC_SHA3_256_OUTPUT_LENGTH_BYTE; + SHA3Final(Context, TmpBuf); + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_256_BLOCK_SIZE_BYTE); + SHA3Update(Context, @(TmpBuf[0]), Len); + SHA3Final(Context, Output); +end; + +procedure SHA3_384HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); +var + Len: Integer; + TmpBuf: TCnSHA3GeneralDigest; +begin + Len := HMAC_SHA3_384_OUTPUT_LENGTH_BYTE; + SHA3Final(Context, TmpBuf); + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_384_BLOCK_SIZE_BYTE); + SHA3Update(Context, @(TmpBuf[0]), Len); + SHA3Final(Context, Output); +end; + +procedure SHA3_512HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); +var + Len: Integer; + TmpBuf: TCnSHA3GeneralDigest; +begin + Len := HMAC_SHA3_512_OUTPUT_LENGTH_BYTE; + SHA3Final(Context, TmpBuf); + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_512_BLOCK_SIZE_BYTE); + SHA3Update(Context, @(TmpBuf[0]), Len); + SHA3Final(Context, Output); +end; + +procedure SHA3_224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_224Digest); +var + Context: TCnSHA3Context; + Dig: TCnSHA3GeneralDigest; +begin + SHA3_224HmacInit(Context, Key, KeyByteLength); + SHA3_224HmacUpdate(Context, Input, ByteLength); + SHA3_224HmacFinal(Context, Dig); + Move(Dig[0], Output[0], Context.DigestLen); +end; + +procedure SHA3_256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_256Digest); +var + Context: TCnSHA3Context; + Dig: TCnSHA3GeneralDigest; +begin + SHA3_256HmacInit(Context, Key, KeyByteLength); + SHA3_256HmacUpdate(Context, Input, ByteLength); + SHA3_256HmacFinal(Context, Dig); + Move(Dig[0], Output[0], Context.DigestLen); +end; + +procedure SHA3_384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_384Digest); +var + Context: TCnSHA3Context; + Dig: TCnSHA3GeneralDigest; +begin + SHA3_384HmacInit(Context, Key, KeyByteLength); + SHA3_384HmacUpdate(Context, Input, ByteLength); + SHA3_384HmacFinal(Context, Dig); + Move(Dig[0], Output[0], Context.DigestLen); +end; + +procedure SHA3_512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_512Digest); +var + Context: TCnSHA3Context; + Dig: TCnSHA3GeneralDigest; +begin + SHA3_512HmacInit(Context, Key, KeyByteLength); + SHA3_512HmacUpdate(Context, Input, ByteLength); + SHA3_512HmacFinal(Context, Dig); + Move(Dig[0], Output[0], Context.DigestLen); +end; + +end. diff --git a/CnPack/Crypto/CnSM3.pas b/CnPack/Crypto/CnSM3.pas index 53106c6..ba4e680 100644 --- a/CnPack/Crypto/CnSM3.pas +++ b/CnPack/Crypto/CnSM3.pas @@ -1,829 +1,829 @@ -{******************************************************************************} -{ CnPack For Delphi/C++Builder } -{ йԼĿԴ } -{ (C)Copyright 2001-2025 CnPack } -{ ------------------------------------ } -{ } -{ ǿԴ CnPack ķЭ } -{ ĺ·һ } -{ } -{ һĿϣãûκεû } -{ ʺضĿĶĵϸ CnPack Э顣 } -{ } -{ ӦѾͿһյһ CnPack Эĸ } -{ ûУɷǵվ } -{ } -{ վַhttps://www.cnpack.org } -{ ʼmaster@cnpack.org } -{ } -{******************************************************************************} - -unit CnSM3; -{* |
-================================================================================
-* ƣ
-* Ԫƣ SM3 Ӵ㷨ʵֵԪ
-* ԪߣCnPack 飨master@cnpack.org)
-*           οֲ goldboar  C 
-*     עԪʵ˹ SM3 Ӵ㷨Ӧ HMAC 㷨
-*           ο㷨ĵSM3 Cryptographic Hash Algorith
-*           http://www.oscca.gov.cn/UpFile/20101222141857786.pdf
-*
-* ƽ̨Windows 7 + Delphi 5.0
-* ݲԣPWin9X/2000/XP/7 + Delphi 5/6
-*   õԪеַϱػʽ
-* ޸ļ¼2019.12.12 V1.2
-*               ֧ TBytes
-*           2019.04.15 V1.1
-*               ֧ Win32/Win64/MacOS
-*           2014.09.23 V1.0
-*               ֲԪ
-================================================================================
-|
} - -interface - -{$I CnPack.inc} - -uses - Classes, SysUtils, CnNative, CnConsts {$IFDEF MSWINDOWS}, Windows {$ENDIF}; - -type - PCnSM3Digest = ^TCnSM3Digest; - TCnSM3Digest = array[0..31] of Byte; - {* SM3 Ӵս32 ֽ} - - TCnSM3Context = packed record - {* SM3 Ľṹ} - Total: array[0..1] of Cardinal; {!< number of bytes processed } - State: array[0..7] of Cardinal; {!< intermediate digest state } - Buffer: array[0..63] of Byte; {!< data block being processed } - Ipad: array[0..63] of Byte; {!< HMAC: inner padding } - Opad: array[0..63] of Byte; {!< HMAC: outer padding } - end; - PCnSM3Context = ^TCnSM3Context; - - TCnSM3CalcProgressFunc = procedure (ATotal, AProgress: Int64; - var Cancel: Boolean) of object; - {* SM3 ӴսȻص¼} - -function SM3(Input: PAnsiChar; ByteLength: Cardinal): TCnSM3Digest; -{* ݿ SM3 㡣 - - - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵTCnSM3Digest - ص SM3 Ӵֵ - - } - -function SM3Buffer(const Buffer; Count: Cardinal): TCnSM3Digest; -{* ݿ SM3 㡣 - - - const Buffer - ݿַ - Count: Cardinal - ݿֽڳ - - ֵTCnSM3Digest - ص SM3 Ӵֵ -} - -function SM3Bytes(Data: TBytes): TCnSM3Digest; -{* ֽ SM3 㡣 - - - Data: TBytes - ֽ - - ֵTCnSM3Digest - ص SM3 Ӵֵ -} - -function SM3String(const Str: string): TCnSM3Digest; -{* String ݽ SM3 㣬ע D2009 ϰ汾 string Ϊ UnicodeString - лὫǿת AnsiString м㡣 - - - const Str: string - ַ - - ֵTCnSM3Digest - ص SM3 Ӵֵ -} - -function SM3StringA(const Str: AnsiString): TCnSM3Digest; -{* AnsiString ݽ SM3 㡣 - - - const Str: AnsiString - ַ - - ֵTCnSM3Digest - ص SM3 Ӵֵ -} - -function SM3StringW(const Str: WideString): TCnSM3Digest; -{* WideString ַת SM3 㡣 - ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ - ƽֱ̨תΪ AnsiString ͣٽм㡣 - - - const Str: WideString - Ŀַ - - ֵTCnSM3Digest - ص SM3 Ӵֵ -} - -{$IFDEF UNICODE} - -function SM3UnicodeString(const Str: string): TCnSM3Digest; -{* UnicodeString ݽֱӵ SM3 㣬ֱӼڲ UTF16 ݣת - - - const Str: string - Ŀַ - - ֵTCnSM3Digest - ص SM3 Ӵֵ -} - -{$ELSE} - -function SM3UnicodeString(const Str: WideString): TCnSM3Digest; -{* UnicodeString ݽֱӵ SM3 㣬ֱӼڲ UTF16 ݣת - - - const Str: WideString - Ŀַ - - ֵTCnSM3Digest - ص SM3 Ӵֵ -} - -{$ENDIF} - -function SM3File(const FileName: string; CallBack: TCnSM3CalcProgressFunc = nil): TCnSM3Digest; -{* ָļݽ SM3 㡣 - - - const FileName: string - ļ - CallBack: TCnSM3CalcProgressFunc - ȻصĬΪ - - ֵTCnSM3Digest - ص SM3 Ӵֵ -} - -function SM3Stream(Stream: TStream; CallBack: TCnSM3CalcProgressFunc = nil): TCnSM3Digest; -{* ָݽ SM3 㡣 - - - Stream: TStream - - CallBack: TCnSM3CalcProgressFunc - ȻصĬΪ - - ֵTCnSM3Digest - ص SM3 Ӵֵ -} - -// ⲿݽɢ SM3 㣬SM3Update ɶα - -procedure SM3Init(var Context: TCnSM3Context); -{* ʼһ SM3 ģ׼ SM3 - - - var Context: TCnSM3Context - ʼ SM3 - - ֵޣ -} - -procedure SM3Update(var Context: TCnSM3Context; Input: PAnsiChar; ByteLength: Cardinal); -{* ԳʼĶһݽ SM3 㡣 - ɶε㲻ͬݿ飬轫ͬݿƴڴС - - - var Context: TCnSM3Context - SM3 - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - - ֵޣ -} - -procedure SM3Final(var Context: TCnSM3Context; var Digest: TCnSM3Digest); -{* ּ㣬 SM3 Digest - - - var Context: TCnSM3Context - SM3 - var Digest: TCnSM3Digest - ص SM3 Ӵֵ - - ֵޣ -} - -function SM3Print(const Digest: TCnSM3Digest): string; -{* ʮƸʽ SM3 Ӵֵ - - - const Digest: TCnSM3Digest - ָ SM3 Ӵֵ - - ֵstring - ʮַ -} - -function SM3Match(const D1: TCnSM3Digest; const D2: TCnSM3Digest): Boolean; -{* Ƚ SM3 ӴֵǷȡ - - - const D1: TCnSM3Digest - Ƚϵ SM3 Ӵֵһ - const D2: TCnSM3Digest - Ƚϵ SM3 Ӵֵ - - ֵBoolean - Ƿ -} - -function SM3DigestToStr(const Digest: TCnSM3Digest): string; -{* SM3 Ӵֱֵת stringÿֽڶӦһַ - - - const Digest: TCnSM3Digest - ת SM3 Ӵֵ - - ֵstring - صַ -} - -procedure SM3Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSM3Digest); -{* SM3 HMACHash-based Message Authentication Code㣬 - ͨݵļϼԿĸҲмΡ - - - Key: PAnsiChar - SM3 Կݿַ - KeyByteLength: Integer - SM3 Կݿֽڳ - Input: PAnsiChar - ݿַ - ByteLength: Cardinal - ݿֽڳ - var Output: TCnSM3Digest - ص SM3 Ӵֵ - - ֵޣ -} - -implementation - -const - SM3Padding: array[0..63] of Byte = - ( - $80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ); - - SM3_T: array[0..63] of Cardinal = ( - $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, - $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, - $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, - $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, - $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, - $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, - $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, - $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A - ); - - MAX_FILE_SIZE = 512 * 1024 * 1024; - // If file size <= this size (bytes), using Mapping, else stream - - HMAC_SM3_BLOCK_SIZE_BYTE = 64; - HMAC_SM3_OUTPUT_LENGTH_BYTE = 32; - -type - TSM3ProcessData = array[0..63] of Byte; - -procedure GetULongBe(var N: Cardinal; B: PAnsiChar; I: Integer); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -var - D: Cardinal; -begin - D := (Cardinal(B[I]) shl 24) or (Cardinal(B[I + 1]) shl 16) or - (Cardinal(B[I + 2]) shl 8) or (Cardinal(B[I + 3])); - N := D; -end; - -procedure PutULongBe(N: Cardinal; B: PAnsiChar; I: Integer); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - B[I] := AnsiChar(N shr 24); - B[I + 1] := AnsiChar(N shr 16); - B[I + 2] := AnsiChar(N shr 8); - B[I + 3] := AnsiChar(N); -end; - -function FF0(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := X xor Y xor Z; -end; - -function FF1(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (X and Y) or (Y and Z) or (X and Z); -end; - -function GG0(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := X xor Y xor Z; -end; - -function GG1(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (X and Y) or ((not X) and Z); -end; - -function SM3Shl(X: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := (X and $FFFFFFFF) shl N; -end; - -// ѭơע N Ϊ 0 32 ʱֵΪ XN Ϊ 33 ʱֵ N Ϊ 1 ʱķֵ -function ROTL(X: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := SM3Shl(X, N) or (X shr (32 - N)); -end; - -function P0(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := X xor ROTL(X, 9) xor ROTL(X, 17); -end; - -function P1(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} -begin - Result := X xor ROTL(X, 15) xor ROTL(X, 23); -end; - -procedure SM3Init(var Context: TCnSM3Context); -begin - Context.Total[0] := 0; - Context.Total[1] := 0; - - Context.State[0] := $7380166F; - Context.State[1] := $4914B2B9; - Context.State[2] := $172442D7; - Context.State[3] := $DA8A0600; - Context.State[4] := $A96F30BC; - Context.State[5] := $163138AA; - Context.State[6] := $E38DEE4D; - Context.State[7] := $B0FB0E4E; - - FillChar(Context.Buffer, SizeOf(Context.Buffer), 0); -end; - -// һδ 64 ֽҲ 512 λݿ -procedure SM3Process(var Context: TCnSM3Context; Data: PAnsiChar); -var - SS1, SS2, TT1, TT2: Cardinal; - W: array[0..67] of Cardinal; - W1: array[0..63] of Cardinal; - A, B, C, D, E, F, G, H: Cardinal; - Temp1, Temp2: Cardinal; - J: Integer; -begin - GetULongBe(W[ 0], Data, 0); - GetULongBe(W[ 1], Data, 4); - GetULongBe(W[ 2], Data, 8); - GetULongBe(W[ 3], Data, 12); - GetULongBe(W[ 4], Data, 16); - GetULongBe(W[ 5], Data, 20); - GetULongBe(W[ 6], Data, 24); - GetULongBe(W[ 7], Data, 28); - GetULongBe(W[ 8], Data, 32); - GetULongBe(W[ 9], Data, 36); - GetULongBe(W[10], Data, 40); - GetULongBe(W[11], Data, 44); - GetULongBe(W[12], Data, 48); - GetULongBe(W[13], Data, 52); - GetULongBe(W[14], Data, 56); - GetULongBe(W[15], Data, 60); - - for J := 16 to 67 do - begin - Temp1 := W[J - 16] xor W[J - 9]; - Temp2 := ROTL(W[J - 3], 15); - W[J] := P1(Temp1 xor Temp2) xor (ROTL(W[J - 13], 7) xor W[J - 6]); - end; - - for J := 0 to 63 do - W1[J] := W[J] xor W[J + 4]; - - // ѾW/W1ֵ - - A := Context.State[0]; - B := Context.State[1]; - C := Context.State[2]; - D := Context.State[3]; - E := Context.State[4]; - F := Context.State[5]; - G := Context.State[6]; - H := Context.State[7]; - - for J := 0 to 15 do - begin - SS1 := ROTL((ROTL(A, 12) + E + ROTL(SM3_T[J], J)), 7); - SS2 := SS1 xor ROTL(A, 12); - TT1 := FF0(A, B, C) + D + SS2 + W1[J]; - TT2 := GG0(E, F, G) + H + SS1 + W[J]; - D := C; - C := ROTL(B, 9); - B := A; - A := TT1; - H := G; - G := ROTL(F, 19); - F := E; - E := P0(TT2); - end; - - for J := 16 to 63 do - begin - SS1 := ROTL((ROTL(A, 12) + E + ROTL(SM3_T[J], J)), 7); - SS2 := SS1 xor ROTL(A, 12); - TT1 := FF1(A, B, C) + D + SS2 + W1[J]; - TT2 := GG1(E, F, G) + H + SS1 + W[J]; - D := C; - C := ROTL(B,9); - B := A; - A := TT1; - H := G; - G := ROTL(F,19); - F := E; - E := P0(TT2); - end; - - Context.State[0] := Context.State[0] xor A; - Context.State[1] := Context.State[1] xor B; - Context.State[2] := Context.State[2] xor C; - Context.State[3] := Context.State[3] xor D; - Context.State[4] := Context.State[4] xor E; - Context.State[5] := Context.State[5] xor F; - Context.State[6] := Context.State[6] xor G; - Context.State[7] := Context.State[7] xor H; - - // -end; - -procedure SM3UpdateW(var Context: TCnSM3Context; Input: PWideChar; CharLength: Cardinal); -var -{$IFDEF MSWINDOWS} - pContent: PAnsiChar; - iLen: Cardinal; -{$ELSE} - S: string; // UnicodeString - A: AnsiString; -{$ENDIF} -begin -{$IFDEF MSWINDOWS} - GetMem(pContent, CharLength * SizeOf(WideChar)); - try - iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 - PAnsiChar(pContent), CharLength * SizeOf(WideChar), nil, nil); - SM3Update(Context, pContent, iLen); - finally - FreeMem(pContent); - end; -{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ - S := StrNew(Input); - A := AnsiString(S); - SM3Update(Context, @A[1], Length(A)); -{$ENDIF} -end; - -procedure SM3Update(var Context: TCnSM3Context; Input: PAnsiChar; ByteLength: Cardinal); -var - Fill, Left: Cardinal; -begin - if (Input = nil) or (ByteLength <= 0) then - Exit; - - Left := Context.Total[0] and $3F; - Fill := 64 - Left; - - Context.Total[0] := Context.Total[0] + ByteLength; - Context.Total[0] := Context.Total[0] and $FFFFFFFF; - - if Context.Total[0] < ByteLength then - Context.Total[1] := Context.Total[1] + 1; - - if (Left <> 0) and (ByteLength >= Fill) then - begin - Move(Input^, Context.Buffer[Left], Fill); - SM3Process(Context, @(Context.Buffer[0])); - Input := Input + Fill; - ByteLength := ByteLength - Fill; - Left := 0; - end; - - while ByteLength >= 64 do - begin - SM3Process(Context, Input); - Input := Input + 64; - ByteLength := ByteLength - 64; - end; - - if ByteLength > 0 then - Move(Input^, Context.Buffer[Left], ByteLength); -end; - -procedure SM3Final(var Context: TCnSM3Context; var Digest: TCnSM3Digest); -var - Last, Padn: Cardinal; - High, Low: Cardinal; - MsgLen: array[0..7] of Byte; -begin - High := (Context.Total[0] shr 29) or (Context.Total[1] shl 3); - Low := Context.Total[0] shl 3; - - PutULongBe(High, @(MsgLen[0]), 0); - PutULongBe(Low, @(MsgLen[0]), 4); - - Last := Context.Total[0] and $3F; - if Last < 56 then - Padn := 56 - Last - else - Padn := 120 - Last; - - SM3Update(Context, @(SM3Padding[0]), Padn); - SM3Update(Context, @(MsgLen[0]), 8); - - PutULongBe(Context.State[0], @Digest, 0); - PutULongBe(Context.State[1], @Digest, 4); - PutULongBe(Context.State[2], @Digest, 8); - PutULongBe(Context.State[3], @Digest, 12); - PutULongBe(Context.State[4], @Digest, 16); - PutULongBe(Context.State[5], @Digest, 20); - PutULongBe(Context.State[6], @Digest, 24); - PutULongBe(Context.State[7], @Digest, 28); -end; - -function SM3(Input: PAnsiChar; ByteLength: Cardinal): TCnSM3Digest; -var - Ctx: TCnSM3Context; -begin - SM3Init(Ctx); - SM3Update(Ctx, Input, ByteLength); - SM3Final(Ctx, Result); -end; - -procedure SM3HmacStarts(var Ctx: TCnSM3Context; Key: PAnsiChar; KeyLength: Integer); -var - I: Integer; - Sum: TCnSM3Digest; -begin - if KeyLength > HMAC_SM3_BLOCK_SIZE_BYTE then - begin - Sum := SM3(Key, KeyLength); - KeyLength := HMAC_SM3_OUTPUT_LENGTH_BYTE; - Key := @(Sum[0]); - end; - - FillChar(Ctx.Ipad, HMAC_SM3_BLOCK_SIZE_BYTE, $36); - FillChar(Ctx.Opad, HMAC_SM3_BLOCK_SIZE_BYTE, $5C); - - for I := 0 to KeyLength - 1 do - begin - Ctx.Ipad[I] := Byte(Ctx.Ipad[I] xor Byte(Key[I])); - Ctx.Opad[I] := Byte(Ctx.Opad[I] xor Byte(Key[I])); - end; - - SM3Init(Ctx); - SM3Update(Ctx, @(Ctx.Ipad[0]), HMAC_SM3_BLOCK_SIZE_BYTE); -end; - -procedure SM3HmacUpdate(var Ctx: TCnSM3Context; Input: PAnsiChar; Length: Cardinal); -begin - SM3Update(Ctx, Input, Length); -end; - -procedure SM3HmacFinish(var Ctx: TCnSM3Context; var Output: TCnSM3Digest); -var - Len: Integer; - TmpBuf: TCnSM3Digest; -begin - Len := HMAC_SM3_OUTPUT_LENGTH_BYTE; - SM3Final(Ctx, TmpBuf); - SM3Init(Ctx); - SM3Update(Ctx, @(Ctx.Opad[0]), HMAC_SM3_BLOCK_SIZE_BYTE); - SM3Update(Ctx, @(TmpBuf[0]), Len); - SM3Final(Ctx, Output); -end; - -procedure SM3Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; - ByteLength: Cardinal; var Output: TCnSM3Digest); -var - Ctx: TCnSM3Context; -begin - SM3HmacStarts(Ctx, Key, KeyByteLength); - SM3HmacUpdate(Ctx, Input, ByteLength); - SM3HmacFinish(Ctx, Output); -end; - -function SM3Buffer(const Buffer; Count: Cardinal): TCnSM3Digest; -var - Context: TCnSM3Context; -begin - SM3Init(Context); - SM3Update(Context, PAnsiChar(Buffer), Count); - SM3Final(Context, Result); -end; - -function SM3Bytes(Data: TBytes): TCnSM3Digest; -var - Context: TCnSM3Context; -begin - SM3Init(Context); - SM3Update(Context, PAnsiChar(@Data[0]), Length(Data)); - SM3Final(Context, Result); -end; - -// String ݽ SM3 ת -function SM3String(const Str: string): TCnSM3Digest; -var - AStr: AnsiString; -begin - AStr := AnsiString(Str); - Result := SM3StringA(AStr); -end; - -// AnsiString ݽ SM3 ת -function SM3StringA(const Str: AnsiString): TCnSM3Digest; -var - Context: TCnSM3Context; -begin - SM3Init(Context); - SM3Update(Context, PAnsiChar(Str), Length(Str)); - SM3Final(Context, Result); -end; - -// WideString ݽ SM3 ת -function SM3StringW(const Str: WideString): TCnSM3Digest; -var - Context: TCnSM3Context; -begin - SM3Init(Context); - SM3UpdateW(Context, PWideChar(Str), Length(Str)); - SM3Final(Context, Result); -end; - -// UnicodeString ݽֱӵ SM3 㣬ת -{$IFDEF UNICODE} -function SM3UnicodeString(const Str: string): TCnSM3Digest; -{$ELSE} -function SM3UnicodeString(const Str: WideString): TCnSM3Digest; -{$ENDIF} -var - Context: TCnSM3Context; -begin - SM3Init(Context); - SM3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); - SM3Final(Context, Result); -end; - -function InternalSM3Stream(Stream: TStream; const BufSize: Cardinal; var D: - TCnSM3Digest; CallBack: TCnSM3CalcProgressFunc = nil): Boolean; -var - Context: TCnSM3Context; - Buf: PAnsiChar; - BufLen: Cardinal; - Size: Int64; - ReadBytes: Cardinal; - TotalBytes: Int64; - SavePos: Int64; - CancelCalc: Boolean; -begin - Result := False; - Size := Stream.Size; - SavePos := Stream.Position; - TotalBytes := 0; - if Size = 0 then Exit; - if Size < BufSize then BufLen := Size - else BufLen := BufSize; - - CancelCalc := False; - SM3Init(Context); - GetMem(Buf, BufLen); - try - Stream.Position := 0; - repeat - ReadBytes := Stream.Read(Buf^, BufLen); - if ReadBytes <> 0 then - begin - Inc(TotalBytes, ReadBytes); - SM3Update(Context, Buf, ReadBytes); - if Assigned(CallBack) then - begin - CallBack(Size, TotalBytes, CancelCalc); - if CancelCalc then Exit; - end; - end; - until (ReadBytes = 0) or (TotalBytes = Size); - SM3Final(Context, D); - Result := True; - finally - FreeMem(Buf, BufLen); - Stream.Position := SavePos; - end; -end; - -// ָļݽSM3ת -function SM3File(const FileName: string; - CallBack: TCnSM3CalcProgressFunc): TCnSM3Digest; -var -{$IFDEF MSWINDOWS} - FileHandle: THandle; - MapHandle: THandle; - ViewPointer: Pointer; - Context: TCnSM3Context; -{$ENDIF} - Stream: TStream; - FileIsZeroSize: Boolean; - - function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; -{$IFDEF MSWINDOWS} - var - H: THandle; - Info: BY_HANDLE_FILE_INFORMATION; - Rec : Int64Rec; -{$ENDIF} - begin -{$IFDEF MSWINDOWS} - Result := False; - IsEmpty := False; - H := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); - if H = INVALID_HANDLE_VALUE then Exit; - try - if not GetFileInformationByHandle(H, Info) then Exit; - finally - CloseHandle(H); - end; - Rec.Lo := Info.nFileSizeLow; - Rec.Hi := Info.nFileSizeHigh; - Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); - IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); -{$ELSE} - Result := True; // Windows ƽ̨ Trueʾ Mapping -{$ENDIF} - end; - -begin - FileIsZeroSize := False; - if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then - begin - // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ - Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); - try - InternalSM3Stream(Stream, 4096 * 1024, Result, CallBack); - finally - Stream.Free; - end; - end - else - begin -{$IFDEF MSWINDOWS} - SM3Init(Context); - FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or - FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or - FILE_FLAG_SEQUENTIAL_SCAN, 0); - if FileHandle <> INVALID_HANDLE_VALUE then - begin - try - MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); - if MapHandle <> 0 then - begin - try - ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); - if ViewPointer <> nil then - begin - try - SM3Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); - finally - UnmapViewOfFile(ViewPointer); - end; - end - else - begin - raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); - end; - finally - CloseHandle(MapHandle); - end; - end - else - begin - if not FileIsZeroSize then - raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); - end; - finally - CloseHandle(FileHandle); - end; - end; - SM3Final(Context, Result); -{$ENDIF} - end; -end; - -// ָ SM3 -function SM3Stream(Stream: TStream; - CallBack: TCnSM3CalcProgressFunc = nil): TCnSM3Digest; -begin - InternalSM3Stream(Stream, 4096 * 1024, Result, CallBack); -end; - -function SM3Print(const Digest: TCnSM3Digest): string; -begin - Result := DataToHex(@Digest[0], SizeOf(TCnSM3Digest)); -end; - -function SM3Match(const D1, D2: TCnSM3Digest): Boolean; -begin - Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSM3Digest)); -end; - -function SM3DigestToStr(const Digest: TCnSM3Digest): string; -begin - Result := MemoryToString(@Digest[0], SizeOf(TCnSM3Digest)); -end; - -end. +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnSM3; +{* |
+================================================================================
+* ƣ
+* Ԫƣ SM3 Ӵ㷨ʵֵԪ
+* ԪߣCnPack 飨master@cnpack.org)
+*           οֲ goldboar  C 
+*     עԪʵ˹ SM3 Ӵ㷨Ӧ HMAC 㷨
+*           ο㷨ĵSM3 Cryptographic Hash Algorith
+*           http://www.oscca.gov.cn/UpFile/20101222141857786.pdf
+*
+* ƽ̨Windows 7 + Delphi 5.0
+* ݲԣPWin9X/2000/XP/7 + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2019.12.12 V1.2
+*               ֧ TBytes
+*           2019.04.15 V1.1
+*               ֧ Win32/Win64/MacOS
+*           2014.09.23 V1.0
+*               ֲԪ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + Classes, SysUtils, CnNative, CnConsts {$IFDEF MSWINDOWS}, Windows {$ENDIF}; + +type + PCnSM3Digest = ^TCnSM3Digest; + TCnSM3Digest = array[0..31] of Byte; + {* SM3 Ӵս32 ֽ} + + TCnSM3Context = packed record + {* SM3 Ľṹ} + Total: array[0..1] of Cardinal; {!< number of bytes processed } + State: array[0..7] of Cardinal; {!< intermediate digest state } + Buffer: array[0..63] of Byte; {!< data block being processed } + Ipad: array[0..63] of Byte; {!< HMAC: inner padding } + Opad: array[0..63] of Byte; {!< HMAC: outer padding } + end; + PCnSM3Context = ^TCnSM3Context; + + TCnSM3CalcProgressFunc = procedure (ATotal, AProgress: Int64; + var Cancel: Boolean) of object; + {* SM3 ӴսȻص¼} + +function SM3(Input: PAnsiChar; ByteLength: Cardinal): TCnSM3Digest; +{* ݿ SM3 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSM3Digest - ص SM3 Ӵֵ + + } + +function SM3Buffer(const Buffer; Count: Cardinal): TCnSM3Digest; +{* ݿ SM3 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3Bytes(Data: TBytes): TCnSM3Digest; +{* ֽ SM3 㡣 + + + Data: TBytes - ֽ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3String(const Str: string): TCnSM3Digest; +{* String ݽ SM3 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3StringA(const Str: AnsiString): TCnSM3Digest; +{* AnsiString ݽ SM3 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3StringW(const Str: WideString): TCnSM3Digest; +{* WideString ַת SM3 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +{$IFDEF UNICODE} + +function SM3UnicodeString(const Str: string): TCnSM3Digest; +{* UnicodeString ݽֱӵ SM3 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +{$ELSE} + +function SM3UnicodeString(const Str: WideString): TCnSM3Digest; +{* UnicodeString ݽֱӵ SM3 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +{$ENDIF} + +function SM3File(const FileName: string; CallBack: TCnSM3CalcProgressFunc = nil): TCnSM3Digest; +{* ָļݽ SM3 㡣 + + + const FileName: string - ļ + CallBack: TCnSM3CalcProgressFunc - ȻصĬΪ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3Stream(Stream: TStream; CallBack: TCnSM3CalcProgressFunc = nil): TCnSM3Digest; +{* ָݽ SM3 㡣 + + + Stream: TStream - + CallBack: TCnSM3CalcProgressFunc - ȻصĬΪ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +// ⲿݽɢ SM3 㣬SM3Update ɶα + +procedure SM3Init(var Context: TCnSM3Context); +{* ʼһ SM3 ģ׼ SM3 + + + var Context: TCnSM3Context - ʼ SM3 + + ֵޣ +} + +procedure SM3Update(var Context: TCnSM3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SM3 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSM3Context - SM3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SM3Final(var Context: TCnSM3Context; var Digest: TCnSM3Digest); +{* ּ㣬 SM3 Digest + + + var Context: TCnSM3Context - SM3 + var Digest: TCnSM3Digest - ص SM3 Ӵֵ + + ֵޣ +} + +function SM3Print(const Digest: TCnSM3Digest): string; +{* ʮƸʽ SM3 Ӵֵ + + + const Digest: TCnSM3Digest - ָ SM3 Ӵֵ + + ֵstring - ʮַ +} + +function SM3Match(const D1: TCnSM3Digest; const D2: TCnSM3Digest): Boolean; +{* Ƚ SM3 ӴֵǷȡ + + + const D1: TCnSM3Digest - Ƚϵ SM3 Ӵֵһ + const D2: TCnSM3Digest - Ƚϵ SM3 Ӵֵ + + ֵBoolean - Ƿ +} + +function SM3DigestToStr(const Digest: TCnSM3Digest): string; +{* SM3 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSM3Digest - ת SM3 Ӵֵ + + ֵstring - صַ +} + +procedure SM3Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSM3Digest); +{* SM3 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SM3 Կݿַ + KeyByteLength: Integer - SM3 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSM3Digest - ص SM3 Ӵֵ + + ֵޣ +} + +implementation + +const + SM3Padding: array[0..63] of Byte = + ( + $80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ); + + SM3_T: array[0..63] of Cardinal = ( + $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, + $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A + ); + + MAX_FILE_SIZE = 512 * 1024 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + HMAC_SM3_BLOCK_SIZE_BYTE = 64; + HMAC_SM3_OUTPUT_LENGTH_BYTE = 32; + +type + TSM3ProcessData = array[0..63] of Byte; + +procedure GetULongBe(var N: Cardinal; B: PAnsiChar; I: Integer); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +var + D: Cardinal; +begin + D := (Cardinal(B[I]) shl 24) or (Cardinal(B[I + 1]) shl 16) or + (Cardinal(B[I + 2]) shl 8) or (Cardinal(B[I + 3])); + N := D; +end; + +procedure PutULongBe(N: Cardinal; B: PAnsiChar; I: Integer); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + B[I] := AnsiChar(N shr 24); + B[I + 1] := AnsiChar(N shr 16); + B[I + 2] := AnsiChar(N shr 8); + B[I + 3] := AnsiChar(N); +end; + +function FF0(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor Y xor Z; +end; + +function FF1(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and Y) or (Y and Z) or (X and Z); +end; + +function GG0(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor Y xor Z; +end; + +function GG1(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and Y) or ((not X) and Z); +end; + +function SM3Shl(X: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and $FFFFFFFF) shl N; +end; + +// ѭơע N Ϊ 0 32 ʱֵΪ XN Ϊ 33 ʱֵ N Ϊ 1 ʱķֵ +function ROTL(X: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := SM3Shl(X, N) or (X shr (32 - N)); +end; + +function P0(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor ROTL(X, 9) xor ROTL(X, 17); +end; + +function P1(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor ROTL(X, 15) xor ROTL(X, 23); +end; + +procedure SM3Init(var Context: TCnSM3Context); +begin + Context.Total[0] := 0; + Context.Total[1] := 0; + + Context.State[0] := $7380166F; + Context.State[1] := $4914B2B9; + Context.State[2] := $172442D7; + Context.State[3] := $DA8A0600; + Context.State[4] := $A96F30BC; + Context.State[5] := $163138AA; + Context.State[6] := $E38DEE4D; + Context.State[7] := $B0FB0E4E; + + FillChar(Context.Buffer, SizeOf(Context.Buffer), 0); +end; + +// һδ 64 ֽҲ 512 λݿ +procedure SM3Process(var Context: TCnSM3Context; Data: PAnsiChar); +var + SS1, SS2, TT1, TT2: Cardinal; + W: array[0..67] of Cardinal; + W1: array[0..63] of Cardinal; + A, B, C, D, E, F, G, H: Cardinal; + Temp1, Temp2: Cardinal; + J: Integer; +begin + GetULongBe(W[ 0], Data, 0); + GetULongBe(W[ 1], Data, 4); + GetULongBe(W[ 2], Data, 8); + GetULongBe(W[ 3], Data, 12); + GetULongBe(W[ 4], Data, 16); + GetULongBe(W[ 5], Data, 20); + GetULongBe(W[ 6], Data, 24); + GetULongBe(W[ 7], Data, 28); + GetULongBe(W[ 8], Data, 32); + GetULongBe(W[ 9], Data, 36); + GetULongBe(W[10], Data, 40); + GetULongBe(W[11], Data, 44); + GetULongBe(W[12], Data, 48); + GetULongBe(W[13], Data, 52); + GetULongBe(W[14], Data, 56); + GetULongBe(W[15], Data, 60); + + for J := 16 to 67 do + begin + Temp1 := W[J - 16] xor W[J - 9]; + Temp2 := ROTL(W[J - 3], 15); + W[J] := P1(Temp1 xor Temp2) xor (ROTL(W[J - 13], 7) xor W[J - 6]); + end; + + for J := 0 to 63 do + W1[J] := W[J] xor W[J + 4]; + + // ѾW/W1ֵ + + A := Context.State[0]; + B := Context.State[1]; + C := Context.State[2]; + D := Context.State[3]; + E := Context.State[4]; + F := Context.State[5]; + G := Context.State[6]; + H := Context.State[7]; + + for J := 0 to 15 do + begin + SS1 := ROTL((ROTL(A, 12) + E + ROTL(SM3_T[J], J)), 7); + SS2 := SS1 xor ROTL(A, 12); + TT1 := FF0(A, B, C) + D + SS2 + W1[J]; + TT2 := GG0(E, F, G) + H + SS1 + W[J]; + D := C; + C := ROTL(B, 9); + B := A; + A := TT1; + H := G; + G := ROTL(F, 19); + F := E; + E := P0(TT2); + end; + + for J := 16 to 63 do + begin + SS1 := ROTL((ROTL(A, 12) + E + ROTL(SM3_T[J], J)), 7); + SS2 := SS1 xor ROTL(A, 12); + TT1 := FF1(A, B, C) + D + SS2 + W1[J]; + TT2 := GG1(E, F, G) + H + SS1 + W[J]; + D := C; + C := ROTL(B,9); + B := A; + A := TT1; + H := G; + G := ROTL(F,19); + F := E; + E := P0(TT2); + end; + + Context.State[0] := Context.State[0] xor A; + Context.State[1] := Context.State[1] xor B; + Context.State[2] := Context.State[2] xor C; + Context.State[3] := Context.State[3] xor D; + Context.State[4] := Context.State[4] xor E; + Context.State[5] := Context.State[5] xor F; + Context.State[6] := Context.State[6] xor G; + Context.State[7] := Context.State[7] xor H; + + // +end; + +procedure SM3UpdateW(var Context: TCnSM3Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + pContent: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(pContent, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(pContent), CharLength * SizeOf(WideChar), nil, nil); + SM3Update(Context, pContent, iLen); + finally + FreeMem(pContent); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SM3Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +procedure SM3Update(var Context: TCnSM3Context; Input: PAnsiChar; ByteLength: Cardinal); +var + Fill, Left: Cardinal; +begin + if (Input = nil) or (ByteLength <= 0) then + Exit; + + Left := Context.Total[0] and $3F; + Fill := 64 - Left; + + Context.Total[0] := Context.Total[0] + ByteLength; + Context.Total[0] := Context.Total[0] and $FFFFFFFF; + + if Context.Total[0] < ByteLength then + Context.Total[1] := Context.Total[1] + 1; + + if (Left <> 0) and (ByteLength >= Fill) then + begin + Move(Input^, Context.Buffer[Left], Fill); + SM3Process(Context, @(Context.Buffer[0])); + Input := Input + Fill; + ByteLength := ByteLength - Fill; + Left := 0; + end; + + while ByteLength >= 64 do + begin + SM3Process(Context, Input); + Input := Input + 64; + ByteLength := ByteLength - 64; + end; + + if ByteLength > 0 then + Move(Input^, Context.Buffer[Left], ByteLength); +end; + +procedure SM3Final(var Context: TCnSM3Context; var Digest: TCnSM3Digest); +var + Last, Padn: Cardinal; + High, Low: Cardinal; + MsgLen: array[0..7] of Byte; +begin + High := (Context.Total[0] shr 29) or (Context.Total[1] shl 3); + Low := Context.Total[0] shl 3; + + PutULongBe(High, @(MsgLen[0]), 0); + PutULongBe(Low, @(MsgLen[0]), 4); + + Last := Context.Total[0] and $3F; + if Last < 56 then + Padn := 56 - Last + else + Padn := 120 - Last; + + SM3Update(Context, @(SM3Padding[0]), Padn); + SM3Update(Context, @(MsgLen[0]), 8); + + PutULongBe(Context.State[0], @Digest, 0); + PutULongBe(Context.State[1], @Digest, 4); + PutULongBe(Context.State[2], @Digest, 8); + PutULongBe(Context.State[3], @Digest, 12); + PutULongBe(Context.State[4], @Digest, 16); + PutULongBe(Context.State[5], @Digest, 20); + PutULongBe(Context.State[6], @Digest, 24); + PutULongBe(Context.State[7], @Digest, 28); +end; + +function SM3(Input: PAnsiChar; ByteLength: Cardinal): TCnSM3Digest; +var + Ctx: TCnSM3Context; +begin + SM3Init(Ctx); + SM3Update(Ctx, Input, ByteLength); + SM3Final(Ctx, Result); +end; + +procedure SM3HmacStarts(var Ctx: TCnSM3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSM3Digest; +begin + if KeyLength > HMAC_SM3_BLOCK_SIZE_BYTE then + begin + Sum := SM3(Key, KeyLength); + KeyLength := HMAC_SM3_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Ctx.Ipad, HMAC_SM3_BLOCK_SIZE_BYTE, $36); + FillChar(Ctx.Opad, HMAC_SM3_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Ctx.Ipad[I] := Byte(Ctx.Ipad[I] xor Byte(Key[I])); + Ctx.Opad[I] := Byte(Ctx.Opad[I] xor Byte(Key[I])); + end; + + SM3Init(Ctx); + SM3Update(Ctx, @(Ctx.Ipad[0]), HMAC_SM3_BLOCK_SIZE_BYTE); +end; + +procedure SM3HmacUpdate(var Ctx: TCnSM3Context; Input: PAnsiChar; Length: Cardinal); +begin + SM3Update(Ctx, Input, Length); +end; + +procedure SM3HmacFinish(var Ctx: TCnSM3Context; var Output: TCnSM3Digest); +var + Len: Integer; + TmpBuf: TCnSM3Digest; +begin + Len := HMAC_SM3_OUTPUT_LENGTH_BYTE; + SM3Final(Ctx, TmpBuf); + SM3Init(Ctx); + SM3Update(Ctx, @(Ctx.Opad[0]), HMAC_SM3_BLOCK_SIZE_BYTE); + SM3Update(Ctx, @(TmpBuf[0]), Len); + SM3Final(Ctx, Output); +end; + +procedure SM3Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSM3Digest); +var + Ctx: TCnSM3Context; +begin + SM3HmacStarts(Ctx, Key, KeyByteLength); + SM3HmacUpdate(Ctx, Input, ByteLength); + SM3HmacFinish(Ctx, Output); +end; + +function SM3Buffer(const Buffer; Count: Cardinal): TCnSM3Digest; +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3Update(Context, PAnsiChar(Buffer), Count); + SM3Final(Context, Result); +end; + +function SM3Bytes(Data: TBytes): TCnSM3Digest; +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SM3Final(Context, Result); +end; + +// String ݽ SM3 ת +function SM3String(const Str: string): TCnSM3Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SM3StringA(AStr); +end; + +// AnsiString ݽ SM3 ת +function SM3StringA(const Str: AnsiString): TCnSM3Digest; +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3Update(Context, PAnsiChar(Str), Length(Str)); + SM3Final(Context, Result); +end; + +// WideString ݽ SM3 ת +function SM3StringW(const Str: WideString): TCnSM3Digest; +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3UpdateW(Context, PWideChar(Str), Length(Str)); + SM3Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SM3 㣬ת +{$IFDEF UNICODE} +function SM3UnicodeString(const Str: string): TCnSM3Digest; +{$ELSE} +function SM3UnicodeString(const Str: WideString): TCnSM3Digest; +{$ENDIF} +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SM3Final(Context, Result); +end; + +function InternalSM3Stream(Stream: TStream; const BufSize: Cardinal; var D: + TCnSM3Digest; CallBack: TCnSM3CalcProgressFunc = nil): Boolean; +var + Context: TCnSM3Context; + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then Exit; + if Size < BufSize then BufLen := Size + else BufLen := BufSize; + + CancelCalc := False; + SM3Init(Context); + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + SM3Update(Context, Buf, ReadBytes); + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + SM3Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ָļݽSM3ת +function SM3File(const FileName: string; + CallBack: TCnSM3CalcProgressFunc): TCnSM3Digest; +var +{$IFDEF MSWINDOWS} + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; + Context: TCnSM3Context; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; + + function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} + var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec : Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then Exit; + try + if not GetFileInformationByHandle(H, Info) then Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} + end; + +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSM3Stream(Stream, 4096 * 1024, Result, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + SM3Init(Context); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + SM3Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + SM3Final(Context, Result); +{$ENDIF} + end; +end; + +// ָ SM3 +function SM3Stream(Stream: TStream; + CallBack: TCnSM3CalcProgressFunc = nil): TCnSM3Digest; +begin + InternalSM3Stream(Stream, 4096 * 1024, Result, CallBack); +end; + +function SM3Print(const Digest: TCnSM3Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSM3Digest)); +end; + +function SM3Match(const D1, D2: TCnSM3Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSM3Digest)); +end; + +function SM3DigestToStr(const Digest: TCnSM3Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSM3Digest)); +end; + +end. diff --git a/DelphiToFPC/DTF.Character.pas b/DelphiToFPC/DTF.Character.pas index 60ab0c4..60d8be4 100644 --- a/DelphiToFPC/DTF.Character.pas +++ b/DelphiToFPC/DTF.Character.pas @@ -1,445 +1,445 @@ -unit DTF.Character; - -{$I zLib.inc} - -interface - -uses - Classes, - SysUtils, - Character; - -type - TCharHelper = record helper for Char - public - class function ConvertFromUtf32(AChar: UCS4Char): UnicodeString; static; - class function ConvertToUtf32(const AString: UnicodeString; AIndex: Integer): UCS4Char; overload; static; - class function ConvertToUtf32(const AString: UnicodeString; AIndex: Integer; out ACharLength: Integer): UCS4Char; overload; static; - class function ConvertToUtf32(const AHighSurrogate, ALowSurrogate: UnicodeChar): UCS4Char; overload; static; - - class function GetNumericValue(AChar: UnicodeChar): Double; overload; static; - class function GetNumericValue(const AString: UnicodeString; AIndex: Integer): Double; overload; static; - - class function GetUnicodeCategory(AChar: UnicodeChar): TUnicodeCategory; overload; static; inline; - class function GetUnicodeCategory(const AString: UnicodeString; AIndex: Integer): TUnicodeCategory; overload; static; - - class function IsControl(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsControl(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; - - class function IsDigit(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsDigit(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; - - class function IsSurrogate(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsSurrogate(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; - class function IsHighSurrogate(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsHighSurrogate(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; - class function IsLowSurrogate(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsLowSurrogate(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; - class function IsSurrogatePair(const AHighSurrogate, ALowSurrogate: UnicodeChar): Boolean; overload; static; inline; - class function IsSurrogatePair(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; - - class function IsLetter(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsLetter(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; - - class function IsLetterOrDigit(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsLetterOrDigit(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; - - class function IsLower(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsLower(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; - - class function IsNumber(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsNumber(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; - - class function IsPunctuation(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsPunctuation(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; - - class function IsSeparator(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsSeparator(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; - - class function IsSymbol(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsSymbol(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; - - class function IsUpper(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsUpper(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; - - class function IsWhiteSpace(AChar: UnicodeChar): Boolean; overload; static; inline; - class function IsWhiteSpace(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; - - class function ToLower(AChar: UnicodeChar): UnicodeChar; overload; static; - class function ToLower(const AString: UnicodeString): UnicodeString; inline; overload; static; - class function ToLower(const AString: UnicodeString; const AOptions: TCharacterOptions): UnicodeString; overload; static; - - class function ToUpper(AChar: UnicodeChar): UnicodeChar; overload; static; - class function ToUpper(const AString: UnicodeString): UnicodeString; inline; overload; static; - class function ToUpper(const AString: UnicodeString; const AOptions: TCharacterOptions): UnicodeString; overload; static; - - function GetNumericValue: Double; overload; - function GetUnicodeCategory: TUnicodeCategory; overload; - function IsControl: Boolean; overload; - function IsDigit: Boolean; overload; - function IsSurrogate: Boolean; overload; - function IsHighSurrogate: Boolean; overload; - function IsLowSurrogate: Boolean; overload; - function IsInArray(const ASomeChars: array of Char): Boolean; overload; - function IsLetter: Boolean; overload; - function IsLetterOrDigit: Boolean; overload; - function IsLower: Boolean; overload; - function IsNumber: Boolean; overload; - function IsPunctuation: Boolean; overload; - function IsSeparator: Boolean; overload; - function IsSymbol: Boolean; overload; - function IsUpper: Boolean; overload; - function IsWhiteSpace: Boolean; overload; - function ToLower: UnicodeChar; overload; - function ToUpper: UnicodeChar; overload; - end; - -implementation - -{ TCharHelper } - -class function TCharHelper.ConvertFromUtf32(AChar: UCS4Char): UnicodeString; -begin - Result:= TCharacter.ConvertFromUtf32(AChar); -end; - -class function TCharHelper.ConvertToUtf32(const AString: UnicodeString; - AIndex: Integer; out ACharLength: Integer): UCS4Char; -begin - Result:= TCharacter.ConvertToUtf32(AString, AIndex, ACharLength); -end; - -class function TCharHelper.ConvertToUtf32(const AString: UnicodeString; - AIndex: Integer): UCS4Char; -begin - Result:= TCharacter.ConvertToUtf32(AString, AIndex); -end; - -class function TCharHelper.ConvertToUtf32(const AHighSurrogate, - ALowSurrogate: UnicodeChar): UCS4Char; -begin - Result:= TCharacter.ConvertToUtf32(AHighSurrogate, ALowSurrogate); -end; - -class function TCharHelper.GetNumericValue(const AString: UnicodeString; - AIndex: Integer): Double; -begin - Result:= TCharacter.GetNumericValue(AString, AIndex); -end; - -class function TCharHelper.GetNumericValue(AChar: UnicodeChar): Double; -begin - Result:= TCharacter.GetNumericValue(AChar); -end; - -class function TCharHelper.GetUnicodeCategory( - AChar: UnicodeChar): TUnicodeCategory; -begin - Result:= TCharacter.GetUnicodeCategory(AChar); -end; - -class function TCharHelper.GetUnicodeCategory(const AString: UnicodeString; - AIndex: Integer): TUnicodeCategory; -begin - Result:= TCharacter.GetUnicodeCategory(AString, AIndex); -end; - -class function TCharHelper.IsControl(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsControl(AString, AIndex); -end; - -class function TCharHelper.IsControl(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsControl(AChar); -end; - -class function TCharHelper.IsDigit(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsDigit(AString, AIndex); -end; - -class function TCharHelper.IsDigit(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsDigit(AChar); -end; - -class function TCharHelper.IsHighSurrogate(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsHighSurrogate(AChar); -end; - -class function TCharHelper.IsHighSurrogate(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsHighSurrogate(AString, AIndex); -end; - -class function TCharHelper.IsLetter(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsLetter(AString, AIndex); -end; - -class function TCharHelper.IsLetter(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsLetter(AChar); -end; - -class function TCharHelper.IsLetterOrDigit(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsLetterOrDigit(AChar); -end; - -class function TCharHelper.IsLetterOrDigit(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsLetterOrDigit(AString, AIndex); -end; - -class function TCharHelper.IsLower(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsLower(AString, AIndex); -end; - -class function TCharHelper.IsLower(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsLower(AChar); -end; - -class function TCharHelper.IsLowSurrogate(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsLowSurrogate(AChar); -end; - -class function TCharHelper.IsLowSurrogate(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsLowSurrogate(AString, AIndex); -end; - -class function TCharHelper.IsNumber(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsNumber(AChar); -end; - -class function TCharHelper.IsNumber(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsNumber(AString, AIndex); -end; - -class function TCharHelper.IsPunctuation(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsPunctuation(AChar); -end; - -class function TCharHelper.IsPunctuation(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsPunctuation(AString, AIndex); -end; - -class function TCharHelper.IsSeparator(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsSeparator(AString, AIndex); -end; - -class function TCharHelper.IsSeparator(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsSeparator(AChar); -end; - -class function TCharHelper.IsSurrogate(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsSurrogate(AString, AIndex); -end; - -class function TCharHelper.IsSurrogate(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsSurrogate(AChar); -end; - -class function TCharHelper.IsSurrogatePair(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsSurrogatePair(AString, AIndex); -end; - -class function TCharHelper.IsSurrogatePair(const AHighSurrogate, - ALowSurrogate: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsSurrogatePair(AHighSurrogate, ALowSurrogate); -end; - -class function TCharHelper.IsSymbol(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsSymbol(AString, AIndex); -end; - -class function TCharHelper.IsSymbol(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsSymbol(AChar); -end; - -class function TCharHelper.IsUpper(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsUpper(AString, AIndex); -end; - -class function TCharHelper.IsUpper(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsUpper(AChar); -end; - -class function TCharHelper.IsWhiteSpace(AChar: UnicodeChar): Boolean; -begin - Result:= TCharacter.IsWhiteSpace(AChar); -end; - -class function TCharHelper.IsWhiteSpace(const AString: UnicodeString; - AIndex: Integer): Boolean; -begin - Result:= TCharacter.IsWhiteSpace(AString, AIndex); -end; - -class function TCharHelper.ToLower(const AString: UnicodeString; - const AOptions: TCharacterOptions): UnicodeString; -begin - Result:= TCharacter.ToLower(AString, AOptions); -end; - -class function TCharHelper.ToLower(const AString: UnicodeString): UnicodeString; -begin - Result:= TCharacter.ToLower(AString); -end; - -class function TCharHelper.ToLower(AChar: UnicodeChar): UnicodeChar; -begin - Result:= TCharacter.ToLower(AChar); -end; - -class function TCharHelper.ToUpper(AChar: UnicodeChar): UnicodeChar; -begin - Result:= TCharacter.ToUpper(AChar); -end; - -class function TCharHelper.ToUpper(const AString: UnicodeString): UnicodeString; -begin - Result:= TCharacter.ToUpper(AString); -end; - -class function TCharHelper.ToUpper(const AString: UnicodeString; - const AOptions: TCharacterOptions): UnicodeString; -begin - Result:= TCharacter.ToUpper(AString, AOptions); -end; - -function TCharHelper.GetNumericValue: Double; -begin - Result := GetNumericValue(Self); -end; - -function TCharHelper.GetUnicodeCategory: TUnicodeCategory; -begin - Result := GetUnicodeCategory(Self); -end; - -function TCharHelper.IsControl: Boolean; -begin - Result := IsControl(Self); -end; - -function TCharHelper.IsDigit: Boolean; -begin - Result := IsDigit(Self); -end; - -function TCharHelper.IsHighSurrogate: Boolean; -begin - Result := IsHighSurrogate(Self); -end; - -function TCharHelper.IsInArray(const ASomeChars: array of Char): Boolean; -var - LChar: Char; -begin - for LChar in ASomeChars do - if (LChar = Self) then Exit(True); - Result := False; -end; - -function TCharHelper.IsLetter: Boolean; -begin - Result := IsLetter(Self); -end; - -function TCharHelper.IsLetterOrDigit: Boolean; -begin - Result := IsLetterOrDigit(Self); -end; - -function TCharHelper.IsLower: Boolean; -begin - Result := IsLower(Self); -end; - -function TCharHelper.IsLowSurrogate: Boolean; -begin - Result := IsLowSurrogate(Self); -end; - -function TCharHelper.IsNumber: Boolean; -begin - Result := IsNumber(Self); -end; - -function TCharHelper.IsPunctuation: Boolean; -begin - Result := IsPunctuation(Self); -end; - -function TCharHelper.IsSeparator: Boolean; -begin - Result := IsSeparator(Self); -end; - -function TCharHelper.IsSurrogate: Boolean; -begin - Result := IsSurrogate(Self); -end; - -function TCharHelper.IsSymbol: Boolean; -begin - Result := IsSymbol(Self); -end; - -function TCharHelper.IsUpper: Boolean; -begin - Result := IsUpper(Self); -end; - -function TCharHelper.IsWhiteSpace: Boolean; -begin - Result := IsWhiteSpace(Self); -end; - -function TCharHelper.ToLower: UnicodeChar; -begin - Result := ToLower(Self); -end; - -function TCharHelper.ToUpper: UnicodeChar; -begin - Result := ToUpper(Self); -end; - -end. - +unit DTF.Character; + +{$I zLib.inc} + +interface + +uses + Classes, + SysUtils, + Character; + +type + TCharHelper = record helper for Char + public + class function ConvertFromUtf32(AChar: UCS4Char): UnicodeString; static; + class function ConvertToUtf32(const AString: UnicodeString; AIndex: Integer): UCS4Char; overload; static; + class function ConvertToUtf32(const AString: UnicodeString; AIndex: Integer; out ACharLength: Integer): UCS4Char; overload; static; + class function ConvertToUtf32(const AHighSurrogate, ALowSurrogate: UnicodeChar): UCS4Char; overload; static; + + class function GetNumericValue(AChar: UnicodeChar): Double; overload; static; + class function GetNumericValue(const AString: UnicodeString; AIndex: Integer): Double; overload; static; + + class function GetUnicodeCategory(AChar: UnicodeChar): TUnicodeCategory; overload; static; inline; + class function GetUnicodeCategory(const AString: UnicodeString; AIndex: Integer): TUnicodeCategory; overload; static; + + class function IsControl(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsControl(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; + + class function IsDigit(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsDigit(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; + + class function IsSurrogate(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsSurrogate(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; + class function IsHighSurrogate(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsHighSurrogate(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; + class function IsLowSurrogate(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsLowSurrogate(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; + class function IsSurrogatePair(const AHighSurrogate, ALowSurrogate: UnicodeChar): Boolean; overload; static; inline; + class function IsSurrogatePair(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; + + class function IsLetter(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsLetter(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; + + class function IsLetterOrDigit(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsLetterOrDigit(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; + + class function IsLower(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsLower(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; + + class function IsNumber(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsNumber(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; + + class function IsPunctuation(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsPunctuation(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; + + class function IsSeparator(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsSeparator(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; + + class function IsSymbol(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsSymbol(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; + + class function IsUpper(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsUpper(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; inline; + + class function IsWhiteSpace(AChar: UnicodeChar): Boolean; overload; static; inline; + class function IsWhiteSpace(const AString: UnicodeString; AIndex: Integer): Boolean; overload; static; + + class function ToLower(AChar: UnicodeChar): UnicodeChar; overload; static; + class function ToLower(const AString: UnicodeString): UnicodeString; inline; overload; static; + class function ToLower(const AString: UnicodeString; const AOptions: TCharacterOptions): UnicodeString; overload; static; + + class function ToUpper(AChar: UnicodeChar): UnicodeChar; overload; static; + class function ToUpper(const AString: UnicodeString): UnicodeString; inline; overload; static; + class function ToUpper(const AString: UnicodeString; const AOptions: TCharacterOptions): UnicodeString; overload; static; + + function GetNumericValue: Double; overload; + function GetUnicodeCategory: TUnicodeCategory; overload; + function IsControl: Boolean; overload; + function IsDigit: Boolean; overload; + function IsSurrogate: Boolean; overload; + function IsHighSurrogate: Boolean; overload; + function IsLowSurrogate: Boolean; overload; + function IsInArray(const ASomeChars: array of Char): Boolean; overload; + function IsLetter: Boolean; overload; + function IsLetterOrDigit: Boolean; overload; + function IsLower: Boolean; overload; + function IsNumber: Boolean; overload; + function IsPunctuation: Boolean; overload; + function IsSeparator: Boolean; overload; + function IsSymbol: Boolean; overload; + function IsUpper: Boolean; overload; + function IsWhiteSpace: Boolean; overload; + function ToLower: UnicodeChar; overload; + function ToUpper: UnicodeChar; overload; + end; + +implementation + +{ TCharHelper } + +class function TCharHelper.ConvertFromUtf32(AChar: UCS4Char): UnicodeString; +begin + Result:= TCharacter.ConvertFromUtf32(AChar); +end; + +class function TCharHelper.ConvertToUtf32(const AString: UnicodeString; + AIndex: Integer; out ACharLength: Integer): UCS4Char; +begin + Result:= TCharacter.ConvertToUtf32(AString, AIndex, ACharLength); +end; + +class function TCharHelper.ConvertToUtf32(const AString: UnicodeString; + AIndex: Integer): UCS4Char; +begin + Result:= TCharacter.ConvertToUtf32(AString, AIndex); +end; + +class function TCharHelper.ConvertToUtf32(const AHighSurrogate, + ALowSurrogate: UnicodeChar): UCS4Char; +begin + Result:= TCharacter.ConvertToUtf32(AHighSurrogate, ALowSurrogate); +end; + +class function TCharHelper.GetNumericValue(const AString: UnicodeString; + AIndex: Integer): Double; +begin + Result:= TCharacter.GetNumericValue(AString, AIndex); +end; + +class function TCharHelper.GetNumericValue(AChar: UnicodeChar): Double; +begin + Result:= TCharacter.GetNumericValue(AChar); +end; + +class function TCharHelper.GetUnicodeCategory( + AChar: UnicodeChar): TUnicodeCategory; +begin + Result:= TCharacter.GetUnicodeCategory(AChar); +end; + +class function TCharHelper.GetUnicodeCategory(const AString: UnicodeString; + AIndex: Integer): TUnicodeCategory; +begin + Result:= TCharacter.GetUnicodeCategory(AString, AIndex); +end; + +class function TCharHelper.IsControl(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsControl(AString, AIndex); +end; + +class function TCharHelper.IsControl(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsControl(AChar); +end; + +class function TCharHelper.IsDigit(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsDigit(AString, AIndex); +end; + +class function TCharHelper.IsDigit(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsDigit(AChar); +end; + +class function TCharHelper.IsHighSurrogate(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsHighSurrogate(AChar); +end; + +class function TCharHelper.IsHighSurrogate(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsHighSurrogate(AString, AIndex); +end; + +class function TCharHelper.IsLetter(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsLetter(AString, AIndex); +end; + +class function TCharHelper.IsLetter(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsLetter(AChar); +end; + +class function TCharHelper.IsLetterOrDigit(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsLetterOrDigit(AChar); +end; + +class function TCharHelper.IsLetterOrDigit(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsLetterOrDigit(AString, AIndex); +end; + +class function TCharHelper.IsLower(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsLower(AString, AIndex); +end; + +class function TCharHelper.IsLower(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsLower(AChar); +end; + +class function TCharHelper.IsLowSurrogate(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsLowSurrogate(AChar); +end; + +class function TCharHelper.IsLowSurrogate(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsLowSurrogate(AString, AIndex); +end; + +class function TCharHelper.IsNumber(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsNumber(AChar); +end; + +class function TCharHelper.IsNumber(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsNumber(AString, AIndex); +end; + +class function TCharHelper.IsPunctuation(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsPunctuation(AChar); +end; + +class function TCharHelper.IsPunctuation(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsPunctuation(AString, AIndex); +end; + +class function TCharHelper.IsSeparator(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsSeparator(AString, AIndex); +end; + +class function TCharHelper.IsSeparator(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsSeparator(AChar); +end; + +class function TCharHelper.IsSurrogate(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsSurrogate(AString, AIndex); +end; + +class function TCharHelper.IsSurrogate(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsSurrogate(AChar); +end; + +class function TCharHelper.IsSurrogatePair(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsSurrogatePair(AString, AIndex); +end; + +class function TCharHelper.IsSurrogatePair(const AHighSurrogate, + ALowSurrogate: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsSurrogatePair(AHighSurrogate, ALowSurrogate); +end; + +class function TCharHelper.IsSymbol(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsSymbol(AString, AIndex); +end; + +class function TCharHelper.IsSymbol(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsSymbol(AChar); +end; + +class function TCharHelper.IsUpper(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsUpper(AString, AIndex); +end; + +class function TCharHelper.IsUpper(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsUpper(AChar); +end; + +class function TCharHelper.IsWhiteSpace(AChar: UnicodeChar): Boolean; +begin + Result:= TCharacter.IsWhiteSpace(AChar); +end; + +class function TCharHelper.IsWhiteSpace(const AString: UnicodeString; + AIndex: Integer): Boolean; +begin + Result:= TCharacter.IsWhiteSpace(AString, AIndex); +end; + +class function TCharHelper.ToLower(const AString: UnicodeString; + const AOptions: TCharacterOptions): UnicodeString; +begin + Result:= TCharacter.ToLower(AString, AOptions); +end; + +class function TCharHelper.ToLower(const AString: UnicodeString): UnicodeString; +begin + Result:= TCharacter.ToLower(AString); +end; + +class function TCharHelper.ToLower(AChar: UnicodeChar): UnicodeChar; +begin + Result:= TCharacter.ToLower(AChar); +end; + +class function TCharHelper.ToUpper(AChar: UnicodeChar): UnicodeChar; +begin + Result:= TCharacter.ToUpper(AChar); +end; + +class function TCharHelper.ToUpper(const AString: UnicodeString): UnicodeString; +begin + Result:= TCharacter.ToUpper(AString); +end; + +class function TCharHelper.ToUpper(const AString: UnicodeString; + const AOptions: TCharacterOptions): UnicodeString; +begin + Result:= TCharacter.ToUpper(AString, AOptions); +end; + +function TCharHelper.GetNumericValue: Double; +begin + Result := GetNumericValue(Self); +end; + +function TCharHelper.GetUnicodeCategory: TUnicodeCategory; +begin + Result := GetUnicodeCategory(Self); +end; + +function TCharHelper.IsControl: Boolean; +begin + Result := IsControl(Self); +end; + +function TCharHelper.IsDigit: Boolean; +begin + Result := IsDigit(Self); +end; + +function TCharHelper.IsHighSurrogate: Boolean; +begin + Result := IsHighSurrogate(Self); +end; + +function TCharHelper.IsInArray(const ASomeChars: array of Char): Boolean; +var + LChar: Char; +begin + for LChar in ASomeChars do + if (LChar = Self) then Exit(True); + Result := False; +end; + +function TCharHelper.IsLetter: Boolean; +begin + Result := IsLetter(Self); +end; + +function TCharHelper.IsLetterOrDigit: Boolean; +begin + Result := IsLetterOrDigit(Self); +end; + +function TCharHelper.IsLower: Boolean; +begin + Result := IsLower(Self); +end; + +function TCharHelper.IsLowSurrogate: Boolean; +begin + Result := IsLowSurrogate(Self); +end; + +function TCharHelper.IsNumber: Boolean; +begin + Result := IsNumber(Self); +end; + +function TCharHelper.IsPunctuation: Boolean; +begin + Result := IsPunctuation(Self); +end; + +function TCharHelper.IsSeparator: Boolean; +begin + Result := IsSeparator(Self); +end; + +function TCharHelper.IsSurrogate: Boolean; +begin + Result := IsSurrogate(Self); +end; + +function TCharHelper.IsSymbol: Boolean; +begin + Result := IsSymbol(Self); +end; + +function TCharHelper.IsUpper: Boolean; +begin + Result := IsUpper(Self); +end; + +function TCharHelper.IsWhiteSpace: Boolean; +begin + Result := IsWhiteSpace(Self); +end; + +function TCharHelper.ToLower: UnicodeChar; +begin + Result := ToLower(Self); +end; + +function TCharHelper.ToUpper: UnicodeChar; +begin + Result := ToUpper(Self); +end; + +end. + diff --git a/DelphiToFPC/DTF.Consts.pas b/DelphiToFPC/DTF.Consts.pas index 2f64570..0632078 100644 --- a/DelphiToFPC/DTF.Consts.pas +++ b/DelphiToFPC/DTF.Consts.pas @@ -1,37 +1,37 @@ -unit DTF.Consts; - -{$I zLib.inc} - -interface - -resourcestring - SInvalidSourceArray = 'Invalid source array'; - SInvalidCharCount = 'Invalid count (%d)'; - SNoMappingForUnicodeCharacter = 'No mapping for the Unicode character exists in the target multi-byte code page'; - - { System.NetEncoding } - sErrorDecodingURLText = 'Fehler beim Decodieren eines im URL-Stil (%%XX) codierten Strings bei Position %d'; - sInvalidURLEncodedChar = 'Ungültiges URL-codiertes Zeichen (%s) an Position %d'; - sInvalidHTMLEncodedChar = 'Ungültiges HTML-codiertes Zeichen (%s) an Position %d'; - - SArgumentNil = 'Argument must not be nil'; - sArgumentOutOfRange_NeedNonNegValue = 'Argument, %s, must be >= 0'; - sArgumentOutOfRange_OffLenInvalid = 'Offset and length are invalid for the given array'; - - SParamIsNil = 'Parameter %s cannot be nil'; - - SInsufficientReadBuffer = 'Insufficient buffer for requested data'; - SInvalid7BitEncodedInteger = 'Invalid 7 bit integer stream encoding'; - SReadPastEndOfStream = 'Attempt to read past end of stream'; - SInvalidStringLength = 'Invalid string length'; - SNoSurrogates = 'Surrogates not allowed as a single char'; - - SInvalidMask = '''%s'' is an invalid mask at (%d)'; - -const - INFINITE = Cardinal(-1); - -implementation - -end. - +unit DTF.Consts; + +{$I zLib.inc} + +interface + +resourcestring + SInvalidSourceArray = 'Invalid source array'; + SInvalidCharCount = 'Invalid count (%d)'; + SNoMappingForUnicodeCharacter = 'No mapping for the Unicode character exists in the target multi-byte code page'; + + { System.NetEncoding } + sErrorDecodingURLText = 'Fehler beim Decodieren eines im URL-Stil (%%XX) codierten Strings bei Position %d'; + sInvalidURLEncodedChar = 'Ungültiges URL-codiertes Zeichen (%s) an Position %d'; + sInvalidHTMLEncodedChar = 'Ungültiges HTML-codiertes Zeichen (%s) an Position %d'; + + SArgumentNil = 'Argument must not be nil'; + sArgumentOutOfRange_NeedNonNegValue = 'Argument, %s, must be >= 0'; + sArgumentOutOfRange_OffLenInvalid = 'Offset and length are invalid for the given array'; + + SParamIsNil = 'Parameter %s cannot be nil'; + + SInsufficientReadBuffer = 'Insufficient buffer for requested data'; + SInvalid7BitEncodedInteger = 'Invalid 7 bit integer stream encoding'; + SReadPastEndOfStream = 'Attempt to read past end of stream'; + SInvalidStringLength = 'Invalid string length'; + SNoSurrogates = 'Surrogates not allowed as a single char'; + + SInvalidMask = '''%s'' is an invalid mask at (%d)'; + +const + INFINITE = Cardinal(-1); + +implementation + +end. + diff --git a/DelphiToFPC/DTF.Diagnostics.pas b/DelphiToFPC/DTF.Diagnostics.pas index b3bfc49..51349bd 100644 --- a/DelphiToFPC/DTF.Diagnostics.pas +++ b/DelphiToFPC/DTF.Diagnostics.pas @@ -1,148 +1,148 @@ -unit DTF.Diagnostics; - -{$i zLib.inc} - -interface - -uses - Classes, - {$IFDEF MSWINDOWS} - Windows, - {$ENDIF} - {$IFDEF POSIX} - Unixtype, - {$ENDIF} - System.TimeSpan; - -type - TStopwatch = record - strict private - class var FFrequency: Int64; - class var FIsHighResolution: Boolean; - class var TickFrequency: Double; - strict private - FElapsed: Int64; - FRunning: Boolean; - FStartTimeStamp: Int64; - function GetElapsed: TTimeSpan; - function GetElapsedDateTimeTicks: Int64; - function GetElapsedMilliseconds: Int64; - function GetElapsedTicks: Int64; - class procedure InitStopwatchType; static; - public - class function Create: TStopwatch; static; - class function GetTimeStamp: Int64; static; - procedure Reset; - procedure Start; - class function StartNew: TStopwatch; static; - procedure Stop; - property Elapsed: TTimeSpan read GetElapsed; - property ElapsedMilliseconds: Int64 read GetElapsedMilliseconds; - property ElapsedTicks: Int64 read GetElapsedTicks; - class property Frequency: Int64 read FFrequency; - class property IsHighResolution: Boolean read FIsHighResolution; - property IsRunning: Boolean read FRunning; - end; - -implementation - -{ TStopwatch } - -class function TStopwatch.Create: TStopwatch; -begin - InitStopwatchType; - Result.Reset; -end; - -function TStopwatch.GetElapsed: TTimeSpan; -begin - Result := TTimeSpan.Create(GetElapsedDateTimeTicks); -end; - -function TStopwatch.GetElapsedDateTimeTicks: Int64; -begin - Result := ElapsedTicks; - if FIsHighResolution then - Result := Trunc(Result * TickFrequency); -end; - -function TStopwatch.GetElapsedMilliseconds: Int64; -begin - Result := GetElapsedDateTimeTicks div TTimeSpan.TicksPerMillisecond; -end; - -function TStopwatch.GetElapsedTicks: Int64; -begin - Result := FElapsed; - if FRunning then - Result := Result + GetTimeStamp - FStartTimeStamp; -end; - -class function TStopwatch.GetTimeStamp: Int64; -begin - {$IF defined(MSWINDOWS)} - if FIsHighResolution then - QueryPerformanceCounter(Result) - else - Result := TThread.GetTickCount64 * Int64(TTimeSpan.TicksPerMillisecond); - {$ELSE} - Result := TThread.GetTickCount64 * Int64(TTimeSpan.TicksPerMillisecond); - {$ENDIF} -end; - -class procedure TStopwatch.InitStopwatchType; -begin - if FFrequency = 0 then - begin - {$IF defined(MSWINDOWS)} - if not QueryPerformanceFrequency(FFrequency) then - begin - FIsHighResolution := False; - FFrequency := TTimeSpan.TicksPerSecond; - TickFrequency := 1.0; - end else - begin - FIsHighResolution := True; - TickFrequency := 10000000.0 / FFrequency; - end; - {$ELSE} - FIsHighResolution := True; - FFrequency := 10000000; // 100 Nanosecond resolution - TickFrequency := 10000000.0 / FFrequency; - {$ENDIF} - end; -end; - -procedure TStopwatch.Reset; -begin - FElapsed := 0; - FRunning := False; - FStartTimeStamp := 0; -end; - -procedure TStopwatch.Start; -begin - if not FRunning then - begin - FStartTimeStamp := GetTimeStamp; - FRunning := True; - end; -end; - -class function TStopwatch.StartNew: TStopwatch; -begin - InitStopwatchType; - Result.Reset; - Result.Start; -end; - -procedure TStopwatch.Stop; -begin - if FRunning then - begin - FElapsed := FElapsed + GetTimeStamp - FStartTimeStamp; - FRunning := False; - end; -end; - -end. +unit DTF.Diagnostics; + +{$i zLib.inc} + +interface + +uses + Classes, + {$IFDEF MSWINDOWS} + Windows, + {$ENDIF} + {$IFDEF POSIX} + Unixtype, + {$ENDIF} + System.TimeSpan; + +type + TStopwatch = record + strict private + class var FFrequency: Int64; + class var FIsHighResolution: Boolean; + class var TickFrequency: Double; + strict private + FElapsed: Int64; + FRunning: Boolean; + FStartTimeStamp: Int64; + function GetElapsed: TTimeSpan; + function GetElapsedDateTimeTicks: Int64; + function GetElapsedMilliseconds: Int64; + function GetElapsedTicks: Int64; + class procedure InitStopwatchType; static; + public + class function Create: TStopwatch; static; + class function GetTimeStamp: Int64; static; + procedure Reset; + procedure Start; + class function StartNew: TStopwatch; static; + procedure Stop; + property Elapsed: TTimeSpan read GetElapsed; + property ElapsedMilliseconds: Int64 read GetElapsedMilliseconds; + property ElapsedTicks: Int64 read GetElapsedTicks; + class property Frequency: Int64 read FFrequency; + class property IsHighResolution: Boolean read FIsHighResolution; + property IsRunning: Boolean read FRunning; + end; + +implementation + +{ TStopwatch } + +class function TStopwatch.Create: TStopwatch; +begin + InitStopwatchType; + Result.Reset; +end; + +function TStopwatch.GetElapsed: TTimeSpan; +begin + Result := TTimeSpan.Create(GetElapsedDateTimeTicks); +end; + +function TStopwatch.GetElapsedDateTimeTicks: Int64; +begin + Result := ElapsedTicks; + if FIsHighResolution then + Result := Trunc(Result * TickFrequency); +end; + +function TStopwatch.GetElapsedMilliseconds: Int64; +begin + Result := GetElapsedDateTimeTicks div TTimeSpan.TicksPerMillisecond; +end; + +function TStopwatch.GetElapsedTicks: Int64; +begin + Result := FElapsed; + if FRunning then + Result := Result + GetTimeStamp - FStartTimeStamp; +end; + +class function TStopwatch.GetTimeStamp: Int64; +begin + {$IF defined(MSWINDOWS)} + if FIsHighResolution then + QueryPerformanceCounter(Result) + else + Result := TThread.GetTickCount64 * Int64(TTimeSpan.TicksPerMillisecond); + {$ELSE} + Result := TThread.GetTickCount64 * Int64(TTimeSpan.TicksPerMillisecond); + {$ENDIF} +end; + +class procedure TStopwatch.InitStopwatchType; +begin + if FFrequency = 0 then + begin + {$IF defined(MSWINDOWS)} + if not QueryPerformanceFrequency(FFrequency) then + begin + FIsHighResolution := False; + FFrequency := TTimeSpan.TicksPerSecond; + TickFrequency := 1.0; + end else + begin + FIsHighResolution := True; + TickFrequency := 10000000.0 / FFrequency; + end; + {$ELSE} + FIsHighResolution := True; + FFrequency := 10000000; // 100 Nanosecond resolution + TickFrequency := 10000000.0 / FFrequency; + {$ENDIF} + end; +end; + +procedure TStopwatch.Reset; +begin + FElapsed := 0; + FRunning := False; + FStartTimeStamp := 0; +end; + +procedure TStopwatch.Start; +begin + if not FRunning then + begin + FStartTimeStamp := GetTimeStamp; + FRunning := True; + end; +end; + +class function TStopwatch.StartNew: TStopwatch; +begin + InitStopwatchType; + Result.Reset; + Result.Start; +end; + +procedure TStopwatch.Stop; +begin + if FRunning then + begin + FElapsed := FElapsed + GetTimeStamp - FStartTimeStamp; + FRunning := False; + end; +end; + +end. diff --git a/DelphiToFPC/DTF.Generics.pas b/DelphiToFPC/DTF.Generics.pas index acf3cad..bd2ab7a 100644 --- a/DelphiToFPC/DTF.Generics.pas +++ b/DelphiToFPC/DTF.Generics.pas @@ -1,42 +1,42 @@ -unit DTF.Generics; - -{$I zLib.inc} - -interface - -uses - Classes, - SysUtils, - Generics.Defaults, - - DTF.Types; - -type - TComparisonAnonymousFunc = reference to function(const ALeft, ARight: T): Integer; - - TDelegatedComparerAnonymousFunc = class(TComparer) - private - FComparison: TComparisonAnonymousFunc; - public - function Compare(const ALeft, ARight: T): Integer; override; - constructor Create(AComparison: TComparisonAnonymousFunc); - end; - -implementation - -{ TDelegatedComparerAnonymousFunc } - -function TDelegatedComparerAnonymousFunc.Compare(const ALeft, - ARight: T): Integer; -begin - Result := FComparison(ALeft, ARight); -end; - -constructor TDelegatedComparerAnonymousFunc.Create( - AComparison: TComparisonAnonymousFunc); -begin - FComparison := AComparison; -end; - -end. - +unit DTF.Generics; + +{$I zLib.inc} + +interface + +uses + Classes, + SysUtils, + Generics.Defaults, + + DTF.Types; + +type + TComparisonAnonymousFunc = reference to function(const ALeft, ARight: T): Integer; + + TDelegatedComparerAnonymousFunc = class(TComparer) + private + FComparison: TComparisonAnonymousFunc; + public + function Compare(const ALeft, ARight: T): Integer; override; + constructor Create(AComparison: TComparisonAnonymousFunc); + end; + +implementation + +{ TDelegatedComparerAnonymousFunc } + +function TDelegatedComparerAnonymousFunc.Compare(const ALeft, + ARight: T): Integer; +begin + Result := FComparison(ALeft, ARight); +end; + +constructor TDelegatedComparerAnonymousFunc.Create( + AComparison: TComparisonAnonymousFunc); +begin + FComparison := AComparison; +end; + +end. + diff --git a/DelphiToFPC/DTF.Hash.pas b/DelphiToFPC/DTF.Hash.pas index 2ca9cbb..1e2223f 100644 --- a/DelphiToFPC/DTF.Hash.pas +++ b/DelphiToFPC/DTF.Hash.pas @@ -1,520 +1,520 @@ -unit DTF.Hash; - -{$I zLib.inc} - -interface - -uses - SysUtils, - Classes; - -type - /// Hash related Exceptions - EHashException = class(Exception); - - /// Record with common functionality to all Hash functions - THash = record - /// Convert a Digest into an Integer if it's length its four - class function DigestAsInteger(const ADigest: TBytes): Integer; static; - /// Convert a Digest into a hexadecimal value string - class function DigestAsString(const ADigest: TBytes): string; static; - /// Convert a Digest into a GUID if it's length its sixteen - class function DigestAsStringGUID(const ADigest: TBytes): string; static; - /// Gets a random string with the given length - class function GetRandomString(const ALen: Integer = 10): string; static; - /// Gets the BigEndian memory representation of a cardinal value - class function ToBigEndian(AValue: Cardinal): Cardinal; overload; static; inline; - /// Gets the BigEndian memory representation of a UInt64 value - class function ToBigEndian(AValue: UInt64): UInt64; overload; static; inline; - end; - - /// Record to generate BobJenkins Hash values from data. Stores internal state of the process - THashBobJenkins = record - private - FHash: Integer; - function GetDigest: TBytes; - - class function HashLittle(const Data; Len, InitVal: Integer): Integer; static; - public - /// Initialize the Record used to calculate the BobJenkins Hash - class function Create: THashBobJenkins; static; - - /// Puts the state machine of the generator in it's initial state. - procedure Reset(AInitialValue: Integer = 0); - - /// Update the Hash value with the given Data. - procedure Update(const AData; ALength: Cardinal); overload; inline; - procedure Update(const AData: TBytes; ALength: Cardinal = 0); overload; inline; - procedure Update(const Input: string); overload; inline; - - /// Returns the hash value as a TBytes - function HashAsBytes: TBytes; - /// Returns the hash value as integer - function HashAsInteger: Integer; - /// Returns the hash value as string - function HashAsString: string; - - /// Hash the given string and returns it's hash value as integer - class function GetHashBytes(const AData: string): TBytes; static; - /// Hash the given string and returns it's hash value as string - class function GetHashString(const AString: string): string; static; - /// Hash the given string and returns it's hash value as integer - class function GetHashValue(const AData: string): Integer; overload; static; inline; - /// Hash the given Data and returns it's hash value as integer - class function GetHashValue(const AData; ALength: Integer; AInitialValue: Integer = 0): Integer; overload; static; inline; - end; - - /// Record to generate FNV1a 32-bit Hash values from data. Stores internal state of the process - THashFNV1a32 = record - public const - FNV_PRIME = $01000193; // 16777619 - FNV_SEED = $811C9DC5; // 2166136261 - private - FHash: Cardinal; - function GetDigest: TBytes; - - class function Hash(const Data; Len, InitVal: Cardinal): Cardinal; static; - public - /// Initialize the Record used to calculate the FNV1a Hash - class function Create: THashFNV1a32; static; - - /// Puts the state machine of the generator in it's initial state. - procedure Reset(AInitialValue: Cardinal = FNV_SEED); - - /// Update the Hash value with the given Data. - procedure Update(const AData; ALength: Cardinal); overload; inline; - procedure Update(const AData: TBytes; ALength: Cardinal = 0); overload; inline; - procedure Update(const Input: string); overload; inline; - - /// Returns the hash value as a TBytes - function HashAsBytes: TBytes; - /// Returns the hash value as integer - function HashAsInteger: Integer; - /// Returns the hash value as string - function HashAsString: string; - - /// Hash the given string and returns it's hash value as integer - class function GetHashBytes(const AData: string): TBytes; static; - /// Hash the given string and returns it's hash value as string - class function GetHashString(const AString: string): string; overload; static; - class function GetHashString(const AString: RawByteString): string; overload; static; - /// Hash the given string and returns it's hash value as integer - class function GetHashValue(const AData: string): Integer; overload; static; inline; - class function GetHashValue(const AData: RawByteString): Integer; overload; static; inline; - /// Hash the given Data and returns it's hash value as integer - class function GetHashValue(const AData; ALength: Cardinal; AInitialValue: Cardinal = FNV_SEED): Integer; overload; static; inline; - end; - -implementation - -{ THash } - -class function THash.ToBigEndian(AValue: Cardinal): Cardinal; -begin - Result := (AValue shr 24) or (AValue shl 24) or ((AValue shr 8) and $FF00) or ((AValue shl 8) and $FF0000); -end; - -class function THash.ToBigEndian(AValue: UInt64): UInt64; -begin - Result := UInt64(ToBigEndian(Cardinal(AValue))) shl 32 or ToBigEndian(Cardinal(AValue shr 32)); -end; - -class function THash.DigestAsInteger(const ADigest: TBytes): Integer; -begin - if Length(ADigest) <> 4 then - raise EHashException.Create('Digest size must be 4 to Generate a Integer'); - Result := PInteger(@ADigest[0])^; -end; - -class function THash.DigestAsString(const ADigest: TBytes): string; -const - XD: array[0..15] of char = ('0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); -var - I, L: Integer; - PC: PChar; - PB: PByte; -begin - L := Length(ADigest); - SetLength(Result, L * 2); - PC := Pointer(Result); - PB := PByte(ADigest); - for I := 0 to L - 1 do - begin - PC[0] := XD[(PB^ shr 4) and $0f]; - PC[1] := XD[PB^ and $0f]; - Inc(PC, 2); - Inc(PB); - end; -end; - -class function THash.DigestAsStringGUID(const ADigest: TBytes): string; -var - LGUID: TGUID; -begin - LGUID := TGUID.Create(ADigest); - LGUID.D1 := ToBigEndian(LGUID.D1); - LGUID.D2 := Word((WordRec(LGUID.D2).Lo shl 8) or WordRec(LGUID.D2).Hi); - LGUID.D3 := Word((WordRec(LGUID.D3).Lo shl 8) or WordRec(LGUID.D3).Hi); - Result := LGUID.ToString; -end; - -class function THash.GetRandomString(const ALen: Integer): string; -const - ValidChars: string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-/*_'; -var - I, L: Integer; - PC, PV: PChar; -begin - L := Length(ValidChars); - SetLength(Result, ALen); - PC := Pointer(Result); - PV := Pointer(ValidChars); - for I := 1 to ALen do - begin - PC^ := PV[Random(L)]; - Inc(PC); - end; -end; - -{ THashBobJenkins } - -class function THashBobJenkins.HashLittle(const Data; Len, InitVal: Integer): Integer; - function Rot(x, k: Cardinal): Cardinal; inline; - begin - Result := (x shl k) or (x shr (32 - k)); - end; - - procedure Mix(var a, b, c: Cardinal); inline; - begin - Dec(a, c); a := a xor Rot(c, 4); Inc(c, b); - Dec(b, a); b := b xor Rot(a, 6); Inc(a, c); - Dec(c, b); c := c xor Rot(b, 8); Inc(b, a); - Dec(a, c); a := a xor Rot(c,16); Inc(c, b); - Dec(b, a); b := b xor Rot(a,19); Inc(a, c); - Dec(c, b); c := c xor Rot(b, 4); Inc(b, a); - end; - - procedure Final(var a, b, c: Cardinal); inline; - begin - c := c xor b; Dec(c, Rot(b,14)); - a := a xor c; Dec(a, Rot(c,11)); - b := b xor a; Dec(b, Rot(a,25)); - c := c xor b; Dec(c, Rot(b,16)); - a := a xor c; Dec(a, Rot(c, 4)); - b := b xor a; Dec(b, Rot(a,14)); - c := c xor b; Dec(c, Rot(b,24)); - end; - -{$POINTERMATH ON} -var - pb: PByte; - pd: PCardinal absolute pb; - a, b, c: Cardinal; -label - case_1, case_2, case_3, case_4, case_5, case_6, - case_7, case_8, case_9, case_10, case_11, case_12; -begin - a := Cardinal($DEADBEEF) + Cardinal(Len) + Cardinal(InitVal); - b := a; - c := a; - - pb := @Data; - - // 4-byte aligned data - if (Cardinal(pb) and 3) = 0 then - begin - while Len > 12 do - begin - Inc(a, pd[0]); - Inc(b, pd[1]); - Inc(c, pd[2]); - Mix(a, b, c); - Dec(Len, 12); - Inc(pd, 3); - end; - - case Len of - 0: Exit(Integer(c)); - 1: Inc(a, pd[0] and $FF); - 2: Inc(a, pd[0] and $FFFF); - 3: Inc(a, pd[0] and $FFFFFF); - 4: Inc(a, pd[0]); - 5: - begin - Inc(a, pd[0]); - Inc(b, pd[1] and $FF); - end; - 6: - begin - Inc(a, pd[0]); - Inc(b, pd[1] and $FFFF); - end; - 7: - begin - Inc(a, pd[0]); - Inc(b, pd[1] and $FFFFFF); - end; - 8: - begin - Inc(a, pd[0]); - Inc(b, pd[1]); - end; - 9: - begin - Inc(a, pd[0]); - Inc(b, pd[1]); - Inc(c, pd[2] and $FF); - end; - 10: - begin - Inc(a, pd[0]); - Inc(b, pd[1]); - Inc(c, pd[2] and $FFFF); - end; - 11: - begin - Inc(a, pd[0]); - Inc(b, pd[1]); - Inc(c, pd[2] and $FFFFFF); - end; - 12: - begin - Inc(a, pd[0]); - Inc(b, pd[1]); - Inc(c, pd[2]); - end; - end; - end - else - begin - // Ignoring rare case of 2-byte aligned data. This handles all other cases. - while Len > 12 do - begin - Inc(a, pb[0] + pb[1] shl 8 + pb[2] shl 16 + pb[3] shl 24); - Inc(b, pb[4] + pb[5] shl 8 + pb[6] shl 16 + pb[7] shl 24); - Inc(c, pb[8] + pb[9] shl 8 + pb[10] shl 16 + pb[11] shl 24); - Mix(a, b, c); - Dec(Len, 12); - Inc(pb, 12); - end; - - case Len of - 0: Exit(Integer(c)); - 1: goto case_1; - 2: goto case_2; - 3: goto case_3; - 4: goto case_4; - 5: goto case_5; - 6: goto case_6; - 7: goto case_7; - 8: goto case_8; - 9: goto case_9; - 10: goto case_10; - 11: goto case_11; - 12: goto case_12; - end; - -case_12: - Inc(c, pb[11] shl 24); -case_11: - Inc(c, pb[10] shl 16); -case_10: - Inc(c, pb[9] shl 8); -case_9: - Inc(c, pb[8]); -case_8: - Inc(b, pb[7] shl 24); -case_7: - Inc(b, pb[6] shl 16); -case_6: - Inc(b, pb[5] shl 8); -case_5: - Inc(b, pb[4]); -case_4: - Inc(a, pb[3] shl 24); -case_3: - Inc(a, pb[2] shl 16); -case_2: - Inc(a, pb[1] shl 8); -case_1: - Inc(a, pb[0]); - end; - - Final(a, b, c); - Result := Integer(c); -end; - -{$POINTERMATH OFF} - -class function THashBobJenkins.Create: THashBobJenkins; -begin - Result.FHash := 0; -end; - -function THashBobJenkins.GetDigest: TBytes; -begin - SetLength(Result, 4); - PCardinal(@Result[0])^ := THash.ToBigEndian(Cardinal(FHash)); -end; - -class function THashBobJenkins.GetHashString(const AString: string): string; -begin - Result := GetHashValue(AString).ToHexString(8); -end; - -class function THashBobJenkins.GetHashValue(const AData: string): Integer; -begin - Result := HashLittle(Pointer(AData)^, Length(AData) * SizeOf(Char), 0); -end; - -class function THashBobJenkins.GetHashValue(const AData; ALength: Integer; AInitialValue: Integer): Integer; -begin - Result := HashLittle(AData, ALength, AInitialValue); -end; - -function THashBobJenkins.HashAsBytes: TBytes; -begin - Result := GetDigest; -end; - -function THashBobJenkins.HashAsInteger: Integer; -begin - Result := FHash; -end; - -function THashBobJenkins.HashAsString: string; -begin - Result := FHash.ToHexString(8); -end; - -class function THashBobJenkins.GetHashBytes(const AData: string): TBytes; -var - LHash: Integer; -begin - SetLength(Result, 4); - LHash := HashLittle(Pointer(AData)^, Length(AData) * SizeOf(Char), 0); - PCardinal(@Result[0])^ := THash.ToBigEndian(Cardinal(LHash)); -end; - -procedure THashBobJenkins.Reset(AInitialValue: Integer); -begin - FHash := AInitialValue; -end; - -procedure THashBobJenkins.Update(const Input: string); -begin - FHash := HashLittle(Pointer(Input)^, Length(Input) * SizeOf(Char), FHash); -end; - -procedure THashBobJenkins.Update(const AData; ALength: Cardinal); -begin - FHash := HashLittle(AData, ALength, FHash); -end; - -procedure THashBobJenkins.Update(const AData: TBytes; ALength: Cardinal); -begin - if ALength = 0 then - ALength := Length(AData); - FHash := HashLittle(PByte(AData)^, ALength, FHash); -end; - -{ THashFNV1a32 } - -class function THashFNV1a32.Hash(const Data; Len, InitVal: Cardinal): Cardinal; -var - P, PEnd: PByte; -begin - Result := InitVal; - P := @Data; - PEnd := P + Len; - while P < PEnd do - begin - Result := (Result xor Cardinal(P^)) * FNV_PRIME; - Inc(P); - end; -end; - -class function THashFNV1a32.Create: THashFNV1a32; -begin - Result.FHash := FNV_SEED; -end; - -function THashFNV1a32.GetDigest: TBytes; -begin - SetLength(Result, 4); - PCardinal(@Result[0])^ := FHash; -end; - -class function THashFNV1a32.GetHashString(const AString: string): string; -begin - Result := GetHashValue(AString).ToHexString(8); -end; - -class function THashFNV1a32.GetHashValue(const AData: string): Integer; -begin - Result := Integer(Hash(Pointer(AData)^, Length(AData) * SizeOf(Char), FNV_SEED)); -end; - -class function THashFNV1a32.GetHashString(const AString: RawByteString): string; -begin - Result := GetHashValue(AString).ToHexString(8); -end; - -class function THashFNV1a32.GetHashValue(const AData: RawByteString): Integer; -begin - Result := Integer(Hash(Pointer(AData)^, Length(AData), FNV_SEED)); -end; - -class function THashFNV1a32.GetHashValue(const AData; ALength: Cardinal; AInitialValue: Cardinal): Integer; -begin - Result := Integer(Hash(AData, ALength, AInitialValue)); -end; - -function THashFNV1a32.HashAsBytes: TBytes; -begin - Result := GetDigest; -end; - -function THashFNV1a32.HashAsInteger: Integer; -begin - Result := Integer(FHash); -end; - -function THashFNV1a32.HashAsString: string; -begin - Result := FHash.ToHexString(8); -end; - -class function THashFNV1a32.GetHashBytes(const AData: string): TBytes; -var - LHash: Cardinal; -begin - SetLength(Result, 4); - LHash := Hash(Pointer(AData)^, Length(AData) * SizeOf(Char), FNV_SEED); - PCardinal(@Result[0])^ := LHash; -end; - -procedure THashFNV1a32.Reset(AInitialValue: Cardinal); -begin - FHash := AInitialValue; -end; - -procedure THashFNV1a32.Update(const Input: string); -begin - FHash := Hash(Pointer(Input)^, Length(Input) * SizeOf(Char), FHash); -end; - -procedure THashFNV1a32.Update(const AData; ALength: Cardinal); -begin - FHash := Hash(AData, ALength, FHash); -end; - -procedure THashFNV1a32.Update(const AData: TBytes; ALength: Cardinal); -begin - if ALength = 0 then - ALength := Length(AData); - FHash := Hash(PByte(AData)^, ALength, FHash); -end; - -end. +unit DTF.Hash; + +{$I zLib.inc} + +interface + +uses + SysUtils, + Classes; + +type + /// Hash related Exceptions + EHashException = class(Exception); + + /// Record with common functionality to all Hash functions + THash = record + /// Convert a Digest into an Integer if it's length its four + class function DigestAsInteger(const ADigest: TBytes): Integer; static; + /// Convert a Digest into a hexadecimal value string + class function DigestAsString(const ADigest: TBytes): string; static; + /// Convert a Digest into a GUID if it's length its sixteen + class function DigestAsStringGUID(const ADigest: TBytes): string; static; + /// Gets a random string with the given length + class function GetRandomString(const ALen: Integer = 10): string; static; + /// Gets the BigEndian memory representation of a cardinal value + class function ToBigEndian(AValue: Cardinal): Cardinal; overload; static; inline; + /// Gets the BigEndian memory representation of a UInt64 value + class function ToBigEndian(AValue: UInt64): UInt64; overload; static; inline; + end; + + /// Record to generate BobJenkins Hash values from data. Stores internal state of the process + THashBobJenkins = record + private + FHash: Integer; + function GetDigest: TBytes; + + class function HashLittle(const Data; Len, InitVal: Integer): Integer; static; + public + /// Initialize the Record used to calculate the BobJenkins Hash + class function Create: THashBobJenkins; static; + + /// Puts the state machine of the generator in it's initial state. + procedure Reset(AInitialValue: Integer = 0); + + /// Update the Hash value with the given Data. + procedure Update(const AData; ALength: Cardinal); overload; inline; + procedure Update(const AData: TBytes; ALength: Cardinal = 0); overload; inline; + procedure Update(const Input: string); overload; inline; + + /// Returns the hash value as a TBytes + function HashAsBytes: TBytes; + /// Returns the hash value as integer + function HashAsInteger: Integer; + /// Returns the hash value as string + function HashAsString: string; + + /// Hash the given string and returns it's hash value as integer + class function GetHashBytes(const AData: string): TBytes; static; + /// Hash the given string and returns it's hash value as string + class function GetHashString(const AString: string): string; static; + /// Hash the given string and returns it's hash value as integer + class function GetHashValue(const AData: string): Integer; overload; static; inline; + /// Hash the given Data and returns it's hash value as integer + class function GetHashValue(const AData; ALength: Integer; AInitialValue: Integer = 0): Integer; overload; static; inline; + end; + + /// Record to generate FNV1a 32-bit Hash values from data. Stores internal state of the process + THashFNV1a32 = record + public const + FNV_PRIME = $01000193; // 16777619 + FNV_SEED = $811C9DC5; // 2166136261 + private + FHash: Cardinal; + function GetDigest: TBytes; + + class function Hash(const Data; Len, InitVal: Cardinal): Cardinal; static; + public + /// Initialize the Record used to calculate the FNV1a Hash + class function Create: THashFNV1a32; static; + + /// Puts the state machine of the generator in it's initial state. + procedure Reset(AInitialValue: Cardinal = FNV_SEED); + + /// Update the Hash value with the given Data. + procedure Update(const AData; ALength: Cardinal); overload; inline; + procedure Update(const AData: TBytes; ALength: Cardinal = 0); overload; inline; + procedure Update(const Input: string); overload; inline; + + /// Returns the hash value as a TBytes + function HashAsBytes: TBytes; + /// Returns the hash value as integer + function HashAsInteger: Integer; + /// Returns the hash value as string + function HashAsString: string; + + /// Hash the given string and returns it's hash value as integer + class function GetHashBytes(const AData: string): TBytes; static; + /// Hash the given string and returns it's hash value as string + class function GetHashString(const AString: string): string; overload; static; + class function GetHashString(const AString: RawByteString): string; overload; static; + /// Hash the given string and returns it's hash value as integer + class function GetHashValue(const AData: string): Integer; overload; static; inline; + class function GetHashValue(const AData: RawByteString): Integer; overload; static; inline; + /// Hash the given Data and returns it's hash value as integer + class function GetHashValue(const AData; ALength: Cardinal; AInitialValue: Cardinal = FNV_SEED): Integer; overload; static; inline; + end; + +implementation + +{ THash } + +class function THash.ToBigEndian(AValue: Cardinal): Cardinal; +begin + Result := (AValue shr 24) or (AValue shl 24) or ((AValue shr 8) and $FF00) or ((AValue shl 8) and $FF0000); +end; + +class function THash.ToBigEndian(AValue: UInt64): UInt64; +begin + Result := UInt64(ToBigEndian(Cardinal(AValue))) shl 32 or ToBigEndian(Cardinal(AValue shr 32)); +end; + +class function THash.DigestAsInteger(const ADigest: TBytes): Integer; +begin + if Length(ADigest) <> 4 then + raise EHashException.Create('Digest size must be 4 to Generate a Integer'); + Result := PInteger(@ADigest[0])^; +end; + +class function THash.DigestAsString(const ADigest: TBytes): string; +const + XD: array[0..15] of char = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); +var + I, L: Integer; + PC: PChar; + PB: PByte; +begin + L := Length(ADigest); + SetLength(Result, L * 2); + PC := Pointer(Result); + PB := PByte(ADigest); + for I := 0 to L - 1 do + begin + PC[0] := XD[(PB^ shr 4) and $0f]; + PC[1] := XD[PB^ and $0f]; + Inc(PC, 2); + Inc(PB); + end; +end; + +class function THash.DigestAsStringGUID(const ADigest: TBytes): string; +var + LGUID: TGUID; +begin + LGUID := TGUID.Create(ADigest); + LGUID.D1 := ToBigEndian(LGUID.D1); + LGUID.D2 := Word((WordRec(LGUID.D2).Lo shl 8) or WordRec(LGUID.D2).Hi); + LGUID.D3 := Word((WordRec(LGUID.D3).Lo shl 8) or WordRec(LGUID.D3).Hi); + Result := LGUID.ToString; +end; + +class function THash.GetRandomString(const ALen: Integer): string; +const + ValidChars: string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-/*_'; +var + I, L: Integer; + PC, PV: PChar; +begin + L := Length(ValidChars); + SetLength(Result, ALen); + PC := Pointer(Result); + PV := Pointer(ValidChars); + for I := 1 to ALen do + begin + PC^ := PV[Random(L)]; + Inc(PC); + end; +end; + +{ THashBobJenkins } + +class function THashBobJenkins.HashLittle(const Data; Len, InitVal: Integer): Integer; + function Rot(x, k: Cardinal): Cardinal; inline; + begin + Result := (x shl k) or (x shr (32 - k)); + end; + + procedure Mix(var a, b, c: Cardinal); inline; + begin + Dec(a, c); a := a xor Rot(c, 4); Inc(c, b); + Dec(b, a); b := b xor Rot(a, 6); Inc(a, c); + Dec(c, b); c := c xor Rot(b, 8); Inc(b, a); + Dec(a, c); a := a xor Rot(c,16); Inc(c, b); + Dec(b, a); b := b xor Rot(a,19); Inc(a, c); + Dec(c, b); c := c xor Rot(b, 4); Inc(b, a); + end; + + procedure Final(var a, b, c: Cardinal); inline; + begin + c := c xor b; Dec(c, Rot(b,14)); + a := a xor c; Dec(a, Rot(c,11)); + b := b xor a; Dec(b, Rot(a,25)); + c := c xor b; Dec(c, Rot(b,16)); + a := a xor c; Dec(a, Rot(c, 4)); + b := b xor a; Dec(b, Rot(a,14)); + c := c xor b; Dec(c, Rot(b,24)); + end; + +{$POINTERMATH ON} +var + pb: PByte; + pd: PCardinal absolute pb; + a, b, c: Cardinal; +label + case_1, case_2, case_3, case_4, case_5, case_6, + case_7, case_8, case_9, case_10, case_11, case_12; +begin + a := Cardinal($DEADBEEF) + Cardinal(Len) + Cardinal(InitVal); + b := a; + c := a; + + pb := @Data; + + // 4-byte aligned data + if (Cardinal(pb) and 3) = 0 then + begin + while Len > 12 do + begin + Inc(a, pd[0]); + Inc(b, pd[1]); + Inc(c, pd[2]); + Mix(a, b, c); + Dec(Len, 12); + Inc(pd, 3); + end; + + case Len of + 0: Exit(Integer(c)); + 1: Inc(a, pd[0] and $FF); + 2: Inc(a, pd[0] and $FFFF); + 3: Inc(a, pd[0] and $FFFFFF); + 4: Inc(a, pd[0]); + 5: + begin + Inc(a, pd[0]); + Inc(b, pd[1] and $FF); + end; + 6: + begin + Inc(a, pd[0]); + Inc(b, pd[1] and $FFFF); + end; + 7: + begin + Inc(a, pd[0]); + Inc(b, pd[1] and $FFFFFF); + end; + 8: + begin + Inc(a, pd[0]); + Inc(b, pd[1]); + end; + 9: + begin + Inc(a, pd[0]); + Inc(b, pd[1]); + Inc(c, pd[2] and $FF); + end; + 10: + begin + Inc(a, pd[0]); + Inc(b, pd[1]); + Inc(c, pd[2] and $FFFF); + end; + 11: + begin + Inc(a, pd[0]); + Inc(b, pd[1]); + Inc(c, pd[2] and $FFFFFF); + end; + 12: + begin + Inc(a, pd[0]); + Inc(b, pd[1]); + Inc(c, pd[2]); + end; + end; + end + else + begin + // Ignoring rare case of 2-byte aligned data. This handles all other cases. + while Len > 12 do + begin + Inc(a, pb[0] + pb[1] shl 8 + pb[2] shl 16 + pb[3] shl 24); + Inc(b, pb[4] + pb[5] shl 8 + pb[6] shl 16 + pb[7] shl 24); + Inc(c, pb[8] + pb[9] shl 8 + pb[10] shl 16 + pb[11] shl 24); + Mix(a, b, c); + Dec(Len, 12); + Inc(pb, 12); + end; + + case Len of + 0: Exit(Integer(c)); + 1: goto case_1; + 2: goto case_2; + 3: goto case_3; + 4: goto case_4; + 5: goto case_5; + 6: goto case_6; + 7: goto case_7; + 8: goto case_8; + 9: goto case_9; + 10: goto case_10; + 11: goto case_11; + 12: goto case_12; + end; + +case_12: + Inc(c, pb[11] shl 24); +case_11: + Inc(c, pb[10] shl 16); +case_10: + Inc(c, pb[9] shl 8); +case_9: + Inc(c, pb[8]); +case_8: + Inc(b, pb[7] shl 24); +case_7: + Inc(b, pb[6] shl 16); +case_6: + Inc(b, pb[5] shl 8); +case_5: + Inc(b, pb[4]); +case_4: + Inc(a, pb[3] shl 24); +case_3: + Inc(a, pb[2] shl 16); +case_2: + Inc(a, pb[1] shl 8); +case_1: + Inc(a, pb[0]); + end; + + Final(a, b, c); + Result := Integer(c); +end; + +{$POINTERMATH OFF} + +class function THashBobJenkins.Create: THashBobJenkins; +begin + Result.FHash := 0; +end; + +function THashBobJenkins.GetDigest: TBytes; +begin + SetLength(Result, 4); + PCardinal(@Result[0])^ := THash.ToBigEndian(Cardinal(FHash)); +end; + +class function THashBobJenkins.GetHashString(const AString: string): string; +begin + Result := GetHashValue(AString).ToHexString(8); +end; + +class function THashBobJenkins.GetHashValue(const AData: string): Integer; +begin + Result := HashLittle(Pointer(AData)^, Length(AData) * SizeOf(Char), 0); +end; + +class function THashBobJenkins.GetHashValue(const AData; ALength: Integer; AInitialValue: Integer): Integer; +begin + Result := HashLittle(AData, ALength, AInitialValue); +end; + +function THashBobJenkins.HashAsBytes: TBytes; +begin + Result := GetDigest; +end; + +function THashBobJenkins.HashAsInteger: Integer; +begin + Result := FHash; +end; + +function THashBobJenkins.HashAsString: string; +begin + Result := FHash.ToHexString(8); +end; + +class function THashBobJenkins.GetHashBytes(const AData: string): TBytes; +var + LHash: Integer; +begin + SetLength(Result, 4); + LHash := HashLittle(Pointer(AData)^, Length(AData) * SizeOf(Char), 0); + PCardinal(@Result[0])^ := THash.ToBigEndian(Cardinal(LHash)); +end; + +procedure THashBobJenkins.Reset(AInitialValue: Integer); +begin + FHash := AInitialValue; +end; + +procedure THashBobJenkins.Update(const Input: string); +begin + FHash := HashLittle(Pointer(Input)^, Length(Input) * SizeOf(Char), FHash); +end; + +procedure THashBobJenkins.Update(const AData; ALength: Cardinal); +begin + FHash := HashLittle(AData, ALength, FHash); +end; + +procedure THashBobJenkins.Update(const AData: TBytes; ALength: Cardinal); +begin + if ALength = 0 then + ALength := Length(AData); + FHash := HashLittle(PByte(AData)^, ALength, FHash); +end; + +{ THashFNV1a32 } + +class function THashFNV1a32.Hash(const Data; Len, InitVal: Cardinal): Cardinal; +var + P, PEnd: PByte; +begin + Result := InitVal; + P := @Data; + PEnd := P + Len; + while P < PEnd do + begin + Result := (Result xor Cardinal(P^)) * FNV_PRIME; + Inc(P); + end; +end; + +class function THashFNV1a32.Create: THashFNV1a32; +begin + Result.FHash := FNV_SEED; +end; + +function THashFNV1a32.GetDigest: TBytes; +begin + SetLength(Result, 4); + PCardinal(@Result[0])^ := FHash; +end; + +class function THashFNV1a32.GetHashString(const AString: string): string; +begin + Result := GetHashValue(AString).ToHexString(8); +end; + +class function THashFNV1a32.GetHashValue(const AData: string): Integer; +begin + Result := Integer(Hash(Pointer(AData)^, Length(AData) * SizeOf(Char), FNV_SEED)); +end; + +class function THashFNV1a32.GetHashString(const AString: RawByteString): string; +begin + Result := GetHashValue(AString).ToHexString(8); +end; + +class function THashFNV1a32.GetHashValue(const AData: RawByteString): Integer; +begin + Result := Integer(Hash(Pointer(AData)^, Length(AData), FNV_SEED)); +end; + +class function THashFNV1a32.GetHashValue(const AData; ALength: Cardinal; AInitialValue: Cardinal): Integer; +begin + Result := Integer(Hash(AData, ALength, AInitialValue)); +end; + +function THashFNV1a32.HashAsBytes: TBytes; +begin + Result := GetDigest; +end; + +function THashFNV1a32.HashAsInteger: Integer; +begin + Result := Integer(FHash); +end; + +function THashFNV1a32.HashAsString: string; +begin + Result := FHash.ToHexString(8); +end; + +class function THashFNV1a32.GetHashBytes(const AData: string): TBytes; +var + LHash: Cardinal; +begin + SetLength(Result, 4); + LHash := Hash(Pointer(AData)^, Length(AData) * SizeOf(Char), FNV_SEED); + PCardinal(@Result[0])^ := LHash; +end; + +procedure THashFNV1a32.Reset(AInitialValue: Cardinal); +begin + FHash := AInitialValue; +end; + +procedure THashFNV1a32.Update(const Input: string); +begin + FHash := Hash(Pointer(Input)^, Length(Input) * SizeOf(Char), FHash); +end; + +procedure THashFNV1a32.Update(const AData; ALength: Cardinal); +begin + FHash := Hash(AData, ALength, FHash); +end; + +procedure THashFNV1a32.Update(const AData: TBytes; ALength: Cardinal); +begin + if ALength = 0 then + ALength := Length(AData); + FHash := Hash(PByte(AData)^, ALength, FHash); +end; + +end. diff --git a/DelphiToFPC/DTF.RTL.pas b/DelphiToFPC/DTF.RTL.pas index e7a5f02..b990660 100644 --- a/DelphiToFPC/DTF.RTL.pas +++ b/DelphiToFPC/DTF.RTL.pas @@ -1,71 +1,71 @@ -unit DTF.RTL; - -{$I zLib.inc} - -interface - -uses - SysUtils - ,Classes - - {$IFDEF MSWINDOWS} - ,Windows - {$ELSE} - ,BaseUnix - {$ENDIF} - ; - -const - INFINITE = Cardinal(-1); - - {$IF DEFINED(FPC) AND NOT DEFINED(MSWINDOWS)} - EINTR = ESysEINTR; - EAGAIN = ESysEAGAIN; - EWOULDBLOCK = ESysEWOULDBLOCK; - EMFILE = ESysEMFILE; - EINPROGRESS = ESysEINPROGRESS; - - AI_PASSIVE = $00000001; - {$ENDIF} - -function GetLastError: Integer; inline; - -function GrowCollection(const AOldCapacity, ANewCount: Integer): Integer; - -function BytesOf(const Val: Pointer; const Len: Integer): TBytes; - -implementation - -function GetLastError: Integer; -begin - {$IFDEF MSWINDOWS} - Result := Windows.GetLastError; - {$ELSE} - Result := fpgeterrno; - {$ENDIF} -end; - -function GrowCollection(const AOldCapacity, ANewCount: Integer): Integer; -begin - Result := AOldCapacity; - - repeat - if Result > 64 then - Result := (Result * 3) div 2 - else - if Result > 8 then - Result := Result + 16 - else - Result := Result + 4; - if Result < 0 then - OutOfMemoryError; - until (Result >= ANewCount); -end; - -function BytesOf(const Val: Pointer; const Len: Integer): TBytes; -begin - SetLength(Result, Len); - Move(PByte(Val)^, Result[0], Len); -end; - -end. +unit DTF.RTL; + +{$I zLib.inc} + +interface + +uses + SysUtils + ,Classes + + {$IFDEF MSWINDOWS} + ,Windows + {$ELSE} + ,BaseUnix + {$ENDIF} + ; + +const + INFINITE = Cardinal(-1); + + {$IF DEFINED(FPC) AND NOT DEFINED(MSWINDOWS)} + EINTR = ESysEINTR; + EAGAIN = ESysEAGAIN; + EWOULDBLOCK = ESysEWOULDBLOCK; + EMFILE = ESysEMFILE; + EINPROGRESS = ESysEINPROGRESS; + + AI_PASSIVE = $00000001; + {$ENDIF} + +function GetLastError: Integer; inline; + +function GrowCollection(const AOldCapacity, ANewCount: Integer): Integer; + +function BytesOf(const Val: Pointer; const Len: Integer): TBytes; + +implementation + +function GetLastError: Integer; +begin + {$IFDEF MSWINDOWS} + Result := Windows.GetLastError; + {$ELSE} + Result := fpgeterrno; + {$ENDIF} +end; + +function GrowCollection(const AOldCapacity, ANewCount: Integer): Integer; +begin + Result := AOldCapacity; + + repeat + if Result > 64 then + Result := (Result * 3) div 2 + else + if Result > 8 then + Result := Result + 16 + else + Result := Result + 4; + if Result < 0 then + OutOfMemoryError; + until (Result >= ANewCount); +end; + +function BytesOf(const Val: Pointer; const Len: Integer): TBytes; +begin + SetLength(Result, Len); + Move(PByte(Val)^, Result[0], Len); +end; + +end. diff --git a/DelphiToFPC/DTF.Rtti.pas b/DelphiToFPC/DTF.Rtti.pas index 899af7f..c70bad0 100644 --- a/DelphiToFPC/DTF.Rtti.pas +++ b/DelphiToFPC/DTF.Rtti.pas @@ -1,172 +1,172 @@ -unit DTF.Rtti; - -{$I zLib.inc} - -interface - -uses - Classes, - SysUtils, - Rtti, - TypInfo; - -type - - { TRttiField } - - TRttiField = class(TRttiMember) - private - FFieldType: TRttiType; - FRecTypInfo: PTypeInfo; - FManagedField: PManagedField; - FOrder: Integer; - - function GetFieldType: TRttiType; - function GetOffset: Integer; - protected - function GetName: AnsiString; override; - function GetHandle: Pointer; override; - public - constructor Create(AParent: TRttiType; ARecTypInfo: PTypeInfo; AManagedField: PManagedField; AOrder: Integer); - destructor Destroy; override; - - function GetValue(Instance: Pointer): TValue; - procedure SetValue(Instance: Pointer; const AValue: TValue); - - property FieldType: TRttiType read GetFieldType; - property Offset: Integer read GetOffset; - end; - - //TRttiTypeHelper = class helper for TRttiType - //public - // function GetFields: TArray; - // function GetField(const AName: string): TRttiField; - //end; - -function GetRecordFields(ARecordTypeInfo: PTypeInfo): TArray; - -implementation - -function GetRecordFields(ARecordTypeInfo: PTypeInfo): TArray; -var - I: Integer; - LTypeData: PTypeData; - LMgrFieldPtr: PManagedField; - LRttiField: TRttiField; -begin - Result := []; - LTypeData := GetTypeData(ARecordTypeInfo); - if (LTypeData = nil) or (LTypeData.TotalFieldCount <= 0) then Exit; - - SetLength(Result, LTypeData.TotalFieldCount); - - LMgrFieldPtr := PManagedField(PByte(@LTypeData.TotalFieldCount) + SizeOf(LTypeData.TotalFieldCount)); - - for I := 0 to LTypeData.TotalFieldCount - 1 do - begin - LRttiField := TRttiField.Create(nil, ARecordTypeInfo, LMgrFieldPtr, I); - Result[I] := LRttiField; - - Inc(LMgrFieldPtr); - end; -end; - -{ TRttiField } - -constructor TRttiField.Create(AParent: TRttiType; ARecTypInfo: PTypeInfo; - AManagedField: PManagedField; AOrder: Integer); -begin - inherited Create(AParent); - - FRecTypInfo := ARecTypInfo; - FManagedField := AManagedField; - FOrder := AOrder; -end; - -destructor TRttiField.Destroy; -begin - inherited Destroy; -end; - -function TRttiField.GetFieldType: TRttiType; -begin - Result := Parent; -end; - -function TRttiField.GetOffset: Integer; -begin - Result := FManagedField.FldOffset; -end; - -function TRttiField.GetName: AnsiString; -begin - // FPC中只能获取到 record 成员的类型名称 - // 无法获取到成员的实际名称 - // 截止到 2023.08.16, FPC 3.3.1 依然如此 - //Result := FManagedField.TypeRef.Name; - - // 只能暂时使用 record 类型名加下标的方式给成员命名 - Result := Format('%s_field_%d', [FRecTypInfo.Name, FOrder]); -end; - -function TRttiField.GetHandle: Pointer; -begin - Result := FManagedField.TypeRef; -end; - -function TRttiField.GetValue(Instance: Pointer): TValue; -begin - TValue.Make(PByte(Instance) + Offset, Handle, Result); -end; - -procedure TRttiField.SetValue(Instance: Pointer; const AValue: TValue); -begin - AValue.ExtractRawData(PByte(Instance) + Offset); -end; - -//{ TRttiTypeHelper } -// -//function TRttiTypeHelper.GetFields: TArray; -//var -// I: Integer; -// LTypeData: PTypeData; -// LMgrFieldPtr: PManagedField; -// LRttiField: TRttiField; -//begin -// Result := []; -// LTypeData := GetTypeData(Handle); -// if (LTypeData = nil) or (LTypeData.TotalFieldCount <= 0) then Exit; -// -// SetLength(Result, LTypeData.TotalFieldCount); -// -// LMgrFieldPtr := PManagedField(PByte(@LTypeData.TotalFieldCount) + SizeOf(LTypeData.TotalFieldCount)); -// -// for I := 0 to LTypeData.TotalFieldCount - 1 do -// begin -// LRttiField := TRttiField.Create(Self, LMgrFieldPtr); -// Result[I] := LRttiField; -// //GRttiPool.AddObject(LRttiField); -// -// Inc(LMgrFieldPtr); -// end; -//end; -// -//function TRttiTypeHelper.GetField(const AName: string): TRttiField; -//var -// LFields: TArray; -// LField: TRttiField; -//begin -// Result := nil; -// LFields := GetFields; -// -// if (Length(LFields) <= 0) then Exit; -// -// for LField in LFields do -// begin -// if TStrUtils.SameText(LField.Name, AName) then -// Exit(LField); -// end; -//end; - -end. - +unit DTF.Rtti; + +{$I zLib.inc} + +interface + +uses + Classes, + SysUtils, + Rtti, + TypInfo; + +type + + { TRttiField } + + TRttiField = class(TRttiMember) + private + FFieldType: TRttiType; + FRecTypInfo: PTypeInfo; + FManagedField: PManagedField; + FOrder: Integer; + + function GetFieldType: TRttiType; + function GetOffset: Integer; + protected + function GetName: AnsiString; override; + function GetHandle: Pointer; override; + public + constructor Create(AParent: TRttiType; ARecTypInfo: PTypeInfo; AManagedField: PManagedField; AOrder: Integer); + destructor Destroy; override; + + function GetValue(Instance: Pointer): TValue; + procedure SetValue(Instance: Pointer; const AValue: TValue); + + property FieldType: TRttiType read GetFieldType; + property Offset: Integer read GetOffset; + end; + + //TRttiTypeHelper = class helper for TRttiType + //public + // function GetFields: TArray; + // function GetField(const AName: string): TRttiField; + //end; + +function GetRecordFields(ARecordTypeInfo: PTypeInfo): TArray; + +implementation + +function GetRecordFields(ARecordTypeInfo: PTypeInfo): TArray; +var + I: Integer; + LTypeData: PTypeData; + LMgrFieldPtr: PManagedField; + LRttiField: TRttiField; +begin + Result := []; + LTypeData := GetTypeData(ARecordTypeInfo); + if (LTypeData = nil) or (LTypeData.TotalFieldCount <= 0) then Exit; + + SetLength(Result, LTypeData.TotalFieldCount); + + LMgrFieldPtr := PManagedField(PByte(@LTypeData.TotalFieldCount) + SizeOf(LTypeData.TotalFieldCount)); + + for I := 0 to LTypeData.TotalFieldCount - 1 do + begin + LRttiField := TRttiField.Create(nil, ARecordTypeInfo, LMgrFieldPtr, I); + Result[I] := LRttiField; + + Inc(LMgrFieldPtr); + end; +end; + +{ TRttiField } + +constructor TRttiField.Create(AParent: TRttiType; ARecTypInfo: PTypeInfo; + AManagedField: PManagedField; AOrder: Integer); +begin + inherited Create(AParent); + + FRecTypInfo := ARecTypInfo; + FManagedField := AManagedField; + FOrder := AOrder; +end; + +destructor TRttiField.Destroy; +begin + inherited Destroy; +end; + +function TRttiField.GetFieldType: TRttiType; +begin + Result := Parent; +end; + +function TRttiField.GetOffset: Integer; +begin + Result := FManagedField.FldOffset; +end; + +function TRttiField.GetName: AnsiString; +begin + // FPC中只能获取到 record 成员的类型名称 + // 无法获取到成员的实际名称 + // 截止到 2023.08.16, FPC 3.3.1 依然如此 + //Result := FManagedField.TypeRef.Name; + + // 只能暂时使用 record 类型名加下标的方式给成员命名 + Result := Format('%s_field_%d', [FRecTypInfo.Name, FOrder]); +end; + +function TRttiField.GetHandle: Pointer; +begin + Result := FManagedField.TypeRef; +end; + +function TRttiField.GetValue(Instance: Pointer): TValue; +begin + TValue.Make(PByte(Instance) + Offset, Handle, Result); +end; + +procedure TRttiField.SetValue(Instance: Pointer; const AValue: TValue); +begin + AValue.ExtractRawData(PByte(Instance) + Offset); +end; + +//{ TRttiTypeHelper } +// +//function TRttiTypeHelper.GetFields: TArray; +//var +// I: Integer; +// LTypeData: PTypeData; +// LMgrFieldPtr: PManagedField; +// LRttiField: TRttiField; +//begin +// Result := []; +// LTypeData := GetTypeData(Handle); +// if (LTypeData = nil) or (LTypeData.TotalFieldCount <= 0) then Exit; +// +// SetLength(Result, LTypeData.TotalFieldCount); +// +// LMgrFieldPtr := PManagedField(PByte(@LTypeData.TotalFieldCount) + SizeOf(LTypeData.TotalFieldCount)); +// +// for I := 0 to LTypeData.TotalFieldCount - 1 do +// begin +// LRttiField := TRttiField.Create(Self, LMgrFieldPtr); +// Result[I] := LRttiField; +// //GRttiPool.AddObject(LRttiField); +// +// Inc(LMgrFieldPtr); +// end; +//end; +// +//function TRttiTypeHelper.GetField(const AName: string): TRttiField; +//var +// LFields: TArray; +// LField: TRttiField; +//begin +// Result := nil; +// LFields := GetFields; +// +// if (Length(LFields) <= 0) then Exit; +// +// for LField in LFields do +// begin +// if TStrUtils.SameText(LField.Name, AName) then +// Exit(LField); +// end; +//end; + +end. + diff --git a/DelphiToFPC/DTF.StreamEx.pas b/DelphiToFPC/DTF.StreamEx.pas index dd31353..6d5d67e 100644 --- a/DelphiToFPC/DTF.StreamEx.pas +++ b/DelphiToFPC/DTF.StreamEx.pas @@ -1,1835 +1,1835 @@ -unit DTF.StreamEx; - -{$I zLib.inc} - -interface - -uses - Sysutils, - Classes, - - DTF.Consts, - DTF.Character; - -type - TTextReader = class - public - procedure Close; virtual; abstract; - function Peek: Integer; virtual; abstract; - function Read: Integer; overload; virtual; abstract; - function Read(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; overload; virtual; abstract; - function ReadBlock(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; virtual; abstract; - function ReadLine: string; virtual; abstract; - function ReadToEnd: string; virtual; abstract; - procedure Rewind; virtual; abstract; - end; - - TTextWriter = class - public - procedure Close; virtual; abstract; - procedure Flush; virtual; abstract; - procedure Write(Value: Boolean); overload; virtual; abstract; - procedure Write(Value: Char); overload; virtual; abstract; - procedure Write(Value: Char; Count: Integer); overload; virtual; - procedure Write(const Value: TUnicodeCharArray); overload; virtual; abstract; - procedure Write(Value: Double); overload; virtual; abstract; - procedure Write(Value: Integer); overload; virtual; abstract; - procedure Write(Value: Int64); overload; virtual; abstract; - procedure Write(Value: TObject); overload; virtual; abstract; - procedure Write(Value: Single); overload; virtual; abstract; - procedure Write(const Value: string); overload; virtual; abstract; - procedure Write(Value: Cardinal); overload; virtual; abstract; - procedure Write(Value: UInt64); overload; virtual; abstract; - procedure Write(const Format: string; Args: array of const); overload; virtual; abstract; - procedure Write(const Value: TUnicodeCharArray; Index, Count: Integer); overload; virtual; abstract; - procedure WriteLine; overload; virtual; abstract; - procedure WriteLine(Value: Boolean); overload; virtual; abstract; - procedure WriteLine(Value: Char); overload; virtual; abstract; - procedure WriteLine(const Value: TUnicodeCharArray); overload; virtual; abstract; - procedure WriteLine(Value: Double); overload; virtual; abstract; - procedure WriteLine(Value: Integer); overload; virtual; abstract; - procedure WriteLine(Value: Int64); overload; virtual; abstract; - procedure WriteLine(Value: TObject); overload; virtual; abstract; - procedure WriteLine(Value: Single); overload; virtual; abstract; - procedure WriteLine(const Value: string); overload; virtual; abstract; - procedure WriteLine(Value: Cardinal); overload; virtual; abstract; - procedure WriteLine(Value: UInt64); overload; virtual; abstract; - procedure WriteLine(const Format: string; Args: array of const); overload; virtual; abstract; - procedure WriteLine(const Value: TUnicodeCharArray; Index, Count: Integer); overload; virtual; abstract; - end; - - TBinaryReader = class - strict private - FStream: TStream; - FEncoding: TEncoding; - FOwnsStream: Boolean; - FTwoBytesPerChar: Boolean; - FCharBytes: TBytes; - FOneChar: TUnicodeCharArray; - FMaxCharsSize: Integer; - function InternalReadChar: Integer; - function InternalReadChars(const Chars: TUnicodeCharArray; Index, Count: Integer): Integer; - protected - function GetBaseStream: TStream; virtual; - function Read7BitEncodedInt: Integer; virtual; - public - constructor Create(Stream: TStream; AEncoding: TEncoding = nil; AOwnsStream: Boolean = False); overload; - constructor Create(const Filename: string; Encoding: TEncoding = nil); overload; - destructor Destroy; override; - procedure Close; virtual; - function PeekChar: Integer; virtual; - function Read: Integer; overload; virtual; - function Read(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; overload; virtual; - function Read(const Buffer: TBytes; Index, Count: Integer): Integer; overload; virtual; - function ReadBoolean: Boolean; virtual; - function ReadByte: Byte; virtual; - function ReadBytes(Count: Integer): TBytes; virtual; - function ReadChar: Char; virtual; - function ReadChars(Count: Integer): TUnicodeCharArray; virtual; - function ReadDouble: Double; virtual; - function ReadSByte: ShortInt; inline; - function ReadShortInt: ShortInt; virtual; - function ReadSmallInt: SmallInt; virtual; - function ReadInt16: SmallInt; inline; - function ReadInteger: Integer; virtual; - function ReadInt32: Integer; inline; - function ReadInt64: Int64; virtual; - function ReadSingle: Single; virtual; - function ReadString: string; virtual; - function ReadWord: Word; virtual; - function ReadUInt16: Word; inline; - function ReadCardinal: Cardinal; virtual; - function ReadUInt32: Cardinal; inline; - function ReadUInt64: UInt64; virtual; - property BaseStream: TStream read GetBaseStream; - end; - - TBinaryWriter = class - strict private - FStream: TStream; - FOwnsStream: Boolean; - FEncoding: TEncoding; - class var FNull: TBinaryWriter; - class destructor Destroy; - class function GetNull: TBinaryWriter; static; - protected - function GetBaseStream: TStream; virtual; - procedure Write7BitEncodedInt(Value: Integer); virtual; - constructor Create; overload; - public - constructor Create(Stream: TStream); overload; - constructor Create(Stream: TStream; Encoding: TEncoding); overload; - constructor Create(Stream: TStream; Encoding: TEncoding; AOwnsStream: Boolean); overload; - constructor Create(const Filename: string; Append: Boolean = False); overload; - constructor Create(const Filename: string; Append: Boolean; Encoding: TEncoding); overload; - destructor Destroy; override; - procedure Close; virtual; - function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; virtual; - procedure Write(Value: Byte); overload; virtual; - procedure Write(Value: Boolean); overload; virtual; - procedure Write(Value: Char); overload; virtual; - procedure Write(const Value: TUnicodeCharArray); overload; virtual; - procedure Write(const Value: TBytes); overload; virtual; - procedure Write(Value: Double); overload; virtual; - procedure Write(Value: Integer); overload; virtual; - procedure Write(Value: SmallInt); overload; virtual; - procedure Write(Value: ShortInt); overload; virtual; - procedure Write(Value: Word); overload; virtual; - procedure Write(Value: Cardinal); overload; virtual; - procedure Write(Value: Int64); overload; virtual; - procedure Write(Value: Single); overload; virtual; - procedure Write(const Value: string); overload; virtual; - procedure Write(Value: UInt64); overload; virtual; - procedure Write(const Value: TUnicodeCharArray; Index, Count: Integer); overload; virtual; - procedure Write(const Value: TBytes; Index, Count: Integer); overload; virtual; - property BaseStream: TStream read GetBaseStream; - class property Null: TBinaryWriter read GetNull; - end; - - TStringReader = class(TTextReader) - private - FData: string; //String Data being read - FIndex: Integer; //Next character index to be read - public - constructor Create(S: string); - procedure Close; override; - function Peek: Integer; override; - function Read: Integer; overload; override; - function Read(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; overload; override; - function ReadBlock(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; override; - function ReadLine: string; override; - function ReadToEnd: string; override; - procedure Rewind; override; - end; - - TStringWriter = class(TTextWriter) - private - FBuilder: TUnicodeStringBuilder; - FOwnsBuilder: Boolean; - public - constructor Create; overload; - constructor Create(Builder: TUnicodeStringBuilder); overload; - destructor Destroy; override; - procedure Close; override; - procedure Flush; override; - procedure Write(Value: Boolean); override; - procedure Write(Value: Char); override; - procedure Write(Value: Char; Count: Integer); override; - procedure Write(const Value: TUnicodeCharArray); override; - procedure Write(Value: Double); override; - procedure Write(Value: Integer); override; - procedure Write(Value: Int64); override; - procedure Write(Value: TObject); override; - procedure Write(Value: Single); override; - procedure Write(const Value: string); override; - procedure Write(Value: Cardinal); override; - procedure Write(Value: UInt64); override; - procedure Write(const Format: string; Args: array of const); override; - procedure Write(const Value: TUnicodeCharArray; Index, Count: Integer); override; - procedure WriteLine; override; - procedure WriteLine(Value: Boolean); override; - procedure WriteLine(Value: Char); override; - procedure WriteLine(const Value: TUnicodeCharArray); override; - procedure WriteLine(Value: Double); override; - procedure WriteLine(Value: Integer); override; - procedure WriteLine(Value: Int64); override; - procedure WriteLine(Value: TObject); override; - procedure WriteLine(Value: Single); override; - procedure WriteLine(const Value: string); override; - procedure WriteLine(Value: Cardinal); override; - procedure WriteLine(Value: UInt64); override; - procedure WriteLine(const Format: string; Args: array of const); override; - procedure WriteLine(const Value: TUnicodeCharArray; Index, Count: Integer); override; - function ToString: string; - end; - - TStreamWriter = class(TTextWriter) - private - FStream: TStream; - FEncoding: TEncoding; - FNewLine: string; - FAutoFlush: Boolean; - FOwnsStream: Boolean; - protected - FBufferIndex: Integer; - FBuffer: TBytes; - procedure WriteBytes(Bytes: TBytes); - public - constructor Create(Stream: TStream); overload; - constructor Create(Stream: TStream; Encoding: TEncoding; BufferSize: Integer = 4096); overload; - constructor Create(const Filename: string; Append: Boolean = False); overload; - constructor Create(const Filename: string; Append: Boolean; Encoding: TEncoding; BufferSize: Integer = 4096); overload; - destructor Destroy; override; - procedure Close; override; - procedure Flush; override; - procedure OwnStream; inline; - procedure Write(Value: Boolean); override; - procedure Write(Value: Char); override; - procedure Write(const Value: TUnicodeCharArray); override; - procedure Write(Value: Double); override; - procedure Write(Value: Integer); override; - procedure Write(Value: Int64); override; - procedure Write(Value: TObject); override; - procedure Write(Value: Single); override; - procedure Write(const Value: string); override; - procedure Write(Value: Cardinal); override; - procedure Write(Value: UInt64); override; - procedure Write(const Format: string; Args: array of const); override; - procedure Write(const Value: TUnicodeCharArray; Index, Count: Integer); override; - procedure WriteLine; override; - procedure WriteLine(Value: Boolean); override; - procedure WriteLine(Value: Char); override; - procedure WriteLine(const Value: TUnicodeCharArray); override; - procedure WriteLine(Value: Double); override; - procedure WriteLine(Value: Integer); override; - procedure WriteLine(Value: Int64); override; - procedure WriteLine(Value: TObject); override; - procedure WriteLine(Value: Single); override; - procedure WriteLine(const Value: string); override; - procedure WriteLine(Value: Cardinal); override; - procedure WriteLine(Value: UInt64); override; - procedure WriteLine(const Format: string; Args: array of const); override; - procedure WriteLine(const Value: TUnicodeCharArray; Index, Count: Integer); override; - property AutoFlush: Boolean read FAutoFlush write FAutoFlush; - property NewLine: string read FNewLine write FNewLine; - property Encoding: TEncoding read FEncoding; - property BaseStream: TStream read FStream; - end; - - TStreamReader = class(TTextReader) - private type - TBufferedData = class(TUnicodeStringBuilder) - private - FStart: Integer; - FBufferSize: Integer; - function GetChars(AIndex: Integer): Char; inline; - public - constructor Create(ABufferSize: Integer); - procedure Clear; inline; - function Length: Integer; inline; - function PeekChar: Char; inline; - function MoveChar: Char; inline; - procedure MoveArray(DestinationIndex, Count: Integer; var Destination: TUnicodeCharArray); - procedure MoveString(Count, NewPos: Integer; var Destination: string); - procedure TrimBuffer; - property Chars[AIndex: Integer]: Char read GetChars; - end; - - private - FBufferSize: Integer; - FDetectBOM: Boolean; - FEncoding: TEncoding; - FOwnsStream: Boolean; - FSkipPreamble: Boolean; - FStream: TStream; - function DetectBOM(var Encoding: TEncoding; Buffer: TBytes): Integer; - function GetEndOfStream: Boolean; - function SkipPreamble(Encoding: TEncoding; Buffer: TBytes): Integer; - protected - FBufferedData: TBufferedData; - FNoDataInStream: Boolean; - procedure FillBuffer(var Encoding: TEncoding); - public - constructor Create(Stream: TStream); overload; - constructor Create(Stream: TStream; DetectBOM: Boolean); overload; - constructor Create(Stream: TStream; Encoding: TEncoding; - DetectBOM: Boolean = False; BufferSize: Integer = 4096); overload; - constructor Create(const Filename: string); overload; - constructor Create(const Filename: string; DetectBOM: Boolean); overload; - constructor Create(const Filename: string; Encoding: TEncoding; - DetectBOM: Boolean = False; BufferSize: Integer = 4096); overload; - destructor Destroy; override; - procedure Close; override; - procedure DiscardBufferedData; - procedure OwnStream; inline; - function Peek: Integer; override; - function Read: Integer; overload; override; - function Read(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; overload; override; - function ReadBlock(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; override; - function ReadLine: string; override; - function ReadToEnd: string; override; - procedure Rewind; override; - property BaseStream: TStream read FStream; - property CurrentEncoding: TEncoding read FEncoding write FEncoding; - property EndOfStream: Boolean read GetEndOfStream; - - property BufferedData: TBufferedData read FBufferedData; - property NoDataInStream: Boolean read FNoDataInStream; - end; - -implementation - -{ TTextWriter } - -procedure TTextWriter.Write(Value: Char; Count: Integer); -begin - Write(string.Create(Value, Count)); -end; - -{ TBinaryReader } - -procedure TBinaryReader.Close; -begin - if FOwnsStream then - FreeAndNil(FStream); -end; - -constructor TBinaryReader.Create(Stream: TStream; AEncoding: TEncoding; AOwnsStream: Boolean); -begin - inherited Create; - if Stream = nil then - raise EArgumentNilException.CreateRes(@SArgumentNil); - FStream := Stream; - if AEncoding = nil then - FEncoding := TEncoding.UTF8 - else - FEncoding := AEncoding; - FOwnsStream := AOwnsStream; - FTwoBytesPerChar := FEncoding is TUnicodeEncoding; - FMaxCharsSize := FEncoding.GetMaxByteCount($80); -end; - -constructor TBinaryReader.Create(const Filename: string; Encoding: TEncoding); -begin - Create(TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite), Encoding, True); -end; - -destructor TBinaryReader.Destroy; -begin - if not TEncoding.IsStandardEncoding(FEncoding) then - FEncoding.Free; - if FOwnsStream then - FStream.Free; - inherited; -end; - -function TBinaryReader.GetBaseStream: TStream; -begin - Result := FStream; -end; - -function TBinaryReader.InternalReadChar: Integer; -var - CharCount: Integer; - ByteCount: Integer; - Index: Integer; - Position: Int64; - CharByte: Byte; -begin - if FCharBytes = nil then - SetLength(FCharBytes, $80); - if FOneChar = nil then - SetLength(FOneChar, 1); - Index := 0; - Position := FStream.Position; - try - CharCount := 0; - if FTwoBytesPerChar then - ByteCount := 2 - else - ByteCount := 1; - while (CharCount = 0) and (Index < Length(FCharBytes)) do - begin - if FStream.Read(CharByte, SizeOf(CharByte)) = 0 then - ByteCount := 0; - FCharBytes[Index] := CharByte; - Inc(Index); - if ByteCount = 2 then - begin - if FStream.Read(CharByte, SizeOf(CharByte)) = 0 then - ByteCount := 1; - FCharBytes[Index] := CharByte; - Inc(Index); - end; - if ByteCount = 0 then - Exit(-1); - CharCount := FEncoding.GetChars(FCharBytes, 0, Index, FOneChar, 0); - end; - except - FStream.Position := Position; - raise; - end; - if CharCount > 0 then - Result := Integer(FOneChar[0]) - else - Result := -1; -end; - -function TBinaryReader.InternalReadChars(const Chars: TUnicodeCharArray; Index, Count: Integer): Integer; -var - BytesToRead, RemainingChars, CharCount: Integer; -begin - if FCharBytes = nil then - SetLength(FCharBytes, $80); - RemainingChars := Count; - while RemainingChars > 0 do - begin - BytesToRead := RemainingChars; - if FTwoBytesPerChar then - BytesToRead := BytesToRead shl 1; - if BytesToRead > Length(FCharBytes) then - BytesToRead := Length(FCharBytes); - BytesToRead := FStream.Read(FCharBytes[0], BytesToRead); - if BytesToRead = 0 then - Break; - CharCount := FEncoding.GetChars(FCharBytes, 0, BytesToRead, Chars, Index); - Dec(RemainingChars, CharCount); - Inc(Index, CharCount); - end; - Result := Count - RemainingChars; -end; - -function TBinaryReader.PeekChar: Integer; -var - Position: Int64; -begin - Position := FStream.Position; - try - Result := InternalReadChar; - finally - FStream.Position := Position; - end; -end; - -function TBinaryReader.Read(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; -begin - if Index < 0 then - raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Index']); // do not localize - if Count < 0 then - raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Count']); // do not localize - if Length(Buffer) - Index < Count then - raise EArgumentOutOfRangeException.CreateRes(@sArgumentOutOfRange_OffLenInvalid); - Result := InternalReadChars(Buffer, Index, Count); -end; - -function TBinaryReader.Read: Integer; -begin - Result := InternalReadChar; -end; - -function TBinaryReader.Read(const Buffer: TBytes; Index, Count: Integer): Integer; -begin - if Index < 0 then - raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Index']); // do not localize - if Count < 0 then - raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Count']); // do not localize - if Length(Buffer) - Index < Count then - raise EArgumentOutOfRangeException.CreateRes(@sArgumentOutOfRange_OffLenInvalid); - Result := FStream.Read(Buffer[Index], Count); -end; - -function TBinaryReader.Read7BitEncodedInt: Integer; -var - Shift: Integer; - Value: Integer; -begin - Shift := 0; - Result := 0; - repeat - if Shift = 35 then - raise EStreamError.CreateRes(@SInvalid7BitEncodedInteger); - Value := ReadByte; - Result := Result or ((Value and $7F) shl Shift); - Inc(Shift, 7); - until Value and $80 = 0; -end; - -function TBinaryReader.ReadBoolean: Boolean; -begin - FStream.ReadBuffer(Result, SizeOf(Result)); -end; - -function TBinaryReader.ReadByte: Byte; -begin - FStream.ReadBuffer(Result, SizeOf(Result)); -end; - -function TBinaryReader.ReadBytes(Count: Integer): TBytes; -var - BytesRead: Integer; -begin - if Count < 0 then - raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Count']); // do not localize - SetLength(Result, Count); - BytesRead := FStream.Read(Result[0], Count); - if BytesRead <> Count then - SetLength(Result, BytesRead); -end; - -function TBinaryReader.ReadCardinal: Cardinal; -begin - FStream.ReadBuffer(Result, SizeOf(Result)); -end; - -function TBinaryReader.ReadChar: Char; -var - Value: Integer; -begin - Value := Read; - if Value = -1 then - raise EStreamError.CreateRes(@SReadPastEndOfStream); - Result := Char(Value); -end; - -function TBinaryReader.ReadChars(Count: Integer): TUnicodeCharArray; -var - CharsRead: Integer; -begin - if Count < 0 then - raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Count']); // do not localize - SetLength(Result, Count); - CharsRead := InternalReadChars(Result, 0, Count); - if CharsRead <> Count then - SetLength(Result, CharsRead); -end; - -function TBinaryReader.ReadDouble: Double; -begin - FStream.ReadBuffer(Result, SizeOf(Result)); -end; - -function TBinaryReader.ReadInt64: Int64; -begin - FStream.ReadBuffer(Result, SizeOf(Result)); -end; - -function TBinaryReader.ReadInteger: Integer; -begin - FStream.ReadBuffer(Result, SizeOf(Result)); -end; - -function TBinaryReader.ReadInt32: Integer; -begin - Result := ReadInteger; -end; - -function TBinaryReader.ReadShortInt: ShortInt; -begin - FStream.ReadBuffer(Result, SizeOf(Result)); -end; - -function TBinaryReader.ReadSByte: ShortInt; -begin - Result := ReadShortInt; -end; - -function TBinaryReader.ReadSmallInt: SmallInt; -begin - FStream.ReadBuffer(Result, SizeOf(Result)); -end; - -function TBinaryReader.ReadInt16: SmallInt; -begin - Result := ReadSmallInt; -end; - -function TBinaryReader.ReadSingle: Single; -begin - FStream.ReadBuffer(Result, SizeOf(Result)); -end; - -function TBinaryReader.ReadString: string; -var - Bytes: TBytes; - ByteCount, BytesRead: Integer; -begin - ByteCount := Read7BitEncodedInt; - if ByteCount < 0 then - raise EStreamError.CreateRes(@SInvalidStringLength); - if ByteCount > 0 then - begin - SetLength(Bytes, ByteCount); - BytesRead := FStream.Read(Bytes[0], ByteCount); - if BytesRead <> ByteCount then - raise EStreamError.CreateRes(@SReadPastEndOfStream); - Result := FEncoding.GetString(Bytes); - end else - Result := ''; -end; - -function TBinaryReader.ReadUInt32: Cardinal; -begin - Result := ReadCardinal; -end; - -function TBinaryReader.ReadUInt64: UInt64; -begin - FStream.ReadBuffer(Result, SizeOf(Result)); -end; - -function TBinaryReader.ReadWord: Word; -begin - FStream.ReadBuffer(Result, SizeOf(Result)); -end; - -function TBinaryReader.ReadUInt16: Word; -begin - Result := ReadWord; -end; - -{ TNullStream } - -type - TNullStream = class(TStream) - public - function Read(var Buffer; Count: Longint): Longint; override; - function Write(const Buffer; Count: Longint): Longint; override; - function Seek(Offset: Longint; Origin: Word): Longint; overload; override; - function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; override; - end; - -function TNullStream.Read(var Buffer; Count: Longint): Longint; -begin - Result := 0; -end; - -function TNullStream.Write(const Buffer; Count: Longint): Longint; -begin - Result := 0; -end; - -function TNullStream.Seek(Offset: Longint; Origin: Word): Longint; -begin - Result := 0; -end; - -function TNullStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; -begin - Result := 0; -end; - -{ TBinaryWriter } - -constructor TBinaryWriter.Create(Stream: TStream; Encoding: TEncoding); -begin - Create(Stream, Encoding, False); -end; - -constructor TBinaryWriter.Create(Stream: TStream); -begin - Create(Stream, nil, False); -end; - -constructor TBinaryWriter.Create(Stream: TStream; Encoding: TEncoding; AOwnsStream: Boolean); -begin - inherited Create; - if Stream = nil then - raise EArgumentNilException.CreateRes(@SArgumentNil); - FStream := Stream; - if Encoding = nil then - FEncoding := TEncoding.UTF8 - else - FEncoding := Encoding; - FOwnsStream := AOwnsStream; -end; - -procedure TBinaryWriter.Close; -begin - if FOwnsStream then - FreeAndNil(FStream); -end; - -constructor TBinaryWriter.Create(const Filename: string; Append: Boolean; Encoding: TEncoding); -begin - if not Append or not FileExists(Filename) then - FStream := TFileStream.Create(Filename, fmCreate) - else - begin - FStream := TFileStream.Create(Filename, fmOpenWrite); - FStream.Seek(0, soEnd); - end; - Create(FStream, Encoding, True); -end; - -constructor TBinaryWriter.Create(const Filename: string; Append: Boolean); -begin - Create(Filename, Append, nil); -end; - -constructor TBinaryWriter.Create; -begin - Create(TNullStream.Create, nil, True); -end; - -destructor TBinaryWriter.Destroy; -begin - if not TEncoding.IsStandardEncoding(FEncoding) then - FEncoding.Free; - if FOwnsStream then - FStream.Free; - inherited; -end; - -class destructor TBinaryWriter.Destroy; -begin - FNull.Free; -end; - -class function TBinaryWriter.GetNull: TBinaryWriter; -var - Writer: TBinaryWriter; -begin - if FNull = nil then - begin - Writer := TBinaryWriter.Create; - Writer := AtomicCmpExchange(Pointer(FNull), Pointer(Writer), nil); - Writer.Free; - end; - Result := FNull; -end; - -function TBinaryWriter.GetBaseStream: TStream; -begin - Result := FStream; -end; - -function TBinaryWriter.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; -begin - Result := FStream.Seek(Offset, Origin); -end; - -procedure TBinaryWriter.Write(Value: Char); -var - Bytes: TBytes; -begin - if Value.IsSurrogate then - raise EArgumentException.CreateRes(@SNoSurrogates); - Bytes := FEncoding.GetBytes(Value); - FStream.WriteBuffer(Bytes, Length(Bytes)); -end; - -procedure TBinaryWriter.Write(Value: Byte); -begin - FStream.Write(Value, SizeOf(Value)); -end; - -procedure TBinaryWriter.Write(Value: Boolean); -begin - FStream.Write(Value, SizeOf(Value)); -end; - -procedure TBinaryWriter.Write(const Value: TUnicodeCharArray); -var - Bytes: TBytes; -begin - Bytes := FEncoding.GetBytes(Value); - FStream.WriteBuffer(Bytes, Length(Bytes)); -end; - -procedure TBinaryWriter.Write(const Value: string); -var - Bytes: TBytes; -begin - Bytes := FEncoding.GetBytes(Value); - Write7BitEncodedInt(Length(Bytes)); - FStream.WriteBuffer(Bytes, Length(Bytes)); -end; - -procedure TBinaryWriter.Write(Value: Single); -begin - FStream.Write(Value, SizeOf(Value)); -end; - -procedure TBinaryWriter.Write(Value: Int64); -begin - FStream.Write(Value, SizeOf(Value)); -end; - -procedure TBinaryWriter.Write(const Value: TBytes; Index, Count: Integer); -begin - if Index < 0 then - raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Index']); // do not localize - if Count < 0 then - raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Count']); // do not localize - if Length(Value) - Index < Count then - raise EArgumentOutOfRangeException.CreateRes(@sArgumentOutOfRange_OffLenInvalid); - FStream.WriteBuffer(Value, Index, Count); -end; - -procedure TBinaryWriter.Write(const Value: TBytes); -begin - FStream.WriteBuffer(Value, Length(Value)); -end; - -procedure TBinaryWriter.Write(const Value: TUnicodeCharArray; Index, Count: Integer); -var - Bytes: TBytes; -begin - Bytes := FEncoding.GetBytes(Value, Index, Count); - FStream.WriteBuffer(Bytes, Length(Bytes)); -end; - -procedure TBinaryWriter.Write(Value: UInt64); -begin - FStream.Write(Value, SizeOf(Value)); -end; - -procedure TBinaryWriter.Write(Value: Double); -begin - FStream.Write(Value, SizeOf(Value)); -end; - -procedure TBinaryWriter.Write(Value: SmallInt); -begin - FStream.Write(Value, SizeOf(Value)); -end; - -procedure TBinaryWriter.Write(Value: Integer); -begin - FStream.Write(Value, SizeOf(Value)); -end; - -procedure TBinaryWriter.Write(Value: Cardinal); -begin - FStream.Write(Value, SizeOf(Value)); -end; - -procedure TBinaryWriter.Write(Value: Word); -begin - FStream.Write(Value, SizeOf(Value)); -end; - -procedure TBinaryWriter.Write(Value: ShortInt); -begin - FStream.Write(Value, SizeOf(Value)); -end; - -procedure TBinaryWriter.Write7BitEncodedInt(Value: Integer); -begin - repeat - if Value > $7f then - Write(Byte((Value and $7f) or $80)) - else - Write(Byte(Value)); - Value := Value shr 7; - until Value = 0; -end; - -{ TStringReader } - -procedure TStringReader.Close; -begin - FData := ''; - FIndex := -1; -end; - -constructor TStringReader.Create(S: string); -begin - inherited Create; - - FIndex := Low(S); - FData := S; -end; - -function TStringReader.Peek: Integer; -begin - Result := -1; - if (FIndex >= Low(FData)) and (FIndex <= High(FData)) then - Result := Integer(FData[FIndex]); -end; - -function TStringReader.Read: Integer; -begin - Result := -1; - if (FIndex >= Low(FData)) and (FIndex <= High(FData)) then - begin - Result := Integer(FData[FIndex]); - Inc(FIndex); - if FIndex > High(FData) then - FIndex := -1; - end; -end; - -function TStringReader.Read(var Buffer: TUnicodeCharArray; Index, - Count: Integer): Integer; -begin - Result := -1; - - if FIndex = -1 then - Exit; - - if Length(Buffer) < Index + Count then - raise EArgumentOutOfRangeException.CreateRes(@SInsufficientReadBuffer); - - if Count > FData.Length - FIndex + Low(FData) then - Count := FData.Length - FIndex + Low(FData); - Result := Count; - - FData.CopyTo(FIndex-Low(FData), Buffer, Index, Count); - - Inc(FIndex, Count); - if FIndex > High(FData) then - FIndex := -1; -end; - -function TStringReader.ReadBlock(var Buffer: TUnicodeCharArray; Index, - Count: Integer): Integer; -begin - Result := Read(Buffer, Index, Count); -end; - -function TStringReader.ReadLine: string; -var - StartIndex: Integer; - EndIndex: Integer; -begin - Result := ''; - if FIndex = -1 then - Exit; - - StartIndex := FIndex; - EndIndex := FIndex; - - while True do - begin - if EndIndex > High(FData) then - begin - FIndex := EndIndex; - Break; - end; - if FData[EndIndex] = #10 then - begin - FIndex := EndIndex + 1; - Break; - end - else - if (FData[EndIndex] = #13) and (EndIndex + 1 <= High(FData)) and (FData[EndIndex + 1] = #10) then - begin - FIndex := EndIndex + 2; - Break; - end - else - if FData[EndIndex] = #13 then - begin - FIndex := EndIndex + 1; - Break; - end; - Inc(EndIndex); - end; - - Result := FData.SubString(StartIndex-Low(FData), (EndIndex - StartIndex)); - - if FIndex > High(FData) then - FIndex := -1; -end; - -function TStringReader.ReadToEnd: string; -begin - Result := ''; - if FIndex = -1 then - Exit; - Result := FData.SubString(FIndex-Low(FData)); - FIndex := -1; -end; - -procedure TStringReader.Rewind; -begin - FIndex := Low(FData); -end; - -{ TStringWriter } - -procedure TStringWriter.Close; -begin -end; - -constructor TStringWriter.Create; -begin - inherited Create; - - FOwnsBuilder := True; - FBuilder := TUnicodeStringBuilder.Create; -end; - -constructor TStringWriter.Create(Builder: TUnicodeStringBuilder); -begin - inherited Create; - - if not Assigned(Builder) then - raise EArgumentException.CreateResFmt(@SParamIsNil, ['Builder']); // DO NOT LOCALIZE - - FOwnsBuilder := False; - FBuilder := Builder; -end; - -destructor TStringWriter.Destroy; -begin - if FOwnsBuilder then - begin - FBuilder.Free; - FBuilder := nil; - end; - inherited; -end; - -procedure TStringWriter.Flush; -begin - -end; - -function TStringWriter.ToString: string; -begin - Result := FBuilder.ToString; -end; - -procedure TStringWriter.Write(Value: Cardinal); -begin - FBuilder.Append(Value); -end; - -procedure TStringWriter.Write(Value: Boolean); -begin - FBuilder.Append(Value); -end; - -procedure TStringWriter.Write(Value: Char); -begin - FBuilder.Append(Value); -end; - -procedure TStringWriter.Write(Value: Char; Count: Integer); -begin - FBuilder.Append(Value, Count); -end; - -procedure TStringWriter.Write(const Value: TUnicodeCharArray; Index, Count: Integer); -begin - FBuilder.Append(Value, Index, Count); -end; - -procedure TStringWriter.Write(const Format: string; Args: array of const); -begin - FBuilder.AppendFormat(Format, Args); -end; - -procedure TStringWriter.Write(Value: UInt64); -begin - FBuilder.Append(Value); -end; - -procedure TStringWriter.Write(Value: TObject); -begin - FBuilder.Append(Value); -end; - -procedure TStringWriter.Write(Value: Single); -begin - FBuilder.Append(Value); -end; - -procedure TStringWriter.Write(const Value: string); -begin - FBuilder.Append(Value); -end; - -procedure TStringWriter.Write(Value: Int64); -begin - FBuilder.Append(Value); -end; - -procedure TStringWriter.Write(const Value: TUnicodeCharArray); -begin - FBuilder.Append(Value); -end; - -procedure TStringWriter.Write(Value: Double); -begin - FBuilder.Append(Value); -end; - -procedure TStringWriter.Write(Value: Integer); -begin - FBuilder.Append(Value); -end; - -procedure TStringWriter.WriteLine(const Value: TUnicodeCharArray); -begin - FBuilder.Append(Value).AppendLine; -end; - -procedure TStringWriter.WriteLine(Value: Double); -begin - FBuilder.Append(Value).AppendLine; -end; - -procedure TStringWriter.WriteLine(Value: Integer); -begin - FBuilder.Append(Value).AppendLine; -end; - -procedure TStringWriter.WriteLine; -begin - FBuilder.AppendLine; -end; - -procedure TStringWriter.WriteLine(Value: Boolean); -begin - FBuilder.Append(Value).AppendLine; -end; - -procedure TStringWriter.WriteLine(Value: Char); -begin - FBuilder.Append(Value).AppendLine; -end; - -procedure TStringWriter.WriteLine(Value: Int64); -begin - FBuilder.Append(Value).AppendLine; -end; - -procedure TStringWriter.WriteLine(Value: UInt64); -begin - FBuilder.Append(Value).AppendLine; -end; - -procedure TStringWriter.WriteLine(const Format: string; Args: array of const); -begin - FBuilder.AppendFormat(Format, Args).AppendLine; -end; - -procedure TStringWriter.WriteLine(const Value: TUnicodeCharArray; Index, Count: Integer); -begin - FBuilder.Append(Value, Index, Count).AppendLine; -end; - -procedure TStringWriter.WriteLine(Value: Cardinal); -begin - FBuilder.Append(Value).AppendLine; -end; - -procedure TStringWriter.WriteLine(Value: TObject); -begin - FBuilder.Append(Value).AppendLine; -end; - -procedure TStringWriter.WriteLine(Value: Single); -begin - FBuilder.Append(Value).AppendLine; -end; - -procedure TStringWriter.WriteLine(const Value: string); -begin - FBuilder.Append(Value).AppendLine; -end; - -{ TStreamWriter } - -procedure TStreamWriter.Close; -begin - Flush; - if FOwnsStream then - FreeAndNil(FStream); -end; - -constructor TStreamWriter.Create(Stream: TStream); -begin - inherited Create; - FOwnsStream := False; - FStream := Stream; - FEncoding := TEncoding.UTF8; - SetLength(FBuffer, 1024); - FBufferIndex := 0; - FNewLine := sLineBreak; - FAutoFlush := True; -end; - -constructor TStreamWriter.Create(Stream: TStream; Encoding: TEncoding; BufferSize: Integer); -begin - inherited Create; - FOwnsStream := False; - FStream := Stream; - FEncoding := Encoding; - if BufferSize >= 128 then - SetLength(FBuffer, BufferSize) - else - SetLength(FBuffer, 128); - FBufferIndex := 0; - FNewLine := sLineBreak; - FAutoFlush := True; - if Stream.Position = 0 then - WriteBytes(FEncoding.GetPreamble); -end; - -constructor TStreamWriter.Create(const Filename: string; Append: Boolean); -begin - if not Append or not FileExists(Filename) then - FStream := TFileStream.Create(Filename, fmCreate) - else - begin - FStream := TFileStream.Create(Filename, fmOpenWrite); - FStream.Seek(0, soEnd); - end; - Create(FStream); - FOwnsStream := True; -end; - -constructor TStreamWriter.Create(const Filename: string; Append: Boolean; - Encoding: TEncoding; BufferSize: Integer); -begin - if not Append or not FileExists(Filename) then - FStream := TFileStream.Create(Filename, fmCreate) - else - begin - FStream := TFileStream.Create(Filename, fmOpenWrite); - FStream.Seek(0, soEnd); - end; - Create(FStream, Encoding, BufferSize); - FOwnsStream := True; -end; - -destructor TStreamWriter.Destroy; -begin - Close; - SetLength(FBuffer, 0); - inherited; -end; - -procedure TStreamWriter.Flush; -begin - if FBufferIndex = 0 then - Exit; - if FStream = nil then - Exit; - - try - FStream.WriteBuffer(FBuffer, 0, FBufferIndex); - finally - FBufferIndex := 0; - end; -end; - -procedure TStreamWriter.OwnStream; -begin - FOwnsStream := True; -end; - -procedure TStreamWriter.Write(Value: Cardinal); -begin - WriteBytes(FEncoding.GetBytes(UIntToStr(Value))); -end; - -procedure TStreamWriter.Write(const Value: string); -begin - WriteBytes(FEncoding.GetBytes(Value)); -end; - -procedure TStreamWriter.Write(Value: UInt64); -begin - WriteBytes(FEncoding.GetBytes(UIntToStr(Value))); -end; - -procedure TStreamWriter.Write(const Value: TUnicodeCharArray; Index, Count: Integer); -var - Bytes: TBytes; -begin - SetLength(Bytes, Count * 4); - SetLength(Bytes, FEncoding.GetBytes(Value, Index, Count, Bytes, 0)); - WriteBytes(Bytes); -end; - -procedure TStreamWriter.WriteBytes(Bytes: TBytes); -var - ByteIndex: Integer; - WriteLen: Integer; -begin - ByteIndex := 0; - - while ByteIndex < Length(Bytes) do - begin - WriteLen := Length(Bytes) - ByteIndex; - if WriteLen > Length(FBuffer) - FBufferIndex then - WriteLen := Length(FBuffer) - FBufferIndex; - - Move(Bytes[ByteIndex], FBuffer[FBufferIndex], WriteLen); - - Inc(FBufferIndex, WriteLen); - Inc(ByteIndex, WriteLen); - - if FBufferIndex >= Length(FBuffer) then - Flush; - end; - - if FAutoFlush then - Flush; -end; - -procedure TStreamWriter.Write(const Format: string; Args: array of const); -begin - WriteBytes(FEncoding.GetBytes(SysUtils.Format(Format, Args))); -end; - -procedure TStreamWriter.Write(Value: Single); -begin - WriteBytes(FEncoding.GetBytes(FloatToStr(Value))); -end; - -procedure TStreamWriter.Write(const Value: TUnicodeCharArray); -begin - WriteBytes(FEncoding.GetBytes(Value)); -end; - -procedure TStreamWriter.Write(Value: Double); -begin - WriteBytes(FEncoding.GetBytes(FloatToStr(Value))); -end; - -procedure TStreamWriter.Write(Value: Integer); -begin - WriteBytes(FEncoding.GetBytes(IntToStr(Value))); -end; - -procedure TStreamWriter.Write(Value: Char); -begin - WriteBytes(FEncoding.GetBytes(Value)); -end; - -procedure TStreamWriter.Write(Value: TObject); -begin - WriteBytes(FEncoding.GetBytes(Value.ToString)); -end; - -procedure TStreamWriter.Write(Value: Int64); -begin - WriteBytes(FEncoding.GetBytes(IntToStr(Value))); -end; - -procedure TStreamWriter.Write(Value: Boolean); -begin - WriteBytes(FEncoding.GetBytes(BoolToStr(Value, True))); -end; - -procedure TStreamWriter.WriteLine(const Value: TUnicodeCharArray); -begin - WriteBytes(FEncoding.GetBytes(Value)); - WriteBytes(FEncoding.GetBytes(FNewLine)); -end; - -procedure TStreamWriter.WriteLine(Value: Double); -begin - WriteBytes(FEncoding.GetBytes(FloatToStr(Value) + FNewLine)); -end; - -procedure TStreamWriter.WriteLine(Value: Integer); -begin - WriteBytes(FEncoding.GetBytes(IntToStr(Value) + FNewLine)); -end; - -procedure TStreamWriter.WriteLine; -begin - WriteBytes(FEncoding.GetBytes(FNewLine)); -end; - -procedure TStreamWriter.WriteLine(Value: Boolean); -begin - WriteBytes(FEncoding.GetBytes(BoolToStr(Value, True) + FNewLine)); -end; - -procedure TStreamWriter.WriteLine(Value: Char); -begin - WriteBytes(FEncoding.GetBytes(Value)); - WriteBytes(FEncoding.GetBytes(FNewLine)); -end; - -procedure TStreamWriter.WriteLine(Value: Int64); -begin - WriteBytes(FEncoding.GetBytes(IntToStr(Value) + FNewLine)); -end; - -procedure TStreamWriter.WriteLine(Value: UInt64); -begin - WriteBytes(FEncoding.GetBytes(UIntToStr(Value) + FNewLine)); -end; - -procedure TStreamWriter.WriteLine(const Format: string; Args: array of const); -begin - WriteBytes(FEncoding.GetBytes(SysUtils.Format(Format, Args) + FNewLine)); -end; - -procedure TStreamWriter.WriteLine(const Value: TUnicodeCharArray; Index, Count: Integer); -var - Bytes: TBytes; -begin - SetLength(Bytes, Count * 4); - SetLength(Bytes, FEncoding.GetBytes(Value, Index, Count, Bytes, 0)); - WriteBytes(Bytes); - WriteBytes(FEncoding.GetBytes(FNewLine)); -end; - -procedure TStreamWriter.WriteLine(Value: Cardinal); -begin - WriteBytes(FEncoding.GetBytes(UIntToStr(Value) + FNewLine)); -end; - -procedure TStreamWriter.WriteLine(Value: TObject); -begin - WriteBytes(FEncoding.GetBytes(Value.ToString + FNewLine)); -end; - -procedure TStreamWriter.WriteLine(Value: Single); -begin - WriteBytes(FEncoding.GetBytes(FloatToStr(Value) + FNewLine)); -end; - -procedure TStreamWriter.WriteLine(const Value: string); -begin - WriteBytes(FEncoding.GetBytes(Value + FNewLine)); -end; - -{ TStreamReader.TBufferedData } - -constructor TStreamReader.TBufferedData.Create(ABufferSize: Integer); -begin - inherited Create; - FBufferSize := ABufferSize; -end; - -procedure TStreamReader.TBufferedData.Clear; -begin - inherited Length := 0; - FStart := 0; -end; - -function TStreamReader.TBufferedData.GetChars(AIndex: Integer): Char; -begin - Result := FData[FStart + 1 + AIndex]; -end; - -function TStreamReader.TBufferedData.Length: Integer; -begin - Result := FLength - FStart; -end; - -function TStreamReader.TBufferedData.PeekChar: Char; -begin - Result := FData[FStart + 1]; -end; - -function TStreamReader.TBufferedData.MoveChar: Char; -begin - Result := FData[FStart + 1]; - Inc(FStart); -end; - -procedure TStreamReader.TBufferedData.MoveArray(DestinationIndex, Count: Integer; - var Destination: TUnicodeCharArray); -begin - CopyTo(FStart, Destination, DestinationIndex, Count); - Inc(FStart, Count); -end; - -procedure TStreamReader.TBufferedData.MoveString(Count, NewPos: Integer; - var Destination: string); -begin - if (FStart = 0) and (Count = inherited Length) then - Destination := ToString - else - Destination := ToString(FStart, Count); - Inc(FStart, NewPos); -end; - -procedure TStreamReader.TBufferedData.TrimBuffer; -begin - if inherited Length > FBufferSize then - begin - Remove(0, FStart); - FStart := 0; - end; -end; - -{ TStreamReader } - -constructor TStreamReader.Create(Stream: TStream); -begin - Create(Stream, TEncoding.UTF8, True); -end; - -constructor TStreamReader.Create(Stream: TStream; DetectBOM: Boolean); -begin - Create(Stream, TEncoding.UTF8, DetectBOM); -end; - -constructor TStreamReader.Create(Stream: TStream; Encoding: TEncoding; - DetectBOM: Boolean; BufferSize: Integer); -begin - inherited Create; - - if not Assigned(Stream) then - raise EArgumentException.CreateResFmt(@SParamIsNil, ['Stream']); // DO NOT LOCALIZE - if not Assigned(Encoding) then - raise EArgumentException.CreateResFmt(@SParamIsNil, ['Encoding']); // DO NOT LOCALIZE - - FEncoding := Encoding; - FBufferSize := BufferSize; - if FBufferSize < 128 then - FBufferSize := 128; - FBufferedData := TBufferedData.Create(FBufferSize); - FNoDataInStream := False; - FStream := Stream; - FOwnsStream := False; - FDetectBOM := DetectBOM; - FSkipPreamble := not FDetectBOM; -end; - -constructor TStreamReader.Create(const Filename: string; Encoding: TEncoding; - DetectBOM: Boolean; BufferSize: Integer); -begin - Create(TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite), Encoding, DetectBOM, BufferSize); - FOwnsStream := True; -end; - -constructor TStreamReader.Create(const Filename: string; DetectBOM: Boolean); -begin - Create(TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite), DetectBOM); - FOwnsStream := True; -end; - -constructor TStreamReader.Create(const Filename: string); -begin - Create(TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite)); - FOwnsStream := True; -end; - -destructor TStreamReader.Destroy; -begin - Close; - inherited; -end; - -procedure TStreamReader.Close; -begin - if FOwnsStream then - FreeAndNil(FStream); - FreeAndNil(FBufferedData); -end; - -procedure TStreamReader.DiscardBufferedData; -begin - if FBufferedData <> nil then - begin - FBufferedData.Clear; - FNoDataInStream := False; - end; -end; - -function TStreamReader.DetectBOM(var Encoding: TEncoding; Buffer: TBytes): Integer; -var - LEncoding: TEncoding; -begin - // try to automatically detect the buffer encoding - LEncoding := nil; - Result := TEncoding.GetBufferEncoding(Buffer, LEncoding, nil); - if LEncoding <> nil then - Encoding := LEncoding - else if Encoding = nil then - Encoding := TEncoding.Default; - - FDetectBOM := False; -end; - -procedure TStreamReader.FillBuffer(var Encoding: TEncoding); -const - BufferPadding = 4; -var - LString: string; - LBuffer: TBytes; - BytesRead: Integer; - StartIndex: Integer; - ByteCount: Integer; - ByteBufLen: Integer; - ExtraByteCount: Integer; - - procedure AdjustEndOfBuffer(const ABuffer: TBytes; Offset: Integer); - var - Pos, Size: Integer; - Rewind: Integer; - begin - Dec(Offset); - for Pos := Offset downto 0 do - begin - for Size := Offset - Pos + 1 downto 1 do - begin - if Encoding.GetCharCount(ABuffer, Pos, Size) > 0 then - begin - Rewind := Offset - (Pos + Size - 1); - if Rewind <> 0 then - begin - FStream.Position := FStream.Position - Rewind; - BytesRead := BytesRead - Rewind; - end; - Exit; - end; - end; - end; - end; - -begin - SetLength(LBuffer, FBufferSize + BufferPadding); - - // Read data from stream - BytesRead := FStream.Read(LBuffer[0], FBufferSize); - FNoDataInStream := BytesRead = 0; - - // Check for byte order mark and calc start index for character data - if FDetectBOM then - StartIndex := DetectBOM(Encoding, LBuffer) - else if FSkipPreamble then - StartIndex := SkipPreamble(Encoding, LBuffer) - else - StartIndex := 0; - - // Adjust the end of the buffer to be sure we have a valid encoding - if not FNoDataInStream then - AdjustEndOfBuffer(LBuffer, BytesRead); - - // Convert to string and calc byte count for the string - ByteBufLen := BytesRead - StartIndex; - LString := FEncoding.GetString(LBuffer, StartIndex, ByteBufLen); - ByteCount := FEncoding.GetByteCount(LString); - - // If byte count <> number of bytes read from the stream - // the buffer boundary is mid-character and additional bytes - // need to be read from the stream to complete the character - ExtraByteCount := 0; - while (ByteCount <> ByteBufLen) and (ExtraByteCount < FEncoding.GetMaxByteCount(1)) do - begin - // Expand buffer if padding is used - if (StartIndex + ByteBufLen) = Length(LBuffer) then - SetLength(LBuffer, Length(LBuffer) + BufferPadding); - - // Read one more byte from the stream into the - // buffer padding and convert to string again - BytesRead := FStream.Read(LBuffer[StartIndex + ByteBufLen], 1); - if BytesRead = 0 then - // End of stream, append what's been read and discard remaining bytes - Break; - - Inc(ExtraByteCount); - - Inc(ByteBufLen); - LString := FEncoding.GetString(LBuffer, StartIndex, ByteBufLen); - ByteCount := FEncoding.GetByteCount(LString); - end; - - // Add string to character data buffer - FBufferedData.Append(LString); -end; - -function TStreamReader.GetEndOfStream: Boolean; -begin - if not FNoDataInStream and (FBufferedData <> nil) and (FBufferedData.Length < 1) then - FillBuffer(FEncoding); - Result := FNoDataInStream and ((FBufferedData = nil) or (FBufferedData.Length = 0)); -end; - -procedure TStreamReader.OwnStream; -begin - FOwnsStream := True; -end; - -function TStreamReader.Peek: Integer; -begin - Result := -1; - if (FBufferedData <> nil) and (not EndOfStream) then - begin - if FBufferedData.Length < 1 then - FillBuffer(FEncoding); - Result := Integer(FBufferedData.PeekChar); - end; -end; - -function TStreamReader.Read(var Buffer: TUnicodeCharArray; Index, - Count: Integer): Integer; -begin - Result := -1; - if (FBufferedData <> nil) and (not EndOfStream) then - begin - while (FBufferedData.Length < Count) and (not EndOfStream) and (not FNoDataInStream) do - FillBuffer(FEncoding); - - if FBufferedData.Length > Count then - Result := Count - else - Result := FBufferedData.Length; - - FBufferedData.MoveArray(Index, Result, Buffer); - FBufferedData.TrimBuffer; - end; -end; - -function TStreamReader.ReadBlock(var Buffer: TUnicodeCharArray; Index, - Count: Integer): Integer; -begin - Result := Read(Buffer, Index, Count); -end; - -function TStreamReader.Read: Integer; -begin - Result := -1; - if (FBufferedData <> nil) and (not EndOfStream) then - begin - if FBufferedData.Length < 1 then - FillBuffer(FEncoding); - Result := Integer(FBufferedData.MoveChar); - end; -end; - -function TStreamReader.ReadLine: string; -var - NewLineIndex: Integer; - PostNewLineIndex: Integer; - LChar: Char; -begin - Result := ''; - if FBufferedData = nil then - Exit; - NewLineIndex := 0; - PostNewLineIndex := 0; - - while True do - begin - if (NewLineIndex + 2 > FBufferedData.Length) and (not FNoDataInStream) then - FillBuffer(FEncoding); - - if NewLineIndex >= FBufferedData.Length then - begin - if FNoDataInStream then - begin - PostNewLineIndex := NewLineIndex; - Break; - end - else - begin - FillBuffer(FEncoding); - if FBufferedData.Length = 0 then - Break; - end; - end; - LChar := FBufferedData.Chars[NewLineIndex]; - if LChar = #10 then - begin - PostNewLineIndex := NewLineIndex + 1; - Break; - end - else if LChar = #13 then - begin - if (NewLineIndex + 1 < FBufferedData.Length) and (FBufferedData.Chars[NewLineIndex + 1] = #10) then - PostNewLineIndex := NewLineIndex + 2 - else - PostNewLineIndex := NewLineIndex + 1; - Break; - end; - - Inc(NewLineIndex); - end; - - FBufferedData.MoveString(NewLineIndex, PostNewLineIndex, Result); - FBufferedData.TrimBuffer; -end; - -function TStreamReader.ReadToEnd: string; -begin - Result := ''; - if (FBufferedData <> nil) and (not EndOfStream) then - begin - repeat - FillBuffer(FEncoding); - until FNoDataInStream; - FBufferedData.MoveString(FBufferedData.Length, FBufferedData.Length, Result); - FBufferedData.Clear; - end; -end; - -function TStreamReader.SkipPreamble(Encoding: TEncoding; Buffer: TBytes): Integer; -var - I: Integer; - LPreamble: TBytes; - BOMPresent: Boolean; -begin - Result := 0; - LPreamble := Encoding.GetPreamble; - if (Length(LPreamble) > 0) then - begin - if Length(Buffer) >= Length(LPreamble) then - begin - BOMPresent := True; - for I := 0 to Length(LPreamble) - 1 do - if LPreamble[I] <> Buffer[I] then - begin - BOMPresent := False; - Break; - end; - if BOMPresent then - Result := Length(LPreamble); - end; - end; - FSkipPreamble := False; -end; - -procedure TStreamReader.Rewind; -begin - DiscardBufferedData; - FSkipPreamble := not FDetectBOM; - FStream.Position := 0; -end; - -end. +unit DTF.StreamEx; + +{$I zLib.inc} + +interface + +uses + Sysutils, + Classes, + + DTF.Consts, + DTF.Character; + +type + TTextReader = class + public + procedure Close; virtual; abstract; + function Peek: Integer; virtual; abstract; + function Read: Integer; overload; virtual; abstract; + function Read(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; overload; virtual; abstract; + function ReadBlock(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; virtual; abstract; + function ReadLine: string; virtual; abstract; + function ReadToEnd: string; virtual; abstract; + procedure Rewind; virtual; abstract; + end; + + TTextWriter = class + public + procedure Close; virtual; abstract; + procedure Flush; virtual; abstract; + procedure Write(Value: Boolean); overload; virtual; abstract; + procedure Write(Value: Char); overload; virtual; abstract; + procedure Write(Value: Char; Count: Integer); overload; virtual; + procedure Write(const Value: TUnicodeCharArray); overload; virtual; abstract; + procedure Write(Value: Double); overload; virtual; abstract; + procedure Write(Value: Integer); overload; virtual; abstract; + procedure Write(Value: Int64); overload; virtual; abstract; + procedure Write(Value: TObject); overload; virtual; abstract; + procedure Write(Value: Single); overload; virtual; abstract; + procedure Write(const Value: string); overload; virtual; abstract; + procedure Write(Value: Cardinal); overload; virtual; abstract; + procedure Write(Value: UInt64); overload; virtual; abstract; + procedure Write(const Format: string; Args: array of const); overload; virtual; abstract; + procedure Write(const Value: TUnicodeCharArray; Index, Count: Integer); overload; virtual; abstract; + procedure WriteLine; overload; virtual; abstract; + procedure WriteLine(Value: Boolean); overload; virtual; abstract; + procedure WriteLine(Value: Char); overload; virtual; abstract; + procedure WriteLine(const Value: TUnicodeCharArray); overload; virtual; abstract; + procedure WriteLine(Value: Double); overload; virtual; abstract; + procedure WriteLine(Value: Integer); overload; virtual; abstract; + procedure WriteLine(Value: Int64); overload; virtual; abstract; + procedure WriteLine(Value: TObject); overload; virtual; abstract; + procedure WriteLine(Value: Single); overload; virtual; abstract; + procedure WriteLine(const Value: string); overload; virtual; abstract; + procedure WriteLine(Value: Cardinal); overload; virtual; abstract; + procedure WriteLine(Value: UInt64); overload; virtual; abstract; + procedure WriteLine(const Format: string; Args: array of const); overload; virtual; abstract; + procedure WriteLine(const Value: TUnicodeCharArray; Index, Count: Integer); overload; virtual; abstract; + end; + + TBinaryReader = class + strict private + FStream: TStream; + FEncoding: TEncoding; + FOwnsStream: Boolean; + FTwoBytesPerChar: Boolean; + FCharBytes: TBytes; + FOneChar: TUnicodeCharArray; + FMaxCharsSize: Integer; + function InternalReadChar: Integer; + function InternalReadChars(const Chars: TUnicodeCharArray; Index, Count: Integer): Integer; + protected + function GetBaseStream: TStream; virtual; + function Read7BitEncodedInt: Integer; virtual; + public + constructor Create(Stream: TStream; AEncoding: TEncoding = nil; AOwnsStream: Boolean = False); overload; + constructor Create(const Filename: string; Encoding: TEncoding = nil); overload; + destructor Destroy; override; + procedure Close; virtual; + function PeekChar: Integer; virtual; + function Read: Integer; overload; virtual; + function Read(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; overload; virtual; + function Read(const Buffer: TBytes; Index, Count: Integer): Integer; overload; virtual; + function ReadBoolean: Boolean; virtual; + function ReadByte: Byte; virtual; + function ReadBytes(Count: Integer): TBytes; virtual; + function ReadChar: Char; virtual; + function ReadChars(Count: Integer): TUnicodeCharArray; virtual; + function ReadDouble: Double; virtual; + function ReadSByte: ShortInt; inline; + function ReadShortInt: ShortInt; virtual; + function ReadSmallInt: SmallInt; virtual; + function ReadInt16: SmallInt; inline; + function ReadInteger: Integer; virtual; + function ReadInt32: Integer; inline; + function ReadInt64: Int64; virtual; + function ReadSingle: Single; virtual; + function ReadString: string; virtual; + function ReadWord: Word; virtual; + function ReadUInt16: Word; inline; + function ReadCardinal: Cardinal; virtual; + function ReadUInt32: Cardinal; inline; + function ReadUInt64: UInt64; virtual; + property BaseStream: TStream read GetBaseStream; + end; + + TBinaryWriter = class + strict private + FStream: TStream; + FOwnsStream: Boolean; + FEncoding: TEncoding; + class var FNull: TBinaryWriter; + class destructor Destroy; + class function GetNull: TBinaryWriter; static; + protected + function GetBaseStream: TStream; virtual; + procedure Write7BitEncodedInt(Value: Integer); virtual; + constructor Create; overload; + public + constructor Create(Stream: TStream); overload; + constructor Create(Stream: TStream; Encoding: TEncoding); overload; + constructor Create(Stream: TStream; Encoding: TEncoding; AOwnsStream: Boolean); overload; + constructor Create(const Filename: string; Append: Boolean = False); overload; + constructor Create(const Filename: string; Append: Boolean; Encoding: TEncoding); overload; + destructor Destroy; override; + procedure Close; virtual; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; virtual; + procedure Write(Value: Byte); overload; virtual; + procedure Write(Value: Boolean); overload; virtual; + procedure Write(Value: Char); overload; virtual; + procedure Write(const Value: TUnicodeCharArray); overload; virtual; + procedure Write(const Value: TBytes); overload; virtual; + procedure Write(Value: Double); overload; virtual; + procedure Write(Value: Integer); overload; virtual; + procedure Write(Value: SmallInt); overload; virtual; + procedure Write(Value: ShortInt); overload; virtual; + procedure Write(Value: Word); overload; virtual; + procedure Write(Value: Cardinal); overload; virtual; + procedure Write(Value: Int64); overload; virtual; + procedure Write(Value: Single); overload; virtual; + procedure Write(const Value: string); overload; virtual; + procedure Write(Value: UInt64); overload; virtual; + procedure Write(const Value: TUnicodeCharArray; Index, Count: Integer); overload; virtual; + procedure Write(const Value: TBytes; Index, Count: Integer); overload; virtual; + property BaseStream: TStream read GetBaseStream; + class property Null: TBinaryWriter read GetNull; + end; + + TStringReader = class(TTextReader) + private + FData: string; //String Data being read + FIndex: Integer; //Next character index to be read + public + constructor Create(S: string); + procedure Close; override; + function Peek: Integer; override; + function Read: Integer; overload; override; + function Read(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; overload; override; + function ReadBlock(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; override; + function ReadLine: string; override; + function ReadToEnd: string; override; + procedure Rewind; override; + end; + + TStringWriter = class(TTextWriter) + private + FBuilder: TUnicodeStringBuilder; + FOwnsBuilder: Boolean; + public + constructor Create; overload; + constructor Create(Builder: TUnicodeStringBuilder); overload; + destructor Destroy; override; + procedure Close; override; + procedure Flush; override; + procedure Write(Value: Boolean); override; + procedure Write(Value: Char); override; + procedure Write(Value: Char; Count: Integer); override; + procedure Write(const Value: TUnicodeCharArray); override; + procedure Write(Value: Double); override; + procedure Write(Value: Integer); override; + procedure Write(Value: Int64); override; + procedure Write(Value: TObject); override; + procedure Write(Value: Single); override; + procedure Write(const Value: string); override; + procedure Write(Value: Cardinal); override; + procedure Write(Value: UInt64); override; + procedure Write(const Format: string; Args: array of const); override; + procedure Write(const Value: TUnicodeCharArray; Index, Count: Integer); override; + procedure WriteLine; override; + procedure WriteLine(Value: Boolean); override; + procedure WriteLine(Value: Char); override; + procedure WriteLine(const Value: TUnicodeCharArray); override; + procedure WriteLine(Value: Double); override; + procedure WriteLine(Value: Integer); override; + procedure WriteLine(Value: Int64); override; + procedure WriteLine(Value: TObject); override; + procedure WriteLine(Value: Single); override; + procedure WriteLine(const Value: string); override; + procedure WriteLine(Value: Cardinal); override; + procedure WriteLine(Value: UInt64); override; + procedure WriteLine(const Format: string; Args: array of const); override; + procedure WriteLine(const Value: TUnicodeCharArray; Index, Count: Integer); override; + function ToString: string; + end; + + TStreamWriter = class(TTextWriter) + private + FStream: TStream; + FEncoding: TEncoding; + FNewLine: string; + FAutoFlush: Boolean; + FOwnsStream: Boolean; + protected + FBufferIndex: Integer; + FBuffer: TBytes; + procedure WriteBytes(Bytes: TBytes); + public + constructor Create(Stream: TStream); overload; + constructor Create(Stream: TStream; Encoding: TEncoding; BufferSize: Integer = 4096); overload; + constructor Create(const Filename: string; Append: Boolean = False); overload; + constructor Create(const Filename: string; Append: Boolean; Encoding: TEncoding; BufferSize: Integer = 4096); overload; + destructor Destroy; override; + procedure Close; override; + procedure Flush; override; + procedure OwnStream; inline; + procedure Write(Value: Boolean); override; + procedure Write(Value: Char); override; + procedure Write(const Value: TUnicodeCharArray); override; + procedure Write(Value: Double); override; + procedure Write(Value: Integer); override; + procedure Write(Value: Int64); override; + procedure Write(Value: TObject); override; + procedure Write(Value: Single); override; + procedure Write(const Value: string); override; + procedure Write(Value: Cardinal); override; + procedure Write(Value: UInt64); override; + procedure Write(const Format: string; Args: array of const); override; + procedure Write(const Value: TUnicodeCharArray; Index, Count: Integer); override; + procedure WriteLine; override; + procedure WriteLine(Value: Boolean); override; + procedure WriteLine(Value: Char); override; + procedure WriteLine(const Value: TUnicodeCharArray); override; + procedure WriteLine(Value: Double); override; + procedure WriteLine(Value: Integer); override; + procedure WriteLine(Value: Int64); override; + procedure WriteLine(Value: TObject); override; + procedure WriteLine(Value: Single); override; + procedure WriteLine(const Value: string); override; + procedure WriteLine(Value: Cardinal); override; + procedure WriteLine(Value: UInt64); override; + procedure WriteLine(const Format: string; Args: array of const); override; + procedure WriteLine(const Value: TUnicodeCharArray; Index, Count: Integer); override; + property AutoFlush: Boolean read FAutoFlush write FAutoFlush; + property NewLine: string read FNewLine write FNewLine; + property Encoding: TEncoding read FEncoding; + property BaseStream: TStream read FStream; + end; + + TStreamReader = class(TTextReader) + private type + TBufferedData = class(TUnicodeStringBuilder) + private + FStart: Integer; + FBufferSize: Integer; + function GetChars(AIndex: Integer): Char; inline; + public + constructor Create(ABufferSize: Integer); + procedure Clear; inline; + function Length: Integer; inline; + function PeekChar: Char; inline; + function MoveChar: Char; inline; + procedure MoveArray(DestinationIndex, Count: Integer; var Destination: TUnicodeCharArray); + procedure MoveString(Count, NewPos: Integer; var Destination: string); + procedure TrimBuffer; + property Chars[AIndex: Integer]: Char read GetChars; + end; + + private + FBufferSize: Integer; + FDetectBOM: Boolean; + FEncoding: TEncoding; + FOwnsStream: Boolean; + FSkipPreamble: Boolean; + FStream: TStream; + function DetectBOM(var Encoding: TEncoding; Buffer: TBytes): Integer; + function GetEndOfStream: Boolean; + function SkipPreamble(Encoding: TEncoding; Buffer: TBytes): Integer; + protected + FBufferedData: TBufferedData; + FNoDataInStream: Boolean; + procedure FillBuffer(var Encoding: TEncoding); + public + constructor Create(Stream: TStream); overload; + constructor Create(Stream: TStream; DetectBOM: Boolean); overload; + constructor Create(Stream: TStream; Encoding: TEncoding; + DetectBOM: Boolean = False; BufferSize: Integer = 4096); overload; + constructor Create(const Filename: string); overload; + constructor Create(const Filename: string; DetectBOM: Boolean); overload; + constructor Create(const Filename: string; Encoding: TEncoding; + DetectBOM: Boolean = False; BufferSize: Integer = 4096); overload; + destructor Destroy; override; + procedure Close; override; + procedure DiscardBufferedData; + procedure OwnStream; inline; + function Peek: Integer; override; + function Read: Integer; overload; override; + function Read(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; overload; override; + function ReadBlock(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; override; + function ReadLine: string; override; + function ReadToEnd: string; override; + procedure Rewind; override; + property BaseStream: TStream read FStream; + property CurrentEncoding: TEncoding read FEncoding write FEncoding; + property EndOfStream: Boolean read GetEndOfStream; + + property BufferedData: TBufferedData read FBufferedData; + property NoDataInStream: Boolean read FNoDataInStream; + end; + +implementation + +{ TTextWriter } + +procedure TTextWriter.Write(Value: Char; Count: Integer); +begin + Write(string.Create(Value, Count)); +end; + +{ TBinaryReader } + +procedure TBinaryReader.Close; +begin + if FOwnsStream then + FreeAndNil(FStream); +end; + +constructor TBinaryReader.Create(Stream: TStream; AEncoding: TEncoding; AOwnsStream: Boolean); +begin + inherited Create; + if Stream = nil then + raise EArgumentNilException.CreateRes(@SArgumentNil); + FStream := Stream; + if AEncoding = nil then + FEncoding := TEncoding.UTF8 + else + FEncoding := AEncoding; + FOwnsStream := AOwnsStream; + FTwoBytesPerChar := FEncoding is TUnicodeEncoding; + FMaxCharsSize := FEncoding.GetMaxByteCount($80); +end; + +constructor TBinaryReader.Create(const Filename: string; Encoding: TEncoding); +begin + Create(TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite), Encoding, True); +end; + +destructor TBinaryReader.Destroy; +begin + if not TEncoding.IsStandardEncoding(FEncoding) then + FEncoding.Free; + if FOwnsStream then + FStream.Free; + inherited; +end; + +function TBinaryReader.GetBaseStream: TStream; +begin + Result := FStream; +end; + +function TBinaryReader.InternalReadChar: Integer; +var + CharCount: Integer; + ByteCount: Integer; + Index: Integer; + Position: Int64; + CharByte: Byte; +begin + if FCharBytes = nil then + SetLength(FCharBytes, $80); + if FOneChar = nil then + SetLength(FOneChar, 1); + Index := 0; + Position := FStream.Position; + try + CharCount := 0; + if FTwoBytesPerChar then + ByteCount := 2 + else + ByteCount := 1; + while (CharCount = 0) and (Index < Length(FCharBytes)) do + begin + if FStream.Read(CharByte, SizeOf(CharByte)) = 0 then + ByteCount := 0; + FCharBytes[Index] := CharByte; + Inc(Index); + if ByteCount = 2 then + begin + if FStream.Read(CharByte, SizeOf(CharByte)) = 0 then + ByteCount := 1; + FCharBytes[Index] := CharByte; + Inc(Index); + end; + if ByteCount = 0 then + Exit(-1); + CharCount := FEncoding.GetChars(FCharBytes, 0, Index, FOneChar, 0); + end; + except + FStream.Position := Position; + raise; + end; + if CharCount > 0 then + Result := Integer(FOneChar[0]) + else + Result := -1; +end; + +function TBinaryReader.InternalReadChars(const Chars: TUnicodeCharArray; Index, Count: Integer): Integer; +var + BytesToRead, RemainingChars, CharCount: Integer; +begin + if FCharBytes = nil then + SetLength(FCharBytes, $80); + RemainingChars := Count; + while RemainingChars > 0 do + begin + BytesToRead := RemainingChars; + if FTwoBytesPerChar then + BytesToRead := BytesToRead shl 1; + if BytesToRead > Length(FCharBytes) then + BytesToRead := Length(FCharBytes); + BytesToRead := FStream.Read(FCharBytes[0], BytesToRead); + if BytesToRead = 0 then + Break; + CharCount := FEncoding.GetChars(FCharBytes, 0, BytesToRead, Chars, Index); + Dec(RemainingChars, CharCount); + Inc(Index, CharCount); + end; + Result := Count - RemainingChars; +end; + +function TBinaryReader.PeekChar: Integer; +var + Position: Int64; +begin + Position := FStream.Position; + try + Result := InternalReadChar; + finally + FStream.Position := Position; + end; +end; + +function TBinaryReader.Read(var Buffer: TUnicodeCharArray; Index, Count: Integer): Integer; +begin + if Index < 0 then + raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Index']); // do not localize + if Count < 0 then + raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Count']); // do not localize + if Length(Buffer) - Index < Count then + raise EArgumentOutOfRangeException.CreateRes(@sArgumentOutOfRange_OffLenInvalid); + Result := InternalReadChars(Buffer, Index, Count); +end; + +function TBinaryReader.Read: Integer; +begin + Result := InternalReadChar; +end; + +function TBinaryReader.Read(const Buffer: TBytes; Index, Count: Integer): Integer; +begin + if Index < 0 then + raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Index']); // do not localize + if Count < 0 then + raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Count']); // do not localize + if Length(Buffer) - Index < Count then + raise EArgumentOutOfRangeException.CreateRes(@sArgumentOutOfRange_OffLenInvalid); + Result := FStream.Read(Buffer[Index], Count); +end; + +function TBinaryReader.Read7BitEncodedInt: Integer; +var + Shift: Integer; + Value: Integer; +begin + Shift := 0; + Result := 0; + repeat + if Shift = 35 then + raise EStreamError.CreateRes(@SInvalid7BitEncodedInteger); + Value := ReadByte; + Result := Result or ((Value and $7F) shl Shift); + Inc(Shift, 7); + until Value and $80 = 0; +end; + +function TBinaryReader.ReadBoolean: Boolean; +begin + FStream.ReadBuffer(Result, SizeOf(Result)); +end; + +function TBinaryReader.ReadByte: Byte; +begin + FStream.ReadBuffer(Result, SizeOf(Result)); +end; + +function TBinaryReader.ReadBytes(Count: Integer): TBytes; +var + BytesRead: Integer; +begin + if Count < 0 then + raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Count']); // do not localize + SetLength(Result, Count); + BytesRead := FStream.Read(Result[0], Count); + if BytesRead <> Count then + SetLength(Result, BytesRead); +end; + +function TBinaryReader.ReadCardinal: Cardinal; +begin + FStream.ReadBuffer(Result, SizeOf(Result)); +end; + +function TBinaryReader.ReadChar: Char; +var + Value: Integer; +begin + Value := Read; + if Value = -1 then + raise EStreamError.CreateRes(@SReadPastEndOfStream); + Result := Char(Value); +end; + +function TBinaryReader.ReadChars(Count: Integer): TUnicodeCharArray; +var + CharsRead: Integer; +begin + if Count < 0 then + raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Count']); // do not localize + SetLength(Result, Count); + CharsRead := InternalReadChars(Result, 0, Count); + if CharsRead <> Count then + SetLength(Result, CharsRead); +end; + +function TBinaryReader.ReadDouble: Double; +begin + FStream.ReadBuffer(Result, SizeOf(Result)); +end; + +function TBinaryReader.ReadInt64: Int64; +begin + FStream.ReadBuffer(Result, SizeOf(Result)); +end; + +function TBinaryReader.ReadInteger: Integer; +begin + FStream.ReadBuffer(Result, SizeOf(Result)); +end; + +function TBinaryReader.ReadInt32: Integer; +begin + Result := ReadInteger; +end; + +function TBinaryReader.ReadShortInt: ShortInt; +begin + FStream.ReadBuffer(Result, SizeOf(Result)); +end; + +function TBinaryReader.ReadSByte: ShortInt; +begin + Result := ReadShortInt; +end; + +function TBinaryReader.ReadSmallInt: SmallInt; +begin + FStream.ReadBuffer(Result, SizeOf(Result)); +end; + +function TBinaryReader.ReadInt16: SmallInt; +begin + Result := ReadSmallInt; +end; + +function TBinaryReader.ReadSingle: Single; +begin + FStream.ReadBuffer(Result, SizeOf(Result)); +end; + +function TBinaryReader.ReadString: string; +var + Bytes: TBytes; + ByteCount, BytesRead: Integer; +begin + ByteCount := Read7BitEncodedInt; + if ByteCount < 0 then + raise EStreamError.CreateRes(@SInvalidStringLength); + if ByteCount > 0 then + begin + SetLength(Bytes, ByteCount); + BytesRead := FStream.Read(Bytes[0], ByteCount); + if BytesRead <> ByteCount then + raise EStreamError.CreateRes(@SReadPastEndOfStream); + Result := FEncoding.GetString(Bytes); + end else + Result := ''; +end; + +function TBinaryReader.ReadUInt32: Cardinal; +begin + Result := ReadCardinal; +end; + +function TBinaryReader.ReadUInt64: UInt64; +begin + FStream.ReadBuffer(Result, SizeOf(Result)); +end; + +function TBinaryReader.ReadWord: Word; +begin + FStream.ReadBuffer(Result, SizeOf(Result)); +end; + +function TBinaryReader.ReadUInt16: Word; +begin + Result := ReadWord; +end; + +{ TNullStream } + +type + TNullStream = class(TStream) + public + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + function Seek(Offset: Longint; Origin: Word): Longint; overload; override; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; override; + end; + +function TNullStream.Read(var Buffer; Count: Longint): Longint; +begin + Result := 0; +end; + +function TNullStream.Write(const Buffer; Count: Longint): Longint; +begin + Result := 0; +end; + +function TNullStream.Seek(Offset: Longint; Origin: Word): Longint; +begin + Result := 0; +end; + +function TNullStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; +begin + Result := 0; +end; + +{ TBinaryWriter } + +constructor TBinaryWriter.Create(Stream: TStream; Encoding: TEncoding); +begin + Create(Stream, Encoding, False); +end; + +constructor TBinaryWriter.Create(Stream: TStream); +begin + Create(Stream, nil, False); +end; + +constructor TBinaryWriter.Create(Stream: TStream; Encoding: TEncoding; AOwnsStream: Boolean); +begin + inherited Create; + if Stream = nil then + raise EArgumentNilException.CreateRes(@SArgumentNil); + FStream := Stream; + if Encoding = nil then + FEncoding := TEncoding.UTF8 + else + FEncoding := Encoding; + FOwnsStream := AOwnsStream; +end; + +procedure TBinaryWriter.Close; +begin + if FOwnsStream then + FreeAndNil(FStream); +end; + +constructor TBinaryWriter.Create(const Filename: string; Append: Boolean; Encoding: TEncoding); +begin + if not Append or not FileExists(Filename) then + FStream := TFileStream.Create(Filename, fmCreate) + else + begin + FStream := TFileStream.Create(Filename, fmOpenWrite); + FStream.Seek(0, soEnd); + end; + Create(FStream, Encoding, True); +end; + +constructor TBinaryWriter.Create(const Filename: string; Append: Boolean); +begin + Create(Filename, Append, nil); +end; + +constructor TBinaryWriter.Create; +begin + Create(TNullStream.Create, nil, True); +end; + +destructor TBinaryWriter.Destroy; +begin + if not TEncoding.IsStandardEncoding(FEncoding) then + FEncoding.Free; + if FOwnsStream then + FStream.Free; + inherited; +end; + +class destructor TBinaryWriter.Destroy; +begin + FNull.Free; +end; + +class function TBinaryWriter.GetNull: TBinaryWriter; +var + Writer: TBinaryWriter; +begin + if FNull = nil then + begin + Writer := TBinaryWriter.Create; + Writer := AtomicCmpExchange(Pointer(FNull), Pointer(Writer), nil); + Writer.Free; + end; + Result := FNull; +end; + +function TBinaryWriter.GetBaseStream: TStream; +begin + Result := FStream; +end; + +function TBinaryWriter.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; +begin + Result := FStream.Seek(Offset, Origin); +end; + +procedure TBinaryWriter.Write(Value: Char); +var + Bytes: TBytes; +begin + if Value.IsSurrogate then + raise EArgumentException.CreateRes(@SNoSurrogates); + Bytes := FEncoding.GetBytes(Value); + FStream.WriteBuffer(Bytes, Length(Bytes)); +end; + +procedure TBinaryWriter.Write(Value: Byte); +begin + FStream.Write(Value, SizeOf(Value)); +end; + +procedure TBinaryWriter.Write(Value: Boolean); +begin + FStream.Write(Value, SizeOf(Value)); +end; + +procedure TBinaryWriter.Write(const Value: TUnicodeCharArray); +var + Bytes: TBytes; +begin + Bytes := FEncoding.GetBytes(Value); + FStream.WriteBuffer(Bytes, Length(Bytes)); +end; + +procedure TBinaryWriter.Write(const Value: string); +var + Bytes: TBytes; +begin + Bytes := FEncoding.GetBytes(Value); + Write7BitEncodedInt(Length(Bytes)); + FStream.WriteBuffer(Bytes, Length(Bytes)); +end; + +procedure TBinaryWriter.Write(Value: Single); +begin + FStream.Write(Value, SizeOf(Value)); +end; + +procedure TBinaryWriter.Write(Value: Int64); +begin + FStream.Write(Value, SizeOf(Value)); +end; + +procedure TBinaryWriter.Write(const Value: TBytes; Index, Count: Integer); +begin + if Index < 0 then + raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Index']); // do not localize + if Count < 0 then + raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_NeedNonNegValue, ['Count']); // do not localize + if Length(Value) - Index < Count then + raise EArgumentOutOfRangeException.CreateRes(@sArgumentOutOfRange_OffLenInvalid); + FStream.WriteBuffer(Value, Index, Count); +end; + +procedure TBinaryWriter.Write(const Value: TBytes); +begin + FStream.WriteBuffer(Value, Length(Value)); +end; + +procedure TBinaryWriter.Write(const Value: TUnicodeCharArray; Index, Count: Integer); +var + Bytes: TBytes; +begin + Bytes := FEncoding.GetBytes(Value, Index, Count); + FStream.WriteBuffer(Bytes, Length(Bytes)); +end; + +procedure TBinaryWriter.Write(Value: UInt64); +begin + FStream.Write(Value, SizeOf(Value)); +end; + +procedure TBinaryWriter.Write(Value: Double); +begin + FStream.Write(Value, SizeOf(Value)); +end; + +procedure TBinaryWriter.Write(Value: SmallInt); +begin + FStream.Write(Value, SizeOf(Value)); +end; + +procedure TBinaryWriter.Write(Value: Integer); +begin + FStream.Write(Value, SizeOf(Value)); +end; + +procedure TBinaryWriter.Write(Value: Cardinal); +begin + FStream.Write(Value, SizeOf(Value)); +end; + +procedure TBinaryWriter.Write(Value: Word); +begin + FStream.Write(Value, SizeOf(Value)); +end; + +procedure TBinaryWriter.Write(Value: ShortInt); +begin + FStream.Write(Value, SizeOf(Value)); +end; + +procedure TBinaryWriter.Write7BitEncodedInt(Value: Integer); +begin + repeat + if Value > $7f then + Write(Byte((Value and $7f) or $80)) + else + Write(Byte(Value)); + Value := Value shr 7; + until Value = 0; +end; + +{ TStringReader } + +procedure TStringReader.Close; +begin + FData := ''; + FIndex := -1; +end; + +constructor TStringReader.Create(S: string); +begin + inherited Create; + + FIndex := Low(S); + FData := S; +end; + +function TStringReader.Peek: Integer; +begin + Result := -1; + if (FIndex >= Low(FData)) and (FIndex <= High(FData)) then + Result := Integer(FData[FIndex]); +end; + +function TStringReader.Read: Integer; +begin + Result := -1; + if (FIndex >= Low(FData)) and (FIndex <= High(FData)) then + begin + Result := Integer(FData[FIndex]); + Inc(FIndex); + if FIndex > High(FData) then + FIndex := -1; + end; +end; + +function TStringReader.Read(var Buffer: TUnicodeCharArray; Index, + Count: Integer): Integer; +begin + Result := -1; + + if FIndex = -1 then + Exit; + + if Length(Buffer) < Index + Count then + raise EArgumentOutOfRangeException.CreateRes(@SInsufficientReadBuffer); + + if Count > FData.Length - FIndex + Low(FData) then + Count := FData.Length - FIndex + Low(FData); + Result := Count; + + FData.CopyTo(FIndex-Low(FData), Buffer, Index, Count); + + Inc(FIndex, Count); + if FIndex > High(FData) then + FIndex := -1; +end; + +function TStringReader.ReadBlock(var Buffer: TUnicodeCharArray; Index, + Count: Integer): Integer; +begin + Result := Read(Buffer, Index, Count); +end; + +function TStringReader.ReadLine: string; +var + StartIndex: Integer; + EndIndex: Integer; +begin + Result := ''; + if FIndex = -1 then + Exit; + + StartIndex := FIndex; + EndIndex := FIndex; + + while True do + begin + if EndIndex > High(FData) then + begin + FIndex := EndIndex; + Break; + end; + if FData[EndIndex] = #10 then + begin + FIndex := EndIndex + 1; + Break; + end + else + if (FData[EndIndex] = #13) and (EndIndex + 1 <= High(FData)) and (FData[EndIndex + 1] = #10) then + begin + FIndex := EndIndex + 2; + Break; + end + else + if FData[EndIndex] = #13 then + begin + FIndex := EndIndex + 1; + Break; + end; + Inc(EndIndex); + end; + + Result := FData.SubString(StartIndex-Low(FData), (EndIndex - StartIndex)); + + if FIndex > High(FData) then + FIndex := -1; +end; + +function TStringReader.ReadToEnd: string; +begin + Result := ''; + if FIndex = -1 then + Exit; + Result := FData.SubString(FIndex-Low(FData)); + FIndex := -1; +end; + +procedure TStringReader.Rewind; +begin + FIndex := Low(FData); +end; + +{ TStringWriter } + +procedure TStringWriter.Close; +begin +end; + +constructor TStringWriter.Create; +begin + inherited Create; + + FOwnsBuilder := True; + FBuilder := TUnicodeStringBuilder.Create; +end; + +constructor TStringWriter.Create(Builder: TUnicodeStringBuilder); +begin + inherited Create; + + if not Assigned(Builder) then + raise EArgumentException.CreateResFmt(@SParamIsNil, ['Builder']); // DO NOT LOCALIZE + + FOwnsBuilder := False; + FBuilder := Builder; +end; + +destructor TStringWriter.Destroy; +begin + if FOwnsBuilder then + begin + FBuilder.Free; + FBuilder := nil; + end; + inherited; +end; + +procedure TStringWriter.Flush; +begin + +end; + +function TStringWriter.ToString: string; +begin + Result := FBuilder.ToString; +end; + +procedure TStringWriter.Write(Value: Cardinal); +begin + FBuilder.Append(Value); +end; + +procedure TStringWriter.Write(Value: Boolean); +begin + FBuilder.Append(Value); +end; + +procedure TStringWriter.Write(Value: Char); +begin + FBuilder.Append(Value); +end; + +procedure TStringWriter.Write(Value: Char; Count: Integer); +begin + FBuilder.Append(Value, Count); +end; + +procedure TStringWriter.Write(const Value: TUnicodeCharArray; Index, Count: Integer); +begin + FBuilder.Append(Value, Index, Count); +end; + +procedure TStringWriter.Write(const Format: string; Args: array of const); +begin + FBuilder.AppendFormat(Format, Args); +end; + +procedure TStringWriter.Write(Value: UInt64); +begin + FBuilder.Append(Value); +end; + +procedure TStringWriter.Write(Value: TObject); +begin + FBuilder.Append(Value); +end; + +procedure TStringWriter.Write(Value: Single); +begin + FBuilder.Append(Value); +end; + +procedure TStringWriter.Write(const Value: string); +begin + FBuilder.Append(Value); +end; + +procedure TStringWriter.Write(Value: Int64); +begin + FBuilder.Append(Value); +end; + +procedure TStringWriter.Write(const Value: TUnicodeCharArray); +begin + FBuilder.Append(Value); +end; + +procedure TStringWriter.Write(Value: Double); +begin + FBuilder.Append(Value); +end; + +procedure TStringWriter.Write(Value: Integer); +begin + FBuilder.Append(Value); +end; + +procedure TStringWriter.WriteLine(const Value: TUnicodeCharArray); +begin + FBuilder.Append(Value).AppendLine; +end; + +procedure TStringWriter.WriteLine(Value: Double); +begin + FBuilder.Append(Value).AppendLine; +end; + +procedure TStringWriter.WriteLine(Value: Integer); +begin + FBuilder.Append(Value).AppendLine; +end; + +procedure TStringWriter.WriteLine; +begin + FBuilder.AppendLine; +end; + +procedure TStringWriter.WriteLine(Value: Boolean); +begin + FBuilder.Append(Value).AppendLine; +end; + +procedure TStringWriter.WriteLine(Value: Char); +begin + FBuilder.Append(Value).AppendLine; +end; + +procedure TStringWriter.WriteLine(Value: Int64); +begin + FBuilder.Append(Value).AppendLine; +end; + +procedure TStringWriter.WriteLine(Value: UInt64); +begin + FBuilder.Append(Value).AppendLine; +end; + +procedure TStringWriter.WriteLine(const Format: string; Args: array of const); +begin + FBuilder.AppendFormat(Format, Args).AppendLine; +end; + +procedure TStringWriter.WriteLine(const Value: TUnicodeCharArray; Index, Count: Integer); +begin + FBuilder.Append(Value, Index, Count).AppendLine; +end; + +procedure TStringWriter.WriteLine(Value: Cardinal); +begin + FBuilder.Append(Value).AppendLine; +end; + +procedure TStringWriter.WriteLine(Value: TObject); +begin + FBuilder.Append(Value).AppendLine; +end; + +procedure TStringWriter.WriteLine(Value: Single); +begin + FBuilder.Append(Value).AppendLine; +end; + +procedure TStringWriter.WriteLine(const Value: string); +begin + FBuilder.Append(Value).AppendLine; +end; + +{ TStreamWriter } + +procedure TStreamWriter.Close; +begin + Flush; + if FOwnsStream then + FreeAndNil(FStream); +end; + +constructor TStreamWriter.Create(Stream: TStream); +begin + inherited Create; + FOwnsStream := False; + FStream := Stream; + FEncoding := TEncoding.UTF8; + SetLength(FBuffer, 1024); + FBufferIndex := 0; + FNewLine := sLineBreak; + FAutoFlush := True; +end; + +constructor TStreamWriter.Create(Stream: TStream; Encoding: TEncoding; BufferSize: Integer); +begin + inherited Create; + FOwnsStream := False; + FStream := Stream; + FEncoding := Encoding; + if BufferSize >= 128 then + SetLength(FBuffer, BufferSize) + else + SetLength(FBuffer, 128); + FBufferIndex := 0; + FNewLine := sLineBreak; + FAutoFlush := True; + if Stream.Position = 0 then + WriteBytes(FEncoding.GetPreamble); +end; + +constructor TStreamWriter.Create(const Filename: string; Append: Boolean); +begin + if not Append or not FileExists(Filename) then + FStream := TFileStream.Create(Filename, fmCreate) + else + begin + FStream := TFileStream.Create(Filename, fmOpenWrite); + FStream.Seek(0, soEnd); + end; + Create(FStream); + FOwnsStream := True; +end; + +constructor TStreamWriter.Create(const Filename: string; Append: Boolean; + Encoding: TEncoding; BufferSize: Integer); +begin + if not Append or not FileExists(Filename) then + FStream := TFileStream.Create(Filename, fmCreate) + else + begin + FStream := TFileStream.Create(Filename, fmOpenWrite); + FStream.Seek(0, soEnd); + end; + Create(FStream, Encoding, BufferSize); + FOwnsStream := True; +end; + +destructor TStreamWriter.Destroy; +begin + Close; + SetLength(FBuffer, 0); + inherited; +end; + +procedure TStreamWriter.Flush; +begin + if FBufferIndex = 0 then + Exit; + if FStream = nil then + Exit; + + try + FStream.WriteBuffer(FBuffer, 0, FBufferIndex); + finally + FBufferIndex := 0; + end; +end; + +procedure TStreamWriter.OwnStream; +begin + FOwnsStream := True; +end; + +procedure TStreamWriter.Write(Value: Cardinal); +begin + WriteBytes(FEncoding.GetBytes(UIntToStr(Value))); +end; + +procedure TStreamWriter.Write(const Value: string); +begin + WriteBytes(FEncoding.GetBytes(Value)); +end; + +procedure TStreamWriter.Write(Value: UInt64); +begin + WriteBytes(FEncoding.GetBytes(UIntToStr(Value))); +end; + +procedure TStreamWriter.Write(const Value: TUnicodeCharArray; Index, Count: Integer); +var + Bytes: TBytes; +begin + SetLength(Bytes, Count * 4); + SetLength(Bytes, FEncoding.GetBytes(Value, Index, Count, Bytes, 0)); + WriteBytes(Bytes); +end; + +procedure TStreamWriter.WriteBytes(Bytes: TBytes); +var + ByteIndex: Integer; + WriteLen: Integer; +begin + ByteIndex := 0; + + while ByteIndex < Length(Bytes) do + begin + WriteLen := Length(Bytes) - ByteIndex; + if WriteLen > Length(FBuffer) - FBufferIndex then + WriteLen := Length(FBuffer) - FBufferIndex; + + Move(Bytes[ByteIndex], FBuffer[FBufferIndex], WriteLen); + + Inc(FBufferIndex, WriteLen); + Inc(ByteIndex, WriteLen); + + if FBufferIndex >= Length(FBuffer) then + Flush; + end; + + if FAutoFlush then + Flush; +end; + +procedure TStreamWriter.Write(const Format: string; Args: array of const); +begin + WriteBytes(FEncoding.GetBytes(SysUtils.Format(Format, Args))); +end; + +procedure TStreamWriter.Write(Value: Single); +begin + WriteBytes(FEncoding.GetBytes(FloatToStr(Value))); +end; + +procedure TStreamWriter.Write(const Value: TUnicodeCharArray); +begin + WriteBytes(FEncoding.GetBytes(Value)); +end; + +procedure TStreamWriter.Write(Value: Double); +begin + WriteBytes(FEncoding.GetBytes(FloatToStr(Value))); +end; + +procedure TStreamWriter.Write(Value: Integer); +begin + WriteBytes(FEncoding.GetBytes(IntToStr(Value))); +end; + +procedure TStreamWriter.Write(Value: Char); +begin + WriteBytes(FEncoding.GetBytes(Value)); +end; + +procedure TStreamWriter.Write(Value: TObject); +begin + WriteBytes(FEncoding.GetBytes(Value.ToString)); +end; + +procedure TStreamWriter.Write(Value: Int64); +begin + WriteBytes(FEncoding.GetBytes(IntToStr(Value))); +end; + +procedure TStreamWriter.Write(Value: Boolean); +begin + WriteBytes(FEncoding.GetBytes(BoolToStr(Value, True))); +end; + +procedure TStreamWriter.WriteLine(const Value: TUnicodeCharArray); +begin + WriteBytes(FEncoding.GetBytes(Value)); + WriteBytes(FEncoding.GetBytes(FNewLine)); +end; + +procedure TStreamWriter.WriteLine(Value: Double); +begin + WriteBytes(FEncoding.GetBytes(FloatToStr(Value) + FNewLine)); +end; + +procedure TStreamWriter.WriteLine(Value: Integer); +begin + WriteBytes(FEncoding.GetBytes(IntToStr(Value) + FNewLine)); +end; + +procedure TStreamWriter.WriteLine; +begin + WriteBytes(FEncoding.GetBytes(FNewLine)); +end; + +procedure TStreamWriter.WriteLine(Value: Boolean); +begin + WriteBytes(FEncoding.GetBytes(BoolToStr(Value, True) + FNewLine)); +end; + +procedure TStreamWriter.WriteLine(Value: Char); +begin + WriteBytes(FEncoding.GetBytes(Value)); + WriteBytes(FEncoding.GetBytes(FNewLine)); +end; + +procedure TStreamWriter.WriteLine(Value: Int64); +begin + WriteBytes(FEncoding.GetBytes(IntToStr(Value) + FNewLine)); +end; + +procedure TStreamWriter.WriteLine(Value: UInt64); +begin + WriteBytes(FEncoding.GetBytes(UIntToStr(Value) + FNewLine)); +end; + +procedure TStreamWriter.WriteLine(const Format: string; Args: array of const); +begin + WriteBytes(FEncoding.GetBytes(SysUtils.Format(Format, Args) + FNewLine)); +end; + +procedure TStreamWriter.WriteLine(const Value: TUnicodeCharArray; Index, Count: Integer); +var + Bytes: TBytes; +begin + SetLength(Bytes, Count * 4); + SetLength(Bytes, FEncoding.GetBytes(Value, Index, Count, Bytes, 0)); + WriteBytes(Bytes); + WriteBytes(FEncoding.GetBytes(FNewLine)); +end; + +procedure TStreamWriter.WriteLine(Value: Cardinal); +begin + WriteBytes(FEncoding.GetBytes(UIntToStr(Value) + FNewLine)); +end; + +procedure TStreamWriter.WriteLine(Value: TObject); +begin + WriteBytes(FEncoding.GetBytes(Value.ToString + FNewLine)); +end; + +procedure TStreamWriter.WriteLine(Value: Single); +begin + WriteBytes(FEncoding.GetBytes(FloatToStr(Value) + FNewLine)); +end; + +procedure TStreamWriter.WriteLine(const Value: string); +begin + WriteBytes(FEncoding.GetBytes(Value + FNewLine)); +end; + +{ TStreamReader.TBufferedData } + +constructor TStreamReader.TBufferedData.Create(ABufferSize: Integer); +begin + inherited Create; + FBufferSize := ABufferSize; +end; + +procedure TStreamReader.TBufferedData.Clear; +begin + inherited Length := 0; + FStart := 0; +end; + +function TStreamReader.TBufferedData.GetChars(AIndex: Integer): Char; +begin + Result := FData[FStart + 1 + AIndex]; +end; + +function TStreamReader.TBufferedData.Length: Integer; +begin + Result := FLength - FStart; +end; + +function TStreamReader.TBufferedData.PeekChar: Char; +begin + Result := FData[FStart + 1]; +end; + +function TStreamReader.TBufferedData.MoveChar: Char; +begin + Result := FData[FStart + 1]; + Inc(FStart); +end; + +procedure TStreamReader.TBufferedData.MoveArray(DestinationIndex, Count: Integer; + var Destination: TUnicodeCharArray); +begin + CopyTo(FStart, Destination, DestinationIndex, Count); + Inc(FStart, Count); +end; + +procedure TStreamReader.TBufferedData.MoveString(Count, NewPos: Integer; + var Destination: string); +begin + if (FStart = 0) and (Count = inherited Length) then + Destination := ToString + else + Destination := ToString(FStart, Count); + Inc(FStart, NewPos); +end; + +procedure TStreamReader.TBufferedData.TrimBuffer; +begin + if inherited Length > FBufferSize then + begin + Remove(0, FStart); + FStart := 0; + end; +end; + +{ TStreamReader } + +constructor TStreamReader.Create(Stream: TStream); +begin + Create(Stream, TEncoding.UTF8, True); +end; + +constructor TStreamReader.Create(Stream: TStream; DetectBOM: Boolean); +begin + Create(Stream, TEncoding.UTF8, DetectBOM); +end; + +constructor TStreamReader.Create(Stream: TStream; Encoding: TEncoding; + DetectBOM: Boolean; BufferSize: Integer); +begin + inherited Create; + + if not Assigned(Stream) then + raise EArgumentException.CreateResFmt(@SParamIsNil, ['Stream']); // DO NOT LOCALIZE + if not Assigned(Encoding) then + raise EArgumentException.CreateResFmt(@SParamIsNil, ['Encoding']); // DO NOT LOCALIZE + + FEncoding := Encoding; + FBufferSize := BufferSize; + if FBufferSize < 128 then + FBufferSize := 128; + FBufferedData := TBufferedData.Create(FBufferSize); + FNoDataInStream := False; + FStream := Stream; + FOwnsStream := False; + FDetectBOM := DetectBOM; + FSkipPreamble := not FDetectBOM; +end; + +constructor TStreamReader.Create(const Filename: string; Encoding: TEncoding; + DetectBOM: Boolean; BufferSize: Integer); +begin + Create(TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite), Encoding, DetectBOM, BufferSize); + FOwnsStream := True; +end; + +constructor TStreamReader.Create(const Filename: string; DetectBOM: Boolean); +begin + Create(TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite), DetectBOM); + FOwnsStream := True; +end; + +constructor TStreamReader.Create(const Filename: string); +begin + Create(TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite)); + FOwnsStream := True; +end; + +destructor TStreamReader.Destroy; +begin + Close; + inherited; +end; + +procedure TStreamReader.Close; +begin + if FOwnsStream then + FreeAndNil(FStream); + FreeAndNil(FBufferedData); +end; + +procedure TStreamReader.DiscardBufferedData; +begin + if FBufferedData <> nil then + begin + FBufferedData.Clear; + FNoDataInStream := False; + end; +end; + +function TStreamReader.DetectBOM(var Encoding: TEncoding; Buffer: TBytes): Integer; +var + LEncoding: TEncoding; +begin + // try to automatically detect the buffer encoding + LEncoding := nil; + Result := TEncoding.GetBufferEncoding(Buffer, LEncoding, nil); + if LEncoding <> nil then + Encoding := LEncoding + else if Encoding = nil then + Encoding := TEncoding.Default; + + FDetectBOM := False; +end; + +procedure TStreamReader.FillBuffer(var Encoding: TEncoding); +const + BufferPadding = 4; +var + LString: string; + LBuffer: TBytes; + BytesRead: Integer; + StartIndex: Integer; + ByteCount: Integer; + ByteBufLen: Integer; + ExtraByteCount: Integer; + + procedure AdjustEndOfBuffer(const ABuffer: TBytes; Offset: Integer); + var + Pos, Size: Integer; + Rewind: Integer; + begin + Dec(Offset); + for Pos := Offset downto 0 do + begin + for Size := Offset - Pos + 1 downto 1 do + begin + if Encoding.GetCharCount(ABuffer, Pos, Size) > 0 then + begin + Rewind := Offset - (Pos + Size - 1); + if Rewind <> 0 then + begin + FStream.Position := FStream.Position - Rewind; + BytesRead := BytesRead - Rewind; + end; + Exit; + end; + end; + end; + end; + +begin + SetLength(LBuffer, FBufferSize + BufferPadding); + + // Read data from stream + BytesRead := FStream.Read(LBuffer[0], FBufferSize); + FNoDataInStream := BytesRead = 0; + + // Check for byte order mark and calc start index for character data + if FDetectBOM then + StartIndex := DetectBOM(Encoding, LBuffer) + else if FSkipPreamble then + StartIndex := SkipPreamble(Encoding, LBuffer) + else + StartIndex := 0; + + // Adjust the end of the buffer to be sure we have a valid encoding + if not FNoDataInStream then + AdjustEndOfBuffer(LBuffer, BytesRead); + + // Convert to string and calc byte count for the string + ByteBufLen := BytesRead - StartIndex; + LString := FEncoding.GetString(LBuffer, StartIndex, ByteBufLen); + ByteCount := FEncoding.GetByteCount(LString); + + // If byte count <> number of bytes read from the stream + // the buffer boundary is mid-character and additional bytes + // need to be read from the stream to complete the character + ExtraByteCount := 0; + while (ByteCount <> ByteBufLen) and (ExtraByteCount < FEncoding.GetMaxByteCount(1)) do + begin + // Expand buffer if padding is used + if (StartIndex + ByteBufLen) = Length(LBuffer) then + SetLength(LBuffer, Length(LBuffer) + BufferPadding); + + // Read one more byte from the stream into the + // buffer padding and convert to string again + BytesRead := FStream.Read(LBuffer[StartIndex + ByteBufLen], 1); + if BytesRead = 0 then + // End of stream, append what's been read and discard remaining bytes + Break; + + Inc(ExtraByteCount); + + Inc(ByteBufLen); + LString := FEncoding.GetString(LBuffer, StartIndex, ByteBufLen); + ByteCount := FEncoding.GetByteCount(LString); + end; + + // Add string to character data buffer + FBufferedData.Append(LString); +end; + +function TStreamReader.GetEndOfStream: Boolean; +begin + if not FNoDataInStream and (FBufferedData <> nil) and (FBufferedData.Length < 1) then + FillBuffer(FEncoding); + Result := FNoDataInStream and ((FBufferedData = nil) or (FBufferedData.Length = 0)); +end; + +procedure TStreamReader.OwnStream; +begin + FOwnsStream := True; +end; + +function TStreamReader.Peek: Integer; +begin + Result := -1; + if (FBufferedData <> nil) and (not EndOfStream) then + begin + if FBufferedData.Length < 1 then + FillBuffer(FEncoding); + Result := Integer(FBufferedData.PeekChar); + end; +end; + +function TStreamReader.Read(var Buffer: TUnicodeCharArray; Index, + Count: Integer): Integer; +begin + Result := -1; + if (FBufferedData <> nil) and (not EndOfStream) then + begin + while (FBufferedData.Length < Count) and (not EndOfStream) and (not FNoDataInStream) do + FillBuffer(FEncoding); + + if FBufferedData.Length > Count then + Result := Count + else + Result := FBufferedData.Length; + + FBufferedData.MoveArray(Index, Result, Buffer); + FBufferedData.TrimBuffer; + end; +end; + +function TStreamReader.ReadBlock(var Buffer: TUnicodeCharArray; Index, + Count: Integer): Integer; +begin + Result := Read(Buffer, Index, Count); +end; + +function TStreamReader.Read: Integer; +begin + Result := -1; + if (FBufferedData <> nil) and (not EndOfStream) then + begin + if FBufferedData.Length < 1 then + FillBuffer(FEncoding); + Result := Integer(FBufferedData.MoveChar); + end; +end; + +function TStreamReader.ReadLine: string; +var + NewLineIndex: Integer; + PostNewLineIndex: Integer; + LChar: Char; +begin + Result := ''; + if FBufferedData = nil then + Exit; + NewLineIndex := 0; + PostNewLineIndex := 0; + + while True do + begin + if (NewLineIndex + 2 > FBufferedData.Length) and (not FNoDataInStream) then + FillBuffer(FEncoding); + + if NewLineIndex >= FBufferedData.Length then + begin + if FNoDataInStream then + begin + PostNewLineIndex := NewLineIndex; + Break; + end + else + begin + FillBuffer(FEncoding); + if FBufferedData.Length = 0 then + Break; + end; + end; + LChar := FBufferedData.Chars[NewLineIndex]; + if LChar = #10 then + begin + PostNewLineIndex := NewLineIndex + 1; + Break; + end + else if LChar = #13 then + begin + if (NewLineIndex + 1 < FBufferedData.Length) and (FBufferedData.Chars[NewLineIndex + 1] = #10) then + PostNewLineIndex := NewLineIndex + 2 + else + PostNewLineIndex := NewLineIndex + 1; + Break; + end; + + Inc(NewLineIndex); + end; + + FBufferedData.MoveString(NewLineIndex, PostNewLineIndex, Result); + FBufferedData.TrimBuffer; +end; + +function TStreamReader.ReadToEnd: string; +begin + Result := ''; + if (FBufferedData <> nil) and (not EndOfStream) then + begin + repeat + FillBuffer(FEncoding); + until FNoDataInStream; + FBufferedData.MoveString(FBufferedData.Length, FBufferedData.Length, Result); + FBufferedData.Clear; + end; +end; + +function TStreamReader.SkipPreamble(Encoding: TEncoding; Buffer: TBytes): Integer; +var + I: Integer; + LPreamble: TBytes; + BOMPresent: Boolean; +begin + Result := 0; + LPreamble := Encoding.GetPreamble; + if (Length(LPreamble) > 0) then + begin + if Length(Buffer) >= Length(LPreamble) then + begin + BOMPresent := True; + for I := 0 to Length(LPreamble) - 1 do + if LPreamble[I] <> Buffer[I] then + begin + BOMPresent := False; + Break; + end; + if BOMPresent then + Result := Length(LPreamble); + end; + end; + FSkipPreamble := False; +end; + +procedure TStreamReader.Rewind; +begin + DiscardBufferedData; + FSkipPreamble := not FDetectBOM; + FStream.Position := 0; +end; + +end. diff --git a/DelphiToFPC/DTF.Types.pas b/DelphiToFPC/DTF.Types.pas index 2ac5027..c6a6b89 100644 --- a/DelphiToFPC/DTF.Types.pas +++ b/DelphiToFPC/DTF.Types.pas @@ -1,27 +1,27 @@ -unit DTF.Types; - -{$I zLib.inc} - -interface - -uses - Classes, - SysUtils; - -type - TProc = reference to procedure; - TProc = reference to procedure (Arg1: T); - TProc = reference to procedure (Arg1: T1; Arg2: T2); - TProc = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3); - TProc = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4); - - TFunc = reference to function: TResult; - TFunc = reference to function (Arg1: T): TResult; - TFunc = reference to function (Arg1: T1; Arg2: T2): TResult; - TFunc = reference to function (Arg1: T1; Arg2: T2; Arg3: T3): TResult; - TFunc = reference to function (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4): TResult; - -implementation - -end. - +unit DTF.Types; + +{$I zLib.inc} + +interface + +uses + Classes, + SysUtils; + +type + TProc = reference to procedure; + TProc = reference to procedure (Arg1: T); + TProc = reference to procedure (Arg1: T1; Arg2: T2); + TProc = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3); + TProc = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4); + + TFunc = reference to function: TResult; + TFunc = reference to function (Arg1: T): TResult; + TFunc = reference to function (Arg1: T1; Arg2: T2): TResult; + TFunc = reference to function (Arg1: T1; Arg2: T2; Arg3: T3): TResult; + TFunc = reference to function (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4): TResult; + +implementation + +end. + diff --git a/LICENSE b/LICENSE index 65c5ca8..b14ca0a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,165 +1,165 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/Net/BSD.kqueue.pas b/Net/BSD.kqueue.pas index 5489b2e..248f09b 100644 --- a/Net/BSD.kqueue.pas +++ b/Net/BSD.kqueue.pas @@ -1,125 +1,125 @@ -{******************************************************************************} -{ } -{ Delphi cross platform socket library } -{ } -{ Copyright (c) 2017 WiNDDRiVER(soulawing@gmail.com) } -{ } -{ Homepage: https://github.com/winddriver/Delphi-Cross-Socket } -{ } -{******************************************************************************} -unit BSD.kqueue; - -{$I zLib.inc} - -interface - -uses - {$IFDEF DELPHI} - Posix.Base, - Posix.Time - {$ELSE} - BaseUnix, - Unix - {$ENDIF} - ; - -const - EVFILT_READ = -1; - EVFILT_WRITE = -2; - EVFILT_AIO = -3; { attached to aio requests } - EVFILT_VNODE = -4; { attached to vnodes } - EVFILT_PROC = -5; { attached to struct proc } - EVFILT_SIGNAL = -6; { attached to struct proc } - EVFILT_TIMER = -7; { timers } - EVFILT_NETDEV = -8; { network devices } - EVFILT_FS = -9; { filesystem events } - - EVFILT_SYSCOUNT = 9; - - EV_ADD = $0001; { add event to kq } - EV_DELETE = $0002; { delete event from kq } - EV_ENABLE = $0004; { enable event } - EV_DISABLE = $0008; { disable event (not reported) } - -{ flags } - EV_ONESHOT = $0010; { only report one occurrence } - EV_CLEAR = $0020; { clear event state after reporting } - EV_RECEIPT = $0040; { force EV_ERROR on success, data=0 } - EV_DISPATCH = $0080; { disable event after reporting } - EV_SYSFLAGS = $F000; { reserved by system } - EV_FLAG1 = $2000; { filter-specific flag } - -{ returned values } - EV_EOF = $8000; { EOF detected } - EV_ERROR = $4000; { error, data contains errno } - -{ data/hint flags for EVFILT_READ|WRITE, shared with userspace } - NOTE_LOWAT = $0001; { low water mark } - -{ data/hint flags for EVFILT_VNODE, shared with userspace } - NOTE_DELETE = $0001; { vnode was removed } - NOTE_WRITE = $0002; { data contents changed } - NOTE_EXTEND = $0004; { size increased } - NOTE_ATTRIB = $0008; { attributes changed } - NOTE_LINK = $0010; { link count changed } - NOTE_RENAME = $0020; { vnode was renamed } - NOTE_REVOKE = $0040; { vnode access was revoked } - -{ data/hint flags for EVFILT_PROC, shared with userspace } - NOTE_EXIT = $80000000; { process exited } - NOTE_FORK = $40000000; { process forked } - NOTE_EXEC = $20000000; { process exec'd } - NOTE_PCTRLMASK = $f0000000; { mask for hint bits } - NOTE_PDATAMASK = $000fffff; { mask for pid } - -{ additional flags for EVFILT_PROC } - NOTE_TRACK = $00000001; { follow across forks } - NOTE_TRACKERR = $00000002; { could not track child } - NOTE_CHILD = $00000004; { am a child process } - -{ data/hint flags for EVFILT_NETDEV, shared with userspace } - NOTE_LINKUP = $0001; { link is up } - NOTE_LINKDOWN = $0002; { link is down } - NOTE_LINKINV = $0004; { link state is invalid } - -type - PKEvent = ^TKEvent; - TKEvent = record - Ident : UIntPtr; { identifier for this event } - Filter : SmallInt; { filter for event } - Flags : Word; - FFlags : Cardinal; - Data : IntPtr; - uData : Pointer; { opaque user data identifier } - end; - -{$IF DEFINED(FPC)} -{$LINKLIB c} -{$ENDIF} - -function kqueue: Integer; cdecl; - external {$IFDEF DELPHI}libc name _PU + 'kqueue'{$ENDIF}; - -function kevent(kq: Integer; ChangeList: PKEvent; nChanged: Integer; - EventList: PKevent; nEvents: Integer; Timeout: PTimeSpec): Integer; cdecl; - external {$IFDEF DELPHI}libc name _PU + 'kevent'{$ENDIF}; - -procedure EV_SET(kevp: PKEvent; const aIdent: UIntPtr; const aFilter: SmallInt; - const aFlags: Word; const aFFlags: Cardinal; const aData: IntPtr; - const auData: Pointer); inline; - -implementation - -procedure EV_SET(kevp: PKEvent; const aIdent: UIntPtr; const aFilter: SmallInt; - const aFlags: Word; const aFFlags: Cardinal; const aData: IntPtr; - const auData: Pointer); inline; -begin - kevp^.Ident := aIdent; - kevp^.Filter := aFilter; - kevp^.Flags := aFlags; - kevp^.FFlags := aFFlags; - kevp^.Data := aData; - kevp^.uData := auData; -end; - -end. +{******************************************************************************} +{ } +{ Delphi cross platform socket library } +{ } +{ Copyright (c) 2017 WiNDDRiVER(soulawing@gmail.com) } +{ } +{ Homepage: https://github.com/winddriver/Delphi-Cross-Socket } +{ } +{******************************************************************************} +unit BSD.kqueue; + +{$I zLib.inc} + +interface + +uses + {$IFDEF DELPHI} + Posix.Base, + Posix.Time + {$ELSE} + BaseUnix, + Unix + {$ENDIF} + ; + +const + EVFILT_READ = -1; + EVFILT_WRITE = -2; + EVFILT_AIO = -3; { attached to aio requests } + EVFILT_VNODE = -4; { attached to vnodes } + EVFILT_PROC = -5; { attached to struct proc } + EVFILT_SIGNAL = -6; { attached to struct proc } + EVFILT_TIMER = -7; { timers } + EVFILT_NETDEV = -8; { network devices } + EVFILT_FS = -9; { filesystem events } + + EVFILT_SYSCOUNT = 9; + + EV_ADD = $0001; { add event to kq } + EV_DELETE = $0002; { delete event from kq } + EV_ENABLE = $0004; { enable event } + EV_DISABLE = $0008; { disable event (not reported) } + +{ flags } + EV_ONESHOT = $0010; { only report one occurrence } + EV_CLEAR = $0020; { clear event state after reporting } + EV_RECEIPT = $0040; { force EV_ERROR on success, data=0 } + EV_DISPATCH = $0080; { disable event after reporting } + EV_SYSFLAGS = $F000; { reserved by system } + EV_FLAG1 = $2000; { filter-specific flag } + +{ returned values } + EV_EOF = $8000; { EOF detected } + EV_ERROR = $4000; { error, data contains errno } + +{ data/hint flags for EVFILT_READ|WRITE, shared with userspace } + NOTE_LOWAT = $0001; { low water mark } + +{ data/hint flags for EVFILT_VNODE, shared with userspace } + NOTE_DELETE = $0001; { vnode was removed } + NOTE_WRITE = $0002; { data contents changed } + NOTE_EXTEND = $0004; { size increased } + NOTE_ATTRIB = $0008; { attributes changed } + NOTE_LINK = $0010; { link count changed } + NOTE_RENAME = $0020; { vnode was renamed } + NOTE_REVOKE = $0040; { vnode access was revoked } + +{ data/hint flags for EVFILT_PROC, shared with userspace } + NOTE_EXIT = $80000000; { process exited } + NOTE_FORK = $40000000; { process forked } + NOTE_EXEC = $20000000; { process exec'd } + NOTE_PCTRLMASK = $f0000000; { mask for hint bits } + NOTE_PDATAMASK = $000fffff; { mask for pid } + +{ additional flags for EVFILT_PROC } + NOTE_TRACK = $00000001; { follow across forks } + NOTE_TRACKERR = $00000002; { could not track child } + NOTE_CHILD = $00000004; { am a child process } + +{ data/hint flags for EVFILT_NETDEV, shared with userspace } + NOTE_LINKUP = $0001; { link is up } + NOTE_LINKDOWN = $0002; { link is down } + NOTE_LINKINV = $0004; { link state is invalid } + +type + PKEvent = ^TKEvent; + TKEvent = record + Ident : UIntPtr; { identifier for this event } + Filter : SmallInt; { filter for event } + Flags : Word; + FFlags : Cardinal; + Data : IntPtr; + uData : Pointer; { opaque user data identifier } + end; + +{$IF DEFINED(FPC)} +{$LINKLIB c} +{$ENDIF} + +function kqueue: Integer; cdecl; + external {$IFDEF DELPHI}libc name _PU + 'kqueue'{$ENDIF}; + +function kevent(kq: Integer; ChangeList: PKEvent; nChanged: Integer; + EventList: PKevent; nEvents: Integer; Timeout: PTimeSpec): Integer; cdecl; + external {$IFDEF DELPHI}libc name _PU + 'kevent'{$ENDIF}; + +procedure EV_SET(kevp: PKEvent; const aIdent: UIntPtr; const aFilter: SmallInt; + const aFlags: Word; const aFFlags: Cardinal; const aData: IntPtr; + const auData: Pointer); inline; + +implementation + +procedure EV_SET(kevp: PKEvent; const aIdent: UIntPtr; const aFilter: SmallInt; + const aFlags: Word; const aFFlags: Cardinal; const aData: IntPtr; + const auData: Pointer); inline; +begin + kevp^.Ident := aIdent; + kevp^.Filter := aFilter; + kevp^.Flags := aFlags; + kevp^.FFlags := aFFlags; + kevp^.Data := aData; + kevp^.uData := auData; +end; + +end. diff --git a/Net/Demos/Delphi/HttpClient/HttpClient.dpr b/Net/Demos/Delphi/HttpClient/HttpClient.dpr index a746e3e..e382745 100644 --- a/Net/Demos/Delphi/HttpClient/HttpClient.dpr +++ b/Net/Demos/Delphi/HttpClient/HttpClient.dpr @@ -1,296 +1,296 @@ -program HttpClient; - -{$APPTYPE CONSOLE} - -{$I zLib.inc} - -uses - SysUtils, - Classes, - Net.CrossSocket.Base, - Net.CrossHttpClient, - Net.CrossHttpParams, - Net.CrossSslSocket.Types, - Net.CrossSslSocket.Base, - Net.CrossSslSocket.OpenSSL, - Net.OpenSSL, - Utils.IOUtils, - Utils.Utils; - -var - __HttpCli: ICrossHttpClient; - -procedure PrintHelp; -begin - Writeln('HttpClient '); -end; - -procedure PrintEntryList(const AEntryList: TArray; const AIndent: string); -var - LEntryItem: TEntryData; -begin - for LEntryItem in AEntryList do - begin - Writeln(AIndent + Format('%s: %s', [ - LEntryItem.Name, - LEntryItem.Value - ])); - end; -end; - -procedure PrintExtList(const AExtList: TArray; const AIndent: string); -var - LExtItem: TExtensionRawData; -begin - for LExtItem in AExtList do - begin - Writeln(AIndent + 'Name: ', LExtItem.Name); - Writeln(AIndent + 'NID: ', LExtItem.NID); - Writeln(AIndent + 'OID: ', LExtItem.OID); - Writeln(AIndent + 'Critical: ', BoolToStr(LExtItem.Critical, True)); - Writeln(AIndent + 'Value: ', TUtils.BytesToHex(LExtItem.Value)); - Writeln; - end; -end; - -procedure PrintGeneralName(const AName: TGeneralName; const AIndent: string); -begin - Writeln(AIndent + 'TypeID: ', AName.TypeID); - Writeln(AIndent + 'TypeName: ', AName.TypeName); - Writeln(AIndent + 'Value: ', AName.Value); -end; - -procedure PrintGeneralNameList(const ANameList: TArray; const AIndent: string); -var - LNameItem: TGeneralName; -begin - for LNameItem in ANameList do - begin - PrintGeneralName(LNameItem, AIndent); - Writeln; - end; -end; - -procedure PrintCrlDistPointList(const ACrlDistPointList: TArray; const AIndent: string); -var - LCrlDistPointItem: TCrlDistPoint; -begin - for LCrlDistPointItem in ACrlDistPointList do - begin - Writeln(AIndent + 'Reasons: ', LCrlDistPointItem.Reasons); - Writeln(AIndent + 'DpReasons: ', LCrlDistPointItem.DpReasons); - - Writeln(AIndent + 'DistPoint:'); - PrintGeneralNameList(LCrlDistPointItem.DistPoint, AIndent + ' '); - - Writeln(AIndent + 'CRLissuer:'); - PrintGeneralNameList(LCrlDistPointItem.CRLissuer, AIndent + ' '); - - Writeln; - end; -end; - -procedure PrintAuthorityInfoAccesses(const AAuthorityInfoAccesses: TArray; const AIndent: string); -var - LAuthorityInfoAccessItem: TAuthorityInfoAccess; -begin - for LAuthorityInfoAccessItem in AAuthorityInfoAccesses do - begin - Writeln(AIndent + 'Method: ', LAuthorityInfoAccessItem.Method); - Writeln(AIndent + 'MethodDesc: ', LAuthorityInfoAccessItem.MethodDesc); - - Writeln(AIndent + 'Location:'); - PrintGeneralName(LAuthorityInfoAccessItem.Location, AIndent + ' '); - - Writeln; - end; -end; - -procedure PrintSctList(const ASctList: TArray; const AIndent: string); -var - LSctItem: TSct; -begin - for LSctItem in ASctList do - begin - Writeln(AIndent + 'Version: ', LSctItem.Version); - Writeln(AIndent + 'Sct: ', TUtils.BytesToHex(LSctItem.Sct)); - Writeln(AIndent + 'LogID: ', TUtils.BytesToHex(LSctItem.LogID)); - Writeln(AIndent + 'Timestamp: ', LSctItem.Timestamp); - Writeln(AIndent + 'Ext: ', TUtils.BytesToHex(LSctItem.Ext)); - Writeln(AIndent + 'HashAlg: ', LSctItem.HashAlg); - Writeln(AIndent + 'SigAlg: ', LSctItem.SigAlg); - Writeln(AIndent + 'Sig: ', TUtils.BytesToHex(LSctItem.Sig)); - Writeln(AIndent + 'EntryType: ', LSctItem.EntryType); - Writeln(AIndent + 'Source: ', LSctItem.Source); - Writeln(AIndent + 'ValidationStatus: ', LSctItem.ValidationStatus); - - Writeln; - end; -end; - -procedure PrintBasicConstraints(const ABasicConstraints: TBasicConstraints; const AIndent: string); -begin - Writeln(AIndent + 'CA: ', ABasicConstraints.CA); - Writeln(AIndent + 'PathLen: ', ABasicConstraints.PathLen); -end; - -procedure PringExtKeyUsage(const AExtKeyUsage: TExtKeyUsage; const AIndent: string); -var - LExtKeyUsageItem: TExtKeyUsageItem; -begin - Writeln(AIndent + Format('Flags: 0x%x', [AExtKeyUsage.Flags])); - Writeln; - for LExtKeyUsageItem in AExtKeyUsage.List do - begin - Writeln(AIndent + 'NID: ', LExtKeyUsageItem.NID); - Writeln(AIndent + 'OID: ', LExtKeyUsageItem.OID); - Writeln(AIndent + 'Value: ', LExtKeyUsageItem.Value); - Writeln; - end; -end; - -procedure PrintSslInfo(const ASslInfo: TSslInfo); -begin - Writeln(Format('TLS Server Name: %s', [ - ASslInfo.HostName - ])); - - Writeln(Format('SSL/TLS Protocol: %s,%s,%d,%d', [ - ASslInfo.SslVersion, - ASslInfo.CurrentCipher, - ASslInfo.CertInfo.PubKeyBits, - ASslInfo.CurrentCipherBits - ])); - - Writeln(Format('Server Temp Key: %s %d bits', [ - ASslInfo.TmpKeyType, - ASslInfo.TmpKeyBits - ])); - - Writeln(Format('Public Key: %s %d bits', [ - ASslInfo.CertInfo.PubKeyType, - ASslInfo.CertInfo.PubKeyBits - ])); - - Writeln('Signature Algorithm: ', ASslInfo.CertInfo.SigAlg); - - Writeln(Format('CertVersion: %d', [ - ASslInfo.CertInfo.Version + 1 - ])); - - Writeln(Format('Serial Number: %s', [ - TUtils.BytesToHex(ASslInfo.CertInfo.SerialNumber) - ])); - - Writeln(Format('Expiration Date: %s - %s', [ - FormatDateTime('yyyy-mm-dd hh:nn:ss', ASslInfo.CertInfo.NotBefore), - FormatDateTime('yyyy-mm-dd hh:nn:ss', ASslInfo.CertInfo.NotAfter) - ])); - - Writeln; - - Writeln('Subject:'); - PrintEntryList(ASslInfo.CertInfo.Subject, ' '); - Writeln; - - Writeln('Issuer:'); - PrintEntryList(ASslInfo.CertInfo.Issuer, ' '); - Writeln; - - Writeln('SHA256Digest:'); - Writeln(Format(' Certificate: %s', [ - TUtils.BytesToHex(ASslInfo.CertInfo.SHA256Digest) - ])); - Writeln(Format(' Public Key: %s', [ - TUtils.BytesToHex(ASslInfo.CertInfo.PubKeySHA256Digest) - ])); - Writeln; - - Writeln('Extension:'); - Writeln(' AuthorityKeyID: ', TUtils.BytesToHex(ASslInfo.CertInfo.Extension.AuthorityKeyID)); - Writeln(' SubjectKeyID: ', TUtils.BytesToHex(ASslInfo.CertInfo.Extension.SubjectKeyID)); - Writeln(Format(' Key Usage: 0x%x', [ASslInfo.CertInfo.Extension.KeyUsage])); - - Writeln(' Alt Names:'); - PrintGeneralNameList(ASslInfo.CertInfo.Extension.AltNames, ' '); - - Writeln(' Crl Dist Points:'); - PrintCrlDistPointList(ASslInfo.CertInfo.Extension.CrlDistPoints, ' '); - - Writeln(' Authority Info Accesses:'); - PrintAuthorityInfoAccesses(ASslInfo.CertInfo.Extension.AuthorityInfoAccesses, ' '); - - Writeln(' Basic Constraints:'); - PrintBasicConstraints(ASslInfo.CertInfo.Extension.BasicConstraints, ' '); - Writeln; - - Writeln(' ExtKey Usage:'); - PringExtKeyUsage(ASslInfo.CertInfo.Extension.ExtKeyUsage, ' '); - - Writeln(' Sct List:'); - PrintSctList(ASslInfo.CertInfo.Extension.SctList, ' '); - - Writeln(' RawData:'); - PrintExtList(ASslInfo.CertInfo.Extension.RawData, ' '); - - Writeln('Cert PEM:' + sLineBreak, ASslInfo.CertInfo.PEM); - Writeln('Cert DER:' + sLineBreak, TUtils.BytesToHex(ASslInfo.CertInfo.DER)); - - Writeln; -end; - -procedure TestHttpCli; -var - LUrl: string; -begin - LUrl := ParamStr(1); - if (LUrl = '') then - begin - PrintHelp(); - Exit; - end; - - if (__HttpCli = nil) then - __HttpCli := TCrossHttpClient.Create; - -// __HttpCli.LocalPort := 1111; - __HttpCli.AutoUrlEncode := False; - __HttpCli.DoRequest('GET', LUrl, nil, nil, 0, - nil, - procedure(const ARequest: ICrossHttpClientRequest) - begin -// ARequest.Header['User-Agent'] := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'; - end, - procedure(const AResponse: ICrossHttpClientResponse) - var - LSslConnection: ICrossSslConnection; - LSslInfo: TSslInfo; - begin - if (AResponse <> nil) and (AResponse.Content <> nil) then - begin - LSslConnection := AResponse.Connection as ICrossSslConnection; - - if LSslConnection.Ssl and LSslConnection.GetSslInfo(LSslInfo) then - PrintSslInfo(LSslInfo); - - Writeln('HTTP GET success'); - Writeln(AResponse.StatusCode, ' ', AResponse.StatusText); - Writeln(AResponse.Header.Encode); - Writeln(TUtils.GetString(AResponse.Content)); - end else - Writeln('HTTP GET failed'); - end); -end; - -begin - // openssl пĬƲһ, ´޸ - // TSSLTools.LibSSL := 'libssl.so'; - // TSSLTools.LibCRYPTO := 'libcrypto.so'; - -// ReportMemoryLeaksOnShutdown := True; - - CrossSocketLogEnabled := False; - TestHttpCli; - Readln; -end. - +program HttpClient; + +{$APPTYPE CONSOLE} + +{$I zLib.inc} + +uses + SysUtils, + Classes, + Net.CrossSocket.Base, + Net.CrossHttpClient, + Net.CrossHttpParams, + Net.CrossSslSocket.Types, + Net.CrossSslSocket.Base, + Net.CrossSslSocket.OpenSSL, + Net.OpenSSL, + Utils.IOUtils, + Utils.Utils; + +var + __HttpCli: ICrossHttpClient; + +procedure PrintHelp; +begin + Writeln('HttpClient '); +end; + +procedure PrintEntryList(const AEntryList: TArray; const AIndent: string); +var + LEntryItem: TEntryData; +begin + for LEntryItem in AEntryList do + begin + Writeln(AIndent + Format('%s: %s', [ + LEntryItem.Name, + LEntryItem.Value + ])); + end; +end; + +procedure PrintExtList(const AExtList: TArray; const AIndent: string); +var + LExtItem: TExtensionRawData; +begin + for LExtItem in AExtList do + begin + Writeln(AIndent + 'Name: ', LExtItem.Name); + Writeln(AIndent + 'NID: ', LExtItem.NID); + Writeln(AIndent + 'OID: ', LExtItem.OID); + Writeln(AIndent + 'Critical: ', BoolToStr(LExtItem.Critical, True)); + Writeln(AIndent + 'Value: ', TUtils.BytesToHex(LExtItem.Value)); + Writeln; + end; +end; + +procedure PrintGeneralName(const AName: TGeneralName; const AIndent: string); +begin + Writeln(AIndent + 'TypeID: ', AName.TypeID); + Writeln(AIndent + 'TypeName: ', AName.TypeName); + Writeln(AIndent + 'Value: ', AName.Value); +end; + +procedure PrintGeneralNameList(const ANameList: TArray; const AIndent: string); +var + LNameItem: TGeneralName; +begin + for LNameItem in ANameList do + begin + PrintGeneralName(LNameItem, AIndent); + Writeln; + end; +end; + +procedure PrintCrlDistPointList(const ACrlDistPointList: TArray; const AIndent: string); +var + LCrlDistPointItem: TCrlDistPoint; +begin + for LCrlDistPointItem in ACrlDistPointList do + begin + Writeln(AIndent + 'Reasons: ', LCrlDistPointItem.Reasons); + Writeln(AIndent + 'DpReasons: ', LCrlDistPointItem.DpReasons); + + Writeln(AIndent + 'DistPoint:'); + PrintGeneralNameList(LCrlDistPointItem.DistPoint, AIndent + ' '); + + Writeln(AIndent + 'CRLissuer:'); + PrintGeneralNameList(LCrlDistPointItem.CRLissuer, AIndent + ' '); + + Writeln; + end; +end; + +procedure PrintAuthorityInfoAccesses(const AAuthorityInfoAccesses: TArray; const AIndent: string); +var + LAuthorityInfoAccessItem: TAuthorityInfoAccess; +begin + for LAuthorityInfoAccessItem in AAuthorityInfoAccesses do + begin + Writeln(AIndent + 'Method: ', LAuthorityInfoAccessItem.Method); + Writeln(AIndent + 'MethodDesc: ', LAuthorityInfoAccessItem.MethodDesc); + + Writeln(AIndent + 'Location:'); + PrintGeneralName(LAuthorityInfoAccessItem.Location, AIndent + ' '); + + Writeln; + end; +end; + +procedure PrintSctList(const ASctList: TArray; const AIndent: string); +var + LSctItem: TSct; +begin + for LSctItem in ASctList do + begin + Writeln(AIndent + 'Version: ', LSctItem.Version); + Writeln(AIndent + 'Sct: ', TUtils.BytesToHex(LSctItem.Sct)); + Writeln(AIndent + 'LogID: ', TUtils.BytesToHex(LSctItem.LogID)); + Writeln(AIndent + 'Timestamp: ', LSctItem.Timestamp); + Writeln(AIndent + 'Ext: ', TUtils.BytesToHex(LSctItem.Ext)); + Writeln(AIndent + 'HashAlg: ', LSctItem.HashAlg); + Writeln(AIndent + 'SigAlg: ', LSctItem.SigAlg); + Writeln(AIndent + 'Sig: ', TUtils.BytesToHex(LSctItem.Sig)); + Writeln(AIndent + 'EntryType: ', LSctItem.EntryType); + Writeln(AIndent + 'Source: ', LSctItem.Source); + Writeln(AIndent + 'ValidationStatus: ', LSctItem.ValidationStatus); + + Writeln; + end; +end; + +procedure PrintBasicConstraints(const ABasicConstraints: TBasicConstraints; const AIndent: string); +begin + Writeln(AIndent + 'CA: ', ABasicConstraints.CA); + Writeln(AIndent + 'PathLen: ', ABasicConstraints.PathLen); +end; + +procedure PringExtKeyUsage(const AExtKeyUsage: TExtKeyUsage; const AIndent: string); +var + LExtKeyUsageItem: TExtKeyUsageItem; +begin + Writeln(AIndent + Format('Flags: 0x%x', [AExtKeyUsage.Flags])); + Writeln; + for LExtKeyUsageItem in AExtKeyUsage.List do + begin + Writeln(AIndent + 'NID: ', LExtKeyUsageItem.NID); + Writeln(AIndent + 'OID: ', LExtKeyUsageItem.OID); + Writeln(AIndent + 'Value: ', LExtKeyUsageItem.Value); + Writeln; + end; +end; + +procedure PrintSslInfo(const ASslInfo: TSslInfo); +begin + Writeln(Format('TLS Server Name: %s', [ + ASslInfo.HostName + ])); + + Writeln(Format('SSL/TLS Protocol: %s,%s,%d,%d', [ + ASslInfo.SslVersion, + ASslInfo.CurrentCipher, + ASslInfo.CertInfo.PubKeyBits, + ASslInfo.CurrentCipherBits + ])); + + Writeln(Format('Server Temp Key: %s %d bits', [ + ASslInfo.TmpKeyType, + ASslInfo.TmpKeyBits + ])); + + Writeln(Format('Public Key: %s %d bits', [ + ASslInfo.CertInfo.PubKeyType, + ASslInfo.CertInfo.PubKeyBits + ])); + + Writeln('Signature Algorithm: ', ASslInfo.CertInfo.SigAlg); + + Writeln(Format('CertVersion: %d', [ + ASslInfo.CertInfo.Version + 1 + ])); + + Writeln(Format('Serial Number: %s', [ + TUtils.BytesToHex(ASslInfo.CertInfo.SerialNumber) + ])); + + Writeln(Format('Expiration Date: %s - %s', [ + FormatDateTime('yyyy-mm-dd hh:nn:ss', ASslInfo.CertInfo.NotBefore), + FormatDateTime('yyyy-mm-dd hh:nn:ss', ASslInfo.CertInfo.NotAfter) + ])); + + Writeln; + + Writeln('Subject:'); + PrintEntryList(ASslInfo.CertInfo.Subject, ' '); + Writeln; + + Writeln('Issuer:'); + PrintEntryList(ASslInfo.CertInfo.Issuer, ' '); + Writeln; + + Writeln('SHA256Digest:'); + Writeln(Format(' Certificate: %s', [ + TUtils.BytesToHex(ASslInfo.CertInfo.SHA256Digest) + ])); + Writeln(Format(' Public Key: %s', [ + TUtils.BytesToHex(ASslInfo.CertInfo.PubKeySHA256Digest) + ])); + Writeln; + + Writeln('Extension:'); + Writeln(' AuthorityKeyID: ', TUtils.BytesToHex(ASslInfo.CertInfo.Extension.AuthorityKeyID)); + Writeln(' SubjectKeyID: ', TUtils.BytesToHex(ASslInfo.CertInfo.Extension.SubjectKeyID)); + Writeln(Format(' Key Usage: 0x%x', [ASslInfo.CertInfo.Extension.KeyUsage])); + + Writeln(' Alt Names:'); + PrintGeneralNameList(ASslInfo.CertInfo.Extension.AltNames, ' '); + + Writeln(' Crl Dist Points:'); + PrintCrlDistPointList(ASslInfo.CertInfo.Extension.CrlDistPoints, ' '); + + Writeln(' Authority Info Accesses:'); + PrintAuthorityInfoAccesses(ASslInfo.CertInfo.Extension.AuthorityInfoAccesses, ' '); + + Writeln(' Basic Constraints:'); + PrintBasicConstraints(ASslInfo.CertInfo.Extension.BasicConstraints, ' '); + Writeln; + + Writeln(' ExtKey Usage:'); + PringExtKeyUsage(ASslInfo.CertInfo.Extension.ExtKeyUsage, ' '); + + Writeln(' Sct List:'); + PrintSctList(ASslInfo.CertInfo.Extension.SctList, ' '); + + Writeln(' RawData:'); + PrintExtList(ASslInfo.CertInfo.Extension.RawData, ' '); + + Writeln('Cert PEM:' + sLineBreak, ASslInfo.CertInfo.PEM); + Writeln('Cert DER:' + sLineBreak, TUtils.BytesToHex(ASslInfo.CertInfo.DER)); + + Writeln; +end; + +procedure TestHttpCli; +var + LUrl: string; +begin + LUrl := ParamStr(1); + if (LUrl = '') then + begin + PrintHelp(); + Exit; + end; + + if (__HttpCli = nil) then + __HttpCli := TCrossHttpClient.Create; + +// __HttpCli.LocalPort := 1111; + __HttpCli.AutoUrlEncode := False; + __HttpCli.DoRequest('GET', LUrl, nil, nil, 0, + nil, + procedure(const ARequest: ICrossHttpClientRequest) + begin +// ARequest.Header['User-Agent'] := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'; + end, + procedure(const AResponse: ICrossHttpClientResponse) + var + LSslConnection: ICrossSslConnection; + LSslInfo: TSslInfo; + begin + if (AResponse <> nil) and (AResponse.Content <> nil) then + begin + LSslConnection := AResponse.Connection as ICrossSslConnection; + + if LSslConnection.Ssl and LSslConnection.GetSslInfo(LSslInfo) then + PrintSslInfo(LSslInfo); + + Writeln('HTTP GET success'); + Writeln(AResponse.StatusCode, ' ', AResponse.StatusText); + Writeln(AResponse.Header.Encode); + Writeln(TUtils.GetString(AResponse.Content)); + end else + Writeln('HTTP GET failed'); + end); +end; + +begin + // openssl пĬƲһ, ´޸ + // TSSLTools.LibSSL := 'libssl.so'; + // TSSLTools.LibCRYPTO := 'libcrypto.so'; + +// ReportMemoryLeaksOnShutdown := True; + + CrossSocketLogEnabled := False; + TestHttpCli; + Readln; +end. + diff --git a/Net/Demos/Delphi/HttpClient/HttpClient.dproj b/Net/Demos/Delphi/HttpClient/HttpClient.dproj index 3278f4d..5ad639e 100644 --- a/Net/Demos/Delphi/HttpClient/HttpClient.dproj +++ b/Net/Demos/Delphi/HttpClient/HttpClient.dproj @@ -1,1161 +1,1161 @@ - - - {442E776D-AA76-4CED-AB04-3ED1CB1A011F} - HttpClient.dpr - True - Release - 168067 - Console - None - 20.3 - Win64 - HttpClient - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - false - false - false - false - false - 00400000 - HttpClient - 2052 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - $(BDS)\bin\delphi_PROJECTICON.ico - $(BDS)\bin\delphi_PROJECTICNS.icns - bin\$(Platform)\ - ..\..\..\..\;..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC;..\..\..\..\CnPack\Crypto;..\..\..\..\CnPack\Common;$(DCC_UnitSearchPath) - .\$(Platform)\$(Config) - - - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png - true - true - true - true - true - true - true - true - true - true - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - - - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - Debug - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - 1033 - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - Debug - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - 1033 - - - RELEASE;$(DCC_Define) - 0 - false - 0 - - - Debug - - - /usr/bin/gnome-terminal -- "%debuggee%" - (None) - none - - - Debug - - - Debug - - - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - (None) - none - - - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - (None) - none - - - DEBUG;$(DCC_Define) - false - true - true - true - - - Debug - - - Debug - - - Debug - - - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - (None) - none - madExcept;LeakChecking;$(DCC_Define) - 3 - - - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - (None) - none - 3 - madExcept;LeakChecking;$(DCC_Define) - https://www.163.com/ - - - - MainSource - - - Base - - - Cfg_1 - Base - - - Cfg_2 - Base - - - - Delphi.Personality.12 - - - - - HttpClient.dpr - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - False - True - True - True - True - True - True - - - - - true - - - - - true - - - - - true - - - - - HttpClient.exe - true - - - - - 1 - - - 0 - - - - - res\xml - 1 - - - res\xml - 1 - - - - - library\lib\armeabi - 1 - - - library\lib\armeabi - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\mips - 1 - - - library\lib\mips - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable-anydpi-v21 - 1 - - - res\drawable-anydpi-v21 - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - res\values-v21 - 1 - - - res\values-v21 - 1 - - - - - res\values-v31 - 1 - - - res\values-v31 - 1 - - - - - res\values-v35 - 1 - - - res\values-v35 - 1 - - - - - res\drawable-anydpi-v26 - 1 - - - res\drawable-anydpi-v26 - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable-anydpi-v33 - 1 - - - res\drawable-anydpi-v33 - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - res\values-night-v21 - 1 - - - res\values-night-v21 - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable-xxhdpi - 1 - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-xxxhdpi - 1 - - - res\drawable-xxxhdpi - 1 - - - - - res\drawable-ldpi - 1 - - - res\drawable-ldpi - 1 - - - - - res\drawable-mdpi - 1 - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - res\drawable-xhdpi - 1 - - - - - res\drawable-mdpi - 1 - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - res\drawable-xhdpi - 1 - - - - - res\drawable-xxhdpi - 1 - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-xxxhdpi - 1 - - - res\drawable-xxxhdpi - 1 - - - - - res\drawable-small - 1 - - - res\drawable-small - 1 - - - - - res\drawable-normal - 1 - - - res\drawable-normal - 1 - - - - - res\drawable-large - 1 - - - res\drawable-large - 1 - - - - - res\drawable-xlarge - 1 - - - res\drawable-xlarge - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - res\drawable-anydpi-v24 - 1 - - - res\drawable-anydpi-v24 - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable-night-anydpi-v21 - 1 - - - res\drawable-night-anydpi-v21 - 1 - - - - - res\drawable-anydpi-v31 - 1 - - - res\drawable-anydpi-v31 - 1 - - - - - res\drawable-night-anydpi-v31 - 1 - - - res\drawable-night-anydpi-v31 - 1 - - - - - 1 - - - 1 - - - 0 - - - - - 1 - .framework - - - 1 - .framework - - - 1 - .framework - - - 0 - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 0 - .bpl - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 1 - - - 1 - - - - - - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - - - - 1 - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - - - - - - - - - - - - - 12 - - - - - + + + {442E776D-AA76-4CED-AB04-3ED1CB1A011F} + HttpClient.dpr + True + Release + 168067 + Console + None + 20.3 + Win64 + HttpClient + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + false + false + false + false + false + 00400000 + HttpClient + 2052 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\delphi_PROJECTICNS.icns + bin\$(Platform)\ + ..\..\..\..\;..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC;..\..\..\..\CnPack\Crypto;..\..\..\..\CnPack\Common;$(DCC_UnitSearchPath) + .\$(Platform)\$(Config) + + + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + true + true + true + true + true + true + true + true + true + true + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + + + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) + 1033 + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + + + RELEASE;$(DCC_Define) + 0 + false + 0 + + + Debug + + + /usr/bin/gnome-terminal -- "%debuggee%" + (None) + none + + + Debug + + + Debug + + + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) + (None) + none + + + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + (None) + none + + + DEBUG;$(DCC_Define) + false + true + true + true + + + Debug + + + Debug + + + Debug + + + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) + (None) + none + madExcept;LeakChecking;$(DCC_Define) + 3 + + + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + (None) + none + 3 + madExcept;LeakChecking;$(DCC_Define) + https://www.163.com/ + + + + MainSource + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + + + + + HttpClient.dpr + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + False + True + True + True + True + True + True + + + + + true + + + + + true + + + + + true + + + + + HttpClient.exe + true + + + + + 1 + + + 0 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\values-v35 + 1 + + + res\values-v35 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + + + + + + + + + + + + + 12 + + + + + diff --git a/Net/Demos/Delphi/HttpClient/HttpClient.dsv b/Net/Demos/Delphi/HttpClient/HttpClient.dsv index cf3b866..6ffb5c3 100644 --- a/Net/Demos/Delphi/HttpClient/HttpClient.dsv +++ b/Net/Demos/Delphi/HttpClient/HttpClient.dsv @@ -1,11 +1,11 @@ -[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwQ2xp -ZW50XEh0dHBDbGllbnQuZHBy] -Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpClient\HttpClient.dpr -CursorX=1 -CursorY=1 -TopLine=109 -LeftCol=1 -Elisions= -Bookmarks= -EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpClient\HttpClient.dpr - +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwQ2xp +ZW50XEh0dHBDbGllbnQuZHBy] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpClient\HttpClient.dpr +CursorX=1 +CursorY=1 +TopLine=109 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpClient\HttpClient.dpr + diff --git a/Net/Demos/Delphi/HttpServer/HttpServer.dpr b/Net/Demos/Delphi/HttpServer/HttpServer.dpr index 7ef2a9d..e531119 100644 --- a/Net/Demos/Delphi/HttpServer/HttpServer.dpr +++ b/Net/Demos/Delphi/HttpServer/HttpServer.dpr @@ -1,118 +1,118 @@ -program HttpServer; - -{$APPTYPE CONSOLE} - -{$I zLib.inc} - -uses - SysUtils, - Classes, - Net.CrossSocket.Base in '..\..\..\Net.CrossSocket.Base.pas', - Net.CrossHttpServer in '..\..\..\Net.CrossHttpServer.pas', - Net.CrossHttpParams in '..\..\..\Net.CrossHttpParams.pas', - Net.OpenSSL in '..\..\..\Net.OpenSSL.pas', - Utils.Utils in '..\..\..\..\Utils\Utils.Utils.pas', - Utils.Hash in '..\..\..\..\Utils\Utils.Hash.pas', - DTF.Hash in '..\..\..\..\DelphiToFPC\DTF.Hash.pas', - CnAES in '..\..\..\..\CnPack\Crypto\CnAES.pas', - CnBase64 in '..\..\..\..\CnPack\Crypto\CnBase64.pas', - CnConsts in '..\..\..\..\CnPack\Crypto\CnConsts.pas', - CnDES in '..\..\..\..\CnPack\Crypto\CnDES.pas', - CnFloat in '..\..\..\..\CnPack\Crypto\CnFloat.pas', - CnKDF in '..\..\..\..\CnPack\Crypto\CnKDF.pas', - CnMD5 in '..\..\..\..\CnPack\Crypto\CnMD5.pas', - CnNative in '..\..\..\..\CnPack\Crypto\CnNative.pas', - CnPemUtils in '..\..\..\..\CnPack\Crypto\CnPemUtils.pas', - CnRandom in '..\..\..\..\CnPack\Crypto\CnRandom.pas', - CnSHA1 in '..\..\..\..\CnPack\Crypto\CnSHA1.pas', - CnSHA2 in '..\..\..\..\CnPack\Crypto\CnSHA2.pas', - CnSHA3 in '..\..\..\..\CnPack\Crypto\CnSHA3.pas', - CnSM3 in '..\..\..\..\CnPack\Crypto\CnSM3.pas', - Net.CrossHttpParser in '..\..\..\Net.CrossHttpParser.pas', - Net.CrossHttpRouter in '..\..\..\Net.CrossHttpRouter.pas', - Net.CrossHttpRouterDirUtils in '..\..\..\Net.CrossHttpRouterDirUtils.pas', - Utils.AnonymousThread in '..\..\..\..\Utils\Utils.AnonymousThread.pas', - Utils.ArrayUtils in '..\..\..\..\Utils\Utils.ArrayUtils.pas', - Utils.DateTime in '..\..\..\..\Utils\Utils.DateTime.pas'; - -var - __HttpServer: ICrossHttpServer; - -procedure TestCrossHttpServer; -var - LResponseStr: string; -begin - LResponseStr := TOSVersion.ToString + '
Hello World!'; - - //__HttpServer := TCrossHttpServer.Create(0, True); - __HttpServer := TCrossHttpServer.Create(0, False); - if __HttpServer.Ssl then - begin - __HttpServer.SetCertificateFile('server.crt'); - __HttpServer.SetPrivateKeyFile('server.key'); - end; - - __HttpServer.Port := 9010; - __HttpServer.Start( - procedure(const AListen: ICrossListen; const ASuccess: Boolean) - begin - if ASuccess then - begin - if __HttpServer.Ssl then - Writeln('HTTP server(ssl: ' + TSSLTools.LibSSL + ' & ' + TSSLTools.LibCRYPTO + ') listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']') - else - Writeln('HTTP server listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']'); - end; - end); - - __HttpServer.Get('/', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) - begin - AResponse.Send(LResponseStr); - AHandled := True; - end); - - __HttpServer.Get('/ping', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) - begin - AResponse.Send('pong'); - AHandled := True; - end); - - __HttpServer.Post('/upload', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) - var - LHashStr: string; - LFormField: TFormField; - begin - LHashStr := ''; - if (ARequest.BodyType = btMultiPart) then - begin - for LFormField in (ARequest.Body as THttpMultiPartFormData) do - begin - if (LFormField.ContentType <> '') then - begin - if (LHashStr <> '') then - LHashStr := LHashStr + sLineBreak; - - LHashStr := LHashStr + 'FileName: ' + LFormField.FileName + sLineBreak; - LHashStr := LHashStr + 'MD5: ' + THashMD5.GetHashStringFromStream(LFormField.Value) + sLineBreak; - LHashStr := LHashStr + 'SHA1: ' + THashSHA1.GetHashStringFromStream(LFormField.Value) + sLineBreak; - end; - end; - end; - - AResponse.Send(LHashStr); - AHandled := True; - end); -end; - -begin - // openssl пĬƲһ, ´޸ - // TSSLTools.LibSSL := 'libssl.so'; - // TSSLTools.LibCRYPTO := 'libcrypto.so'; - - TestCrossHttpServer; - Readln; -end. - +program HttpServer; + +{$APPTYPE CONSOLE} + +{$I zLib.inc} + +uses + SysUtils, + Classes, + Net.CrossSocket.Base in '..\..\..\Net.CrossSocket.Base.pas', + Net.CrossHttpServer in '..\..\..\Net.CrossHttpServer.pas', + Net.CrossHttpParams in '..\..\..\Net.CrossHttpParams.pas', + Net.OpenSSL in '..\..\..\Net.OpenSSL.pas', + Utils.Utils in '..\..\..\..\Utils\Utils.Utils.pas', + Utils.Hash in '..\..\..\..\Utils\Utils.Hash.pas', + DTF.Hash in '..\..\..\..\DelphiToFPC\DTF.Hash.pas', + CnAES in '..\..\..\..\CnPack\Crypto\CnAES.pas', + CnBase64 in '..\..\..\..\CnPack\Crypto\CnBase64.pas', + CnConsts in '..\..\..\..\CnPack\Crypto\CnConsts.pas', + CnDES in '..\..\..\..\CnPack\Crypto\CnDES.pas', + CnFloat in '..\..\..\..\CnPack\Crypto\CnFloat.pas', + CnKDF in '..\..\..\..\CnPack\Crypto\CnKDF.pas', + CnMD5 in '..\..\..\..\CnPack\Crypto\CnMD5.pas', + CnNative in '..\..\..\..\CnPack\Crypto\CnNative.pas', + CnPemUtils in '..\..\..\..\CnPack\Crypto\CnPemUtils.pas', + CnRandom in '..\..\..\..\CnPack\Crypto\CnRandom.pas', + CnSHA1 in '..\..\..\..\CnPack\Crypto\CnSHA1.pas', + CnSHA2 in '..\..\..\..\CnPack\Crypto\CnSHA2.pas', + CnSHA3 in '..\..\..\..\CnPack\Crypto\CnSHA3.pas', + CnSM3 in '..\..\..\..\CnPack\Crypto\CnSM3.pas', + Net.CrossHttpParser in '..\..\..\Net.CrossHttpParser.pas', + Net.CrossHttpRouter in '..\..\..\Net.CrossHttpRouter.pas', + Net.CrossHttpRouterDirUtils in '..\..\..\Net.CrossHttpRouterDirUtils.pas', + Utils.AnonymousThread in '..\..\..\..\Utils\Utils.AnonymousThread.pas', + Utils.ArrayUtils in '..\..\..\..\Utils\Utils.ArrayUtils.pas', + Utils.DateTime in '..\..\..\..\Utils\Utils.DateTime.pas'; + +var + __HttpServer: ICrossHttpServer; + +procedure TestCrossHttpServer; +var + LResponseStr: string; +begin + LResponseStr := TOSVersion.ToString + '
Hello World!'; + + //__HttpServer := TCrossHttpServer.Create(0, True); + __HttpServer := TCrossHttpServer.Create(0, False); + if __HttpServer.Ssl then + begin + __HttpServer.SetCertificateFile('server.crt'); + __HttpServer.SetPrivateKeyFile('server.key'); + end; + + __HttpServer.Port := 9010; + __HttpServer.Start( + procedure(const AListen: ICrossListen; const ASuccess: Boolean) + begin + if ASuccess then + begin + if __HttpServer.Ssl then + Writeln('HTTP server(ssl: ' + TSSLTools.LibSSL + ' & ' + TSSLTools.LibCRYPTO + ') listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']') + else + Writeln('HTTP server listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']'); + end; + end); + + __HttpServer.Get('/', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) + begin + AResponse.Send(LResponseStr); + AHandled := True; + end); + + __HttpServer.Get('/ping', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) + begin + AResponse.Send('pong'); + AHandled := True; + end); + + __HttpServer.Post('/upload', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) + var + LHashStr: string; + LFormField: TFormField; + begin + LHashStr := ''; + if (ARequest.BodyType = btMultiPart) then + begin + for LFormField in (ARequest.Body as THttpMultiPartFormData) do + begin + if (LFormField.ContentType <> '') then + begin + if (LHashStr <> '') then + LHashStr := LHashStr + sLineBreak; + + LHashStr := LHashStr + 'FileName: ' + LFormField.FileName + sLineBreak; + LHashStr := LHashStr + 'MD5: ' + THashMD5.GetHashStringFromStream(LFormField.Value) + sLineBreak; + LHashStr := LHashStr + 'SHA1: ' + THashSHA1.GetHashStringFromStream(LFormField.Value) + sLineBreak; + end; + end; + end; + + AResponse.Send(LHashStr); + AHandled := True; + end); +end; + +begin + // openssl пĬƲһ, ´޸ + // TSSLTools.LibSSL := 'libssl.so'; + // TSSLTools.LibCRYPTO := 'libcrypto.so'; + + TestCrossHttpServer; + Readln; +end. + diff --git a/Net/Demos/Delphi/HttpServer/HttpServer.dproj b/Net/Demos/Delphi/HttpServer/HttpServer.dproj index b4d5d26..f127ca5 100644 --- a/Net/Demos/Delphi/HttpServer/HttpServer.dproj +++ b/Net/Demos/Delphi/HttpServer/HttpServer.dproj @@ -1,1137 +1,1137 @@ - - - {901CE442-716D-460E-8B45-0B7F08772F0D} - HttpServer.dpr - True - Debug - 168067 - Console - None - 20.2 - Win64 - HttpServer - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - false - false - false - false - false - 00400000 - HttpServer - 2052 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - $(BDS)\bin\delphi_PROJECTICON.ico - $(BDS)\bin\delphi_PROJECTICNS.icns - bin\$(Platform)\ - ..\..\..\..\;..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC;..\..\..\..\CnPack\Crypto;..\..\..\..\CnPack\Common;$(DCC_UnitSearchPath) - - - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png - true - true - true - true - true - true - true - true - true - true - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - - - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - Debug - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - 1033 - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - Debug - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - 1033 - - - RELEASE;$(DCC_Define) - 0 - false - 0 - - - Debug - - - Debug - - - Debug - - - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - (None) - none - - - DEBUG;$(DCC_Define) - false - true - true - true - - - Debug - - - Debug - - - Debug - - - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - (None) - none - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Base - - - Cfg_1 - Base - - - Cfg_2 - Base - - - - Delphi.Personality.12 - - - - - HttpServer.dpr - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - False - True - True - True - True - True - True - - - - - true - - - - - true - - - - - true - - - - - HttpServer.exe - true - - - - - 1 - - - 0 - - - - - res\xml - 1 - - - res\xml - 1 - - - - - library\lib\armeabi - 1 - - - library\lib\armeabi - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\mips - 1 - - - library\lib\mips - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable-anydpi-v21 - 1 - - - res\drawable-anydpi-v21 - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - res\values-v21 - 1 - - - res\values-v21 - 1 - - - - - res\values-v31 - 1 - - - res\values-v31 - 1 - - - - - res\drawable-anydpi-v26 - 1 - - - res\drawable-anydpi-v26 - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable-anydpi-v33 - 1 - - - res\drawable-anydpi-v33 - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - res\values-night-v21 - 1 - - - res\values-night-v21 - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable-xxhdpi - 1 - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-xxxhdpi - 1 - - - res\drawable-xxxhdpi - 1 - - - - - res\drawable-ldpi - 1 - - - res\drawable-ldpi - 1 - - - - - res\drawable-mdpi - 1 - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - res\drawable-xhdpi - 1 - - - - - res\drawable-mdpi - 1 - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - res\drawable-xhdpi - 1 - - - - - res\drawable-xxhdpi - 1 - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-xxxhdpi - 1 - - - res\drawable-xxxhdpi - 1 - - - - - res\drawable-small - 1 - - - res\drawable-small - 1 - - - - - res\drawable-normal - 1 - - - res\drawable-normal - 1 - - - - - res\drawable-large - 1 - - - res\drawable-large - 1 - - - - - res\drawable-xlarge - 1 - - - res\drawable-xlarge - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - res\drawable-anydpi-v24 - 1 - - - res\drawable-anydpi-v24 - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable-night-anydpi-v21 - 1 - - - res\drawable-night-anydpi-v21 - 1 - - - - - res\drawable-anydpi-v31 - 1 - - - res\drawable-anydpi-v31 - 1 - - - - - res\drawable-night-anydpi-v31 - 1 - - - res\drawable-night-anydpi-v31 - 1 - - - - - 1 - - - 1 - - - 0 - - - - - 1 - .framework - - - 1 - .framework - - - 1 - .framework - - - 0 - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 0 - .bpl - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 1 - - - 1 - - - - - - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - - - - 1 - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - - - - - - - - - - - - - 12 - - - - - + + + {901CE442-716D-460E-8B45-0B7F08772F0D} + HttpServer.dpr + True + Debug + 168067 + Console + None + 20.2 + Win64 + HttpServer + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + false + false + false + false + false + 00400000 + HttpServer + 2052 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\delphi_PROJECTICNS.icns + bin\$(Platform)\ + ..\..\..\..\;..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC;..\..\..\..\CnPack\Crypto;..\..\..\..\CnPack\Common;$(DCC_UnitSearchPath) + + + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + true + true + true + true + true + true + true + true + true + true + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + + + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) + 1033 + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + + + RELEASE;$(DCC_Define) + 0 + false + 0 + + + Debug + + + Debug + + + Debug + + + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + (None) + none + + + DEBUG;$(DCC_Define) + false + true + true + true + + + Debug + + + Debug + + + Debug + + + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) + (None) + none + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + + + + + HttpServer.dpr + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + False + True + True + True + True + True + True + + + + + true + + + + + true + + + + + true + + + + + HttpServer.exe + true + + + + + 1 + + + 0 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + + + + + + + + + + + + + 12 + + + + + diff --git a/Net/Demos/Delphi/HttpServer/HttpServer.dproj.local b/Net/Demos/Delphi/HttpServer/HttpServer.dproj.local index b3811b7..d576f03 100644 --- a/Net/Demos/Delphi/HttpServer/HttpServer.dproj.local +++ b/Net/Demos/Delphi/HttpServer/HttpServer.dproj.local @@ -1,2 +1,2 @@ - - + + diff --git a/Net/Demos/Delphi/HttpServer/HttpServer.dsv b/Net/Demos/Delphi/HttpServer/HttpServer.dsv index 4f36088..6bfadf6 100644 --- a/Net/Demos/Delphi/HttpServer/HttpServer.dsv +++ b/Net/Demos/Delphi/HttpServer/HttpServer.dsv @@ -1,110 +1,110 @@ -[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcVXRpbHNcVXRpbHMuSGFzaC5wYXM=] -Module=C:\lang\Repo\Delphi-Cross-Socket\Utils\Utils.Hash.pas -CursorX=31 -CursorY=159 -TopLine=143 -LeftCol=1 -Elisions={{63,4},{88,15},{'核心hash方法'}} -Bookmarks= -EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Utils\Utils.Hash.pas -[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwU2Vy -dmVyXEh0dHBTZXJ2ZXIuZHBy] -Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr -CursorX=85 -CursorY=71 -TopLine=54 -LeftCol=1 -Elisions= -Bookmarks= -EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr -[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwU2Vy -dmVyXEh0dHBTZXJ2ZXIuZHBy] -Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr -CursorX=65 -CursorY=75 -TopLine=27 -LeftCol=1 -Elisions= -Bookmarks= -EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr -[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwU2Vy -dmVyXEh0dHBTZXJ2ZXIuZHBy] -Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr -CursorX=63 -CursorY=29 -TopLine=10 -LeftCol=1 -Elisions= -Bookmarks= -EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr -[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwU2Vy -dmVyXEh0dHBTZXJ2ZXIuZHBy] -Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr -CursorX=1 -CursorY=69 -TopLine=51 -LeftCol=1 -Elisions= -Bookmarks= -EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr -[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc0h0dHBTZXJ2ZXIu -cGFz] -Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas -CursorX=1 -CursorY=3617 -TopLine=3597 -LeftCol=1 -Elisions={{1635,4},{1649,15},{'HttpParser事件'}}{{1823,4},{1826,15},{'内部: 基础发送方法'}}{{1830,4},{1839,15},{'压缩发送'}}{{1841,4},{1850,15},{'不压缩发送'}}{{1852,4},{1871,15},{'常规方法'}}{{2296,2},{2317,13},{'创建Body'}}{{3312,4},{3323,15},{'Session'}}{{3328,4},{3341,15},{'中间件'}}{{3359,4},{3368,15},{'响应请求事件'}} -Bookmarks= -EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas -[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc0h0dHBQYXJzZXIu -cGFz] -Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpParser.pas -CursorX=43 -CursorY=62 -TopLine=42 -LeftCol=1 -Elisions= -Bookmarks= -EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpParser.pas -[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc0h0dHBTZXJ2ZXIu -cGFz] -Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas -CursorX=1 -CursorY=3620 -TopLine=3600 -LeftCol=1 -Elisions={{1635,4},{1649,15},{'HttpParser事件'}}{{1823,4},{1826,15},{'内部: 基础发送方法'}}{{1830,4},{1839,15},{'压缩发送'}}{{1841,4},{1850,15},{'不压缩发送'}}{{1852,4},{1871,15},{'常规方法'}}{{2296,2},{2317,13},{'创建Body'}}{{3312,4},{3323,15},{'Session'}}{{3328,4},{3341,15},{'中间件'}}{{3359,4},{3368,15},{'响应请求事件'}} -Bookmarks= -EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas -[ClosedView_QzpcbGFuZ1xSZXBvXGhvcnNlLXByb3ZpZGVyLWNyb3Nzc29ja2V0XHNyY1xIb3JzZS5Qcm92aWRl -ci5Dcm9zc1NvY2tldC5SZXNwb25zZS5wYXM=] -Module=C:\lang\Repo\horse-provider-crosssocket\src\Horse.Provider.CrossSocket.Response.pas -CursorX=1 -CursorY=256 -TopLine=236 -LeftCol=1 -Elisions= -Bookmarks= -EditViewName=C:\lang\Repo\horse-provider-crosssocket\src\Horse.Provider.CrossSocket.Response.pas -[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc0h0dHBTZXJ2ZXIu -cGFz] -Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas -CursorX=1 -CursorY=4600 -TopLine=4580 -LeftCol=1 -Elisions={{1635,4},{1649,15},{'HttpParser事件'}}{{1823,4},{1826,15},{'内部: 基础发送方法'}}{{1830,4},{1839,15},{'压缩发送'}}{{1841,4},{1850,15},{'不压缩发送'}}{{1852,4},{1871,15},{'常规方法'}}{{2296,2},{2317,13},{'创建Body'}}{{3359,4},{3368,15},{'响应请求事件'}} -Bookmarks= -EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas -[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc1NvY2tldC5CYXNl -LnBhcw==] -Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossSocket.Base.pas -CursorX=1 -CursorY=1682 -TopLine=1664 -LeftCol=1 -Elisions={{816,4},{826,15},{'物理事件'}}{{828,4},{838,15},{'逻辑事件'}}{{1533,2},{1539,13},{'本地地址信息'}}{{1911,2},{1916,13},{'远端地址信息'}} -Bookmarks= -EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossSocket.Base.pas - +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcVXRpbHNcVXRpbHMuSGFzaC5wYXM=] +Module=C:\lang\Repo\Delphi-Cross-Socket\Utils\Utils.Hash.pas +CursorX=31 +CursorY=159 +TopLine=143 +LeftCol=1 +Elisions={{63,4},{88,15},{'核心hash方法'}} +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Utils\Utils.Hash.pas +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwU2Vy +dmVyXEh0dHBTZXJ2ZXIuZHBy] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +CursorX=85 +CursorY=71 +TopLine=54 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwU2Vy +dmVyXEh0dHBTZXJ2ZXIuZHBy] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +CursorX=65 +CursorY=75 +TopLine=27 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwU2Vy +dmVyXEh0dHBTZXJ2ZXIuZHBy] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +CursorX=63 +CursorY=29 +TopLine=10 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XERlbW9zXERlbHBoaVxIdHRwU2Vy +dmVyXEh0dHBTZXJ2ZXIuZHBy] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +CursorX=1 +CursorY=69 +TopLine=51 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Demos\Delphi\HttpServer\HttpServer.dpr +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc0h0dHBTZXJ2ZXIu +cGFz] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas +CursorX=1 +CursorY=3617 +TopLine=3597 +LeftCol=1 +Elisions={{1635,4},{1649,15},{'HttpParser事件'}}{{1823,4},{1826,15},{'内部: 基础发送方法'}}{{1830,4},{1839,15},{'压缩发送'}}{{1841,4},{1850,15},{'不压缩发送'}}{{1852,4},{1871,15},{'常规方法'}}{{2296,2},{2317,13},{'创建Body'}}{{3312,4},{3323,15},{'Session'}}{{3328,4},{3341,15},{'中间件'}}{{3359,4},{3368,15},{'响应请求事件'}} +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc0h0dHBQYXJzZXIu +cGFz] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpParser.pas +CursorX=43 +CursorY=62 +TopLine=42 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpParser.pas +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc0h0dHBTZXJ2ZXIu +cGFz] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas +CursorX=1 +CursorY=3620 +TopLine=3600 +LeftCol=1 +Elisions={{1635,4},{1649,15},{'HttpParser事件'}}{{1823,4},{1826,15},{'内部: 基础发送方法'}}{{1830,4},{1839,15},{'压缩发送'}}{{1841,4},{1850,15},{'不压缩发送'}}{{1852,4},{1871,15},{'常规方法'}}{{2296,2},{2317,13},{'创建Body'}}{{3312,4},{3323,15},{'Session'}}{{3328,4},{3341,15},{'中间件'}}{{3359,4},{3368,15},{'响应请求事件'}} +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas +[ClosedView_QzpcbGFuZ1xSZXBvXGhvcnNlLXByb3ZpZGVyLWNyb3Nzc29ja2V0XHNyY1xIb3JzZS5Qcm92aWRl +ci5Dcm9zc1NvY2tldC5SZXNwb25zZS5wYXM=] +Module=C:\lang\Repo\horse-provider-crosssocket\src\Horse.Provider.CrossSocket.Response.pas +CursorX=1 +CursorY=256 +TopLine=236 +LeftCol=1 +Elisions= +Bookmarks= +EditViewName=C:\lang\Repo\horse-provider-crosssocket\src\Horse.Provider.CrossSocket.Response.pas +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc0h0dHBTZXJ2ZXIu +cGFz] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas +CursorX=1 +CursorY=4600 +TopLine=4580 +LeftCol=1 +Elisions={{1635,4},{1649,15},{'HttpParser事件'}}{{1823,4},{1826,15},{'内部: 基础发送方法'}}{{1830,4},{1839,15},{'压缩发送'}}{{1841,4},{1850,15},{'不压缩发送'}}{{1852,4},{1871,15},{'常规方法'}}{{2296,2},{2317,13},{'创建Body'}}{{3359,4},{3368,15},{'响应请求事件'}} +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossHttpServer.pas +[ClosedView_QzpcbGFuZ1xSZXBvXERlbHBoaS1Dcm9zcy1Tb2NrZXRcTmV0XE5ldC5Dcm9zc1NvY2tldC5CYXNl +LnBhcw==] +Module=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossSocket.Base.pas +CursorX=1 +CursorY=1682 +TopLine=1664 +LeftCol=1 +Elisions={{816,4},{826,15},{'物理事件'}}{{828,4},{838,15},{'逻辑事件'}}{{1533,2},{1539,13},{'本地地址信息'}}{{1911,2},{1916,13},{'远端地址信息'}} +Bookmarks= +EditViewName=C:\lang\Repo\Delphi-Cross-Socket\Net\Net.CrossSocket.Base.pas + diff --git a/Net/Demos/Delphi/WebSocketClient/WebSocketClient.dpr b/Net/Demos/Delphi/WebSocketClient/WebSocketClient.dpr index 71d4336..7a02127 100644 --- a/Net/Demos/Delphi/WebSocketClient/WebSocketClient.dpr +++ b/Net/Demos/Delphi/WebSocketClient/WebSocketClient.dpr @@ -1,98 +1,98 @@ -program WebSocketClient; - -{$APPTYPE CONSOLE} - -{$I zLib.inc} - -uses - SysUtils - ,Classes - ,Net.CrossSocket.Base - ,Net.CrossWebSocketClient - ,Net.CrossWebSocketParser - ,Net.OpenSSL - ,Utils.Utils - ; - -var - __WebSocket: ICrossWebSocket; - -procedure TestWebSocketClient; -begin - __WebSocket := TCrossWebSocket.Create('wss://127.0.0.1:8090/test_web_socket'); - - __WebSocket.OnOpen( - procedure - begin - Writeln('Open'); - __WebSocket.Ping; - end); - - __WebSocket.OnClose( - procedure - begin - Writeln('Close'); - end); - - __WebSocket.OnPing( - procedure - begin - Writeln('Ping'); - end); - - __WebSocket.OnPong( - procedure - begin - Writeln('Pong'); - __WebSocket.Send('你好AAA!', - procedure(const ASuccess: Boolean) - begin - Writeln('你好AAA! ', ASuccess); - end); - - __WebSocket.Send('你好BBB!', - procedure(const ASuccess: Boolean) - begin - Writeln('你好BBB! ', ASuccess); - end); - - __WebSocket.Send('你好CCC!', - procedure(const ASuccess: Boolean) - begin - Writeln('你好CCC! ', ASuccess); - end); - - __WebSocket.Send('你好DDD!', - procedure(const ASuccess: Boolean) - begin - Writeln('你好DDD! ', ASuccess); - end); - end); - - __WebSocket.OnMessage( - procedure(const AMessageType: TWsMessageType; const AMessageData: TBytes) - var - LMessage: string; - begin - case AMessageType of - wtText: - LMessage := TUtils.GetString(AMessageData); - else - LMessage := TUtils.BytesToHex(AMessageData); - end; - - Writeln('[message]:', LMessage); - end); - - __WebSocket.Open; -end; - -begin - // 如果 openssl 运行库名称与默认名称不一致, 请自行用以下代码修改 -// TSSLTools.LibSSL := 'libssl.so'; -// TSSLTools.LibCRYPTO := 'libcrypto.so'; - - TestWebSocketClient; - Readln; -end. - +program WebSocketClient; + +{$APPTYPE CONSOLE} + +{$I zLib.inc} + +uses + SysUtils + ,Classes + ,Net.CrossSocket.Base + ,Net.CrossWebSocketClient + ,Net.CrossWebSocketParser + ,Net.OpenSSL + ,Utils.Utils + ; + +var + __WebSocket: ICrossWebSocket; + +procedure TestWebSocketClient; +begin + __WebSocket := TCrossWebSocket.Create('wss://127.0.0.1:8090/test_web_socket'); + + __WebSocket.OnOpen( + procedure + begin + Writeln('Open'); + __WebSocket.Ping; + end); + + __WebSocket.OnClose( + procedure + begin + Writeln('Close'); + end); + + __WebSocket.OnPing( + procedure + begin + Writeln('Ping'); + end); + + __WebSocket.OnPong( + procedure + begin + Writeln('Pong'); + __WebSocket.Send('你好AAA!', + procedure(const ASuccess: Boolean) + begin + Writeln('你好AAA! ', ASuccess); + end); + + __WebSocket.Send('你好BBB!', + procedure(const ASuccess: Boolean) + begin + Writeln('你好BBB! ', ASuccess); + end); + + __WebSocket.Send('你好CCC!', + procedure(const ASuccess: Boolean) + begin + Writeln('你好CCC! ', ASuccess); + end); + + __WebSocket.Send('你好DDD!', + procedure(const ASuccess: Boolean) + begin + Writeln('你好DDD! ', ASuccess); + end); + end); + + __WebSocket.OnMessage( + procedure(const AMessageType: TWsMessageType; const AMessageData: TBytes) + var + LMessage: string; + begin + case AMessageType of + wtText: + LMessage := TUtils.GetString(AMessageData); + else + LMessage := TUtils.BytesToHex(AMessageData); + end; + + Writeln('[message]:', LMessage); + end); + + __WebSocket.Open; +end; + +begin + // 如果 openssl 运行库名称与默认名称不一致, 请自行用以下代码修改 +// TSSLTools.LibSSL := 'libssl.so'; +// TSSLTools.LibCRYPTO := 'libcrypto.so'; + + TestWebSocketClient; + Readln; +end. + diff --git a/Net/Demos/Delphi/WebSocketClient/WebSocketClient.dproj b/Net/Demos/Delphi/WebSocketClient/WebSocketClient.dproj index 3309ca6..0587663 100644 --- a/Net/Demos/Delphi/WebSocketClient/WebSocketClient.dproj +++ b/Net/Demos/Delphi/WebSocketClient/WebSocketClient.dproj @@ -1,307 +1,307 @@ - - - {0F3555D0-48D7-4CC0-906B-F995416C957C} - WebSocketClient.dpr - True - Release - 693379 - Console - None - 19.5 - Win64 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - false - false - false - false - false - 00400000 - WebSocketClient - 2052 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - $(BDS)\bin\delphi_PROJECTICON.ico - $(BDS)\bin\delphi_PROJECTICNS.icns - bin\$(Platform)\ - ..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC;$(DCC_UnitSearchPath) - - - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png - true - true - true - true - true - true - true - true - true - true - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - - - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - - - $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png - $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png - $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png - $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png - - - $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png - - - $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png - $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png - $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png - $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - Debug - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - 1033 - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - Debug - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - 1033 - - - RELEASE;$(DCC_Define) - 0 - false - 0 - - - Debug - - - Debug - - - Debug - - - Debug - - - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - (None) - none - - - DEBUG;$(DCC_Define) - false - true - true - true - - - Debug - - - Debug - - - Debug - - - Debug - - - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - (None) - none - - - - MainSource - - - Base - - - Cfg_1 - Base - - - Cfg_2 - Base - - - - Delphi.Personality.12 - - - - - WebSocketClient.dpr - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\CEF4Delphi_FMX.bpl not found - File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\AutoUpgraderProXE10.bpl not found - File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\KastriFMX280.bpl not found - File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\CEF4Delphi.bpl not found - - - - False - True - False - True - True - False - True - False - True - True - True - True - - - 12 - - - - + + + {0F3555D0-48D7-4CC0-906B-F995416C957C} + WebSocketClient.dpr + True + Release + 693379 + Console + None + 19.5 + Win64 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + false + false + false + false + false + 00400000 + WebSocketClient + 2052 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\delphi_PROJECTICNS.icns + bin\$(Platform)\ + ..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC;$(DCC_UnitSearchPath) + + + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + true + true + true + true + true + true + true + true + true + true + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + + + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + + + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png + $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png + $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png + + + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png + + + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png + $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png + $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) + 1033 + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + + + RELEASE;$(DCC_Define) + 0 + false + 0 + + + Debug + + + Debug + + + Debug + + + Debug + + + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + (None) + none + + + DEBUG;$(DCC_Define) + false + true + true + true + + + Debug + + + Debug + + + Debug + + + Debug + + + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) + (None) + none + + + + MainSource + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + + + + + WebSocketClient.dpr + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\CEF4Delphi_FMX.bpl not found + File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\AutoUpgraderProXE10.bpl not found + File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\KastriFMX280.bpl not found + File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\CEF4Delphi.bpl not found + + + + False + True + False + True + True + False + True + False + True + True + True + True + + + 12 + + + + diff --git a/Net/Demos/Delphi/WebSocketClient/WebSocketClient.dproj.local b/Net/Demos/Delphi/WebSocketClient/WebSocketClient.dproj.local index b3811b7..d576f03 100644 --- a/Net/Demos/Delphi/WebSocketClient/WebSocketClient.dproj.local +++ b/Net/Demos/Delphi/WebSocketClient/WebSocketClient.dproj.local @@ -1,2 +1,2 @@ - - + + diff --git a/Net/Demos/Delphi/WebSocketServer/WebSocketServer.dpr b/Net/Demos/Delphi/WebSocketServer/WebSocketServer.dpr index d6682ba..5c94881 100644 --- a/Net/Demos/Delphi/WebSocketServer/WebSocketServer.dpr +++ b/Net/Demos/Delphi/WebSocketServer/WebSocketServer.dpr @@ -1,106 +1,106 @@ -program WebSocketServer; - -{$APPTYPE CONSOLE} - -{$I zLib.inc} - -uses - SysUtils - ,Classes - ,Net.CrossSocket.Base - ,Net.CrossHttpServer - ,Net.CrossWebSocketServer - ,Net.CrossWebSocketParser - ,Net.OpenSSL - ,Utils.Utils - ; - -var - __HttpServer: ICrossWebSocketServer; - -procedure TestCrossHttpServer; -var - LResponseStr: string; -begin - __HttpServer := TCrossWebSocketServer.Create(2, True); - if __HttpServer.Ssl then - begin - __HttpServer.SetCertificateFile('server.crt'); - __HttpServer.SetPrivateKeyFile('server.key'); - end; - - __HttpServer.Port := 8090; - __HttpServer.Start( - procedure(const AListen: ICrossListen; const ASuccess: Boolean) - begin - if ASuccess then - begin - if __HttpServer.Ssl then - Writeln('WebSocket server(ssl: ' + TSSLTools.LibSSL + ' & ' + TSSLTools.LibCRYPTO + ') listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']') - else - Writeln('WebSocket server listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']'); - end; - end); - - __HttpServer.Get('/', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) - begin - LResponseStr := TOSVersion.ToString + '
Hello World!'; - AResponse.Send(LResponseStr); - AHandled := True; - end); - - __HttpServer.OnOpen( - procedure(const AConnection: ICrossWebSocketConnection) - begin - Writeln(Format('[%s : %d]Open', [AConnection.PeerAddr, AConnection.PeerPort])); - end); - - __HttpServer.OnClose( - procedure(const AConnection: ICrossWebSocketConnection) - begin - Writeln(Format('[%s : %d]Close', [AConnection.PeerAddr, AConnection.PeerPort])); - end); - - __HttpServer.OnPing( - procedure(const AConnection: ICrossWebSocketConnection) - begin - Writeln(Format('[%s : %d]Ping', [AConnection.PeerAddr, AConnection.PeerPort])); - end); - - __HttpServer.OnPong( - procedure(const AConnection: ICrossWebSocketConnection) - begin - Writeln(Format('[%s : %d]Pong', [AConnection.PeerAddr, AConnection.PeerPort])); - end); - - __HttpServer.OnMessage( - procedure(const AConnection: ICrossWebSocketConnection; - const AType: TWsMessageType; const AData: TBytes) - var - LMessage: string; - begin - if (AType = wtText) then - LMessage := TUtils.GetString(AData) - else - LMessage := TUtils.BytesToHex(AData); - - Writeln(Format('[message][%s : %d]', [AConnection.PeerAddr, AConnection.PeerPort]), LMessage); - - AConnection.WsSend('' + LMessage, - procedure(const AWsConnection: ICrossWebSocketConnection; const ASuccess: Boolean) - begin - //Writeln('ws server send response: ', ASuccess); - end); - end); -end; - -begin - // openssl пĬƲһ, ´޸ -// TSSLTools.LibSSL := 'libssl.so'; -// TSSLTools.LibCRYPTO := 'libcrypto.so'; - - TestCrossHttpServer; - Readln; -end. - +program WebSocketServer; + +{$APPTYPE CONSOLE} + +{$I zLib.inc} + +uses + SysUtils + ,Classes + ,Net.CrossSocket.Base + ,Net.CrossHttpServer + ,Net.CrossWebSocketServer + ,Net.CrossWebSocketParser + ,Net.OpenSSL + ,Utils.Utils + ; + +var + __HttpServer: ICrossWebSocketServer; + +procedure TestCrossHttpServer; +var + LResponseStr: string; +begin + __HttpServer := TCrossWebSocketServer.Create(2, True); + if __HttpServer.Ssl then + begin + __HttpServer.SetCertificateFile('server.crt'); + __HttpServer.SetPrivateKeyFile('server.key'); + end; + + __HttpServer.Port := 8090; + __HttpServer.Start( + procedure(const AListen: ICrossListen; const ASuccess: Boolean) + begin + if ASuccess then + begin + if __HttpServer.Ssl then + Writeln('WebSocket server(ssl: ' + TSSLTools.LibSSL + ' & ' + TSSLTools.LibCRYPTO + ') listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']') + else + Writeln('WebSocket server listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']'); + end; + end); + + __HttpServer.Get('/', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) + begin + LResponseStr := TOSVersion.ToString + '
Hello World!'; + AResponse.Send(LResponseStr); + AHandled := True; + end); + + __HttpServer.OnOpen( + procedure(const AConnection: ICrossWebSocketConnection) + begin + Writeln(Format('[%s : %d]Open', [AConnection.PeerAddr, AConnection.PeerPort])); + end); + + __HttpServer.OnClose( + procedure(const AConnection: ICrossWebSocketConnection) + begin + Writeln(Format('[%s : %d]Close', [AConnection.PeerAddr, AConnection.PeerPort])); + end); + + __HttpServer.OnPing( + procedure(const AConnection: ICrossWebSocketConnection) + begin + Writeln(Format('[%s : %d]Ping', [AConnection.PeerAddr, AConnection.PeerPort])); + end); + + __HttpServer.OnPong( + procedure(const AConnection: ICrossWebSocketConnection) + begin + Writeln(Format('[%s : %d]Pong', [AConnection.PeerAddr, AConnection.PeerPort])); + end); + + __HttpServer.OnMessage( + procedure(const AConnection: ICrossWebSocketConnection; + const AType: TWsMessageType; const AData: TBytes) + var + LMessage: string; + begin + if (AType = wtText) then + LMessage := TUtils.GetString(AData) + else + LMessage := TUtils.BytesToHex(AData); + + Writeln(Format('[message][%s : %d]', [AConnection.PeerAddr, AConnection.PeerPort]), LMessage); + + AConnection.WsSend('' + LMessage, + procedure(const AWsConnection: ICrossWebSocketConnection; const ASuccess: Boolean) + begin + //Writeln('ws server send response: ', ASuccess); + end); + end); +end; + +begin + // openssl пĬƲһ, ´޸ +// TSSLTools.LibSSL := 'libssl.so'; +// TSSLTools.LibCRYPTO := 'libcrypto.so'; + + TestCrossHttpServer; + Readln; +end. + diff --git a/Net/Demos/Delphi/WebSocketServer/WebSocketServer.dproj b/Net/Demos/Delphi/WebSocketServer/WebSocketServer.dproj index 816893c..22ab28a 100644 --- a/Net/Demos/Delphi/WebSocketServer/WebSocketServer.dproj +++ b/Net/Demos/Delphi/WebSocketServer/WebSocketServer.dproj @@ -1,271 +1,271 @@ - - - {4E9D11ED-6713-497F-A9A0-0B9AE1B72E0F} - WebSocketServer.dpr - True - Release - 693379 - Console - None - 19.5 - Win64 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - false - false - false - false - false - 00400000 - WebSocketServer - 2052 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - $(BDS)\bin\delphi_PROJECTICON.ico - $(BDS)\bin\delphi_PROJECTICNS.icns - bin\$(Platform)\ - ..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC;$(DCC_UnitSearchPath) - - - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png - $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png - true - true - true - true - true - true - true - true - true - true - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - - - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - - - $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png - $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png - $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png - $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png - - - $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png - - - $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png - $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png - $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png - $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - Debug - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - 1033 - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - Debug - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - 1033 - - - RELEASE;$(DCC_Define) - 0 - false - 0 - - - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - (None) - none - - - DEBUG;$(DCC_Define) - false - true - true - true - - - Debug - - - Debug - - - Debug - - - Debug - - - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - (None) - none - - - - MainSource - - - Base - - - Cfg_1 - Base - - - Cfg_2 - Base - - - - Delphi.Personality.12 - - - - - WebSocketServer.dpr - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\CEF4Delphi_FMX.bpl not found - File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\AutoUpgraderProXE10.bpl not found - File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\KastriFMX280.bpl not found - File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\CEF4Delphi.bpl not found - - - - False - True - False - True - True - False - True - False - True - True - True - True - - - 12 - - - - + + + {4E9D11ED-6713-497F-A9A0-0B9AE1B72E0F} + WebSocketServer.dpr + True + Release + 693379 + Console + None + 19.5 + Win64 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + false + false + false + false + false + 00400000 + WebSocketServer + 2052 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\delphi_PROJECTICNS.icns + bin\$(Platform)\ + ..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC;$(DCC_UnitSearchPath) + + + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + true + true + true + true + true + true + true + true + true + true + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + + + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + + + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png + $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png + $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png + + + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png + + + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png + $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png + $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) + 1033 + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + + + RELEASE;$(DCC_Define) + 0 + false + 0 + + + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + (None) + none + + + DEBUG;$(DCC_Define) + false + true + true + true + + + Debug + + + Debug + + + Debug + + + Debug + + + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) + (None) + none + + + + MainSource + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + + + + + WebSocketServer.dpr + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\CEF4Delphi_FMX.bpl not found + File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\AutoUpgraderProXE10.bpl not found + File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\KastriFMX280.bpl not found + File C:\Users\Public\Documents\Embarcadero\Studio\22.0\Bpl\CEF4Delphi.bpl not found + + + + False + True + False + True + True + False + True + False + True + True + True + True + + + 12 + + + + diff --git a/Net/Demos/Delphi/WebSocketServer/WebSocketServer.dproj.local b/Net/Demos/Delphi/WebSocketServer/WebSocketServer.dproj.local index b3811b7..d576f03 100644 --- a/Net/Demos/Delphi/WebSocketServer/WebSocketServer.dproj.local +++ b/Net/Demos/Delphi/WebSocketServer/WebSocketServer.dproj.local @@ -1,2 +1,2 @@ - - + + diff --git a/Net/Demos/FPC/HttpClient/HttpClient.lpi b/Net/Demos/FPC/HttpClient/HttpClient.lpi index ce36499..600f06c 100644 --- a/Net/Demos/FPC/HttpClient/HttpClient.lpi +++ b/Net/Demos/FPC/HttpClient/HttpClient.lpi @@ -1,229 +1,229 @@ - - - - - - - - - - - - - - <UseAppBundle Value="False"/> - <ResourceType Value="res"/> - </General> - <BuildModes> - <Item Name="Windows-X64" Default="True"/> - <Item Name="Linux-X64"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpClient"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="x86_64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="3"/> - </Optimizations> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - </CompilerOptions> - </Item> - <Item Name="Linux-ARM64"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpClient"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="aarch64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="3"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - </CompilerOptions> - </Item> - <Item Name="Linux-龙芯"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpClient"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="loongarch64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="3"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - </CompilerOptions> - </Item> - <Item Name="MacOS-ARM64"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpClient"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="aarch64"/> - <TargetOS Value="darwin"/> - <Optimizations> - <OptimizationLevel Value="3"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - </CompilerOptions> - </Item> - <Item Name="Linux-ARM64-debug"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpClient"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <TargetCPU Value="aarch64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="0"/> - </Optimizations> - </CodeGeneration> - <Linking> - <Debugging> - <UseValgrind Value="True"/> - </Debugging> - </Linking> - </CompilerOptions> - </Item> - </BuildModes> - <PublishOptions> - <Version Value="2"/> - <UseFileFilters Value="True"/> - </PublishOptions> - <RunParams> - <FormatVersion Value="2"/> - </RunParams> - <RequiredPackages> - <Item> - <PackageName Value="LazUtils"/> - </Item> - </RequiredPackages> - <Units> - <Unit> - <Filename Value="HttpClient.lpr"/> - <IsPartOfProject Value="True"/> - </Unit> - </Units> - </ProjectOptions> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpClient"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <TargetCPU Value="x86_64"/> - <TargetOS Value="win64"/> - <Optimizations> - <OptimizationLevel Value="0"/> - </Optimizations> - </CodeGeneration> - <Linking> - <Debugging> - <DebugInfoType Value="dsDwarf3"/> - <UseValgrind Value="True"/> - </Debugging> - </Linking> - <Other> - <CustomOptions Value="-k"-lssl -lcrypto -lws2_32 -ladvapi32 -lcrypt32 -lkernel32 -luser32 -lmingwex -lmsvcrt""/> - </Other> - </CompilerOptions> - <Debugging> - <Exceptions> - <Item> - <Name Value="EAbort"/> - </Item> - <Item> - <Name Value="ECodetoolError"/> - </Item> - <Item> - <Name Value="EFOpenError"/> - </Item> - </Exceptions> - </Debugging> -</CONFIG> +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectOptions> + <Version Value="12"/> + <PathDelim Value="\"/> + <General> + <Flags> + <MainUnitHasCreateFormStatements Value="False"/> + <MainUnitHasTitleStatement Value="False"/> + <MainUnitHasScaledStatement Value="False"/> + </Flags> + <SessionStorage Value="InProjectDir"/> + <Title Value="HttpClient"/> + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <BuildModes> + <Item Name="Windows-X64" Default="True"/> + <Item Name="Linux-X64"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpClient"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="x86_64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="3"/> + </Optimizations> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + </CompilerOptions> + </Item> + <Item Name="Linux-ARM64"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpClient"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="aarch64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="3"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + </CompilerOptions> + </Item> + <Item Name="Linux-龙芯"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpClient"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="loongarch64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="3"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + </CompilerOptions> + </Item> + <Item Name="MacOS-ARM64"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpClient"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="aarch64"/> + <TargetOS Value="darwin"/> + <Optimizations> + <OptimizationLevel Value="3"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + </CompilerOptions> + </Item> + <Item Name="Linux-ARM64-debug"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpClient"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <TargetCPU Value="aarch64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="0"/> + </Optimizations> + </CodeGeneration> + <Linking> + <Debugging> + <UseValgrind Value="True"/> + </Debugging> + </Linking> + </CompilerOptions> + </Item> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <RequiredPackages> + <Item> + <PackageName Value="LazUtils"/> + </Item> + </RequiredPackages> + <Units> + <Unit> + <Filename Value="HttpClient.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpClient"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <TargetCPU Value="x86_64"/> + <TargetOS Value="win64"/> + <Optimizations> + <OptimizationLevel Value="0"/> + </Optimizations> + </CodeGeneration> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf3"/> + <UseValgrind Value="True"/> + </Debugging> + </Linking> + <Other> + <CustomOptions Value="-k"-lssl -lcrypto -lws2_32 -ladvapi32 -lcrypt32 -lkernel32 -luser32 -lmingwex -lmsvcrt""/> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/Net/Demos/FPC/HttpClient/HttpClient.lpr b/Net/Demos/FPC/HttpClient/HttpClient.lpr index c02a5a1..f7e0099 100644 --- a/Net/Demos/FPC/HttpClient/HttpClient.lpr +++ b/Net/Demos/FPC/HttpClient/HttpClient.lpr @@ -1,297 +1,297 @@ -program HttpClient; - -{$I zLib.inc} - -uses - {$IFDEF UNIX} - cthreads, - {$ENDIF} - LazUTF8, - SysUtils, - Classes, - Net.CrossSocket.Base, - Net.CrossHttpClient, - Net.CrossHttpParams, - Net.CrossSslSocket.Types, - Net.CrossSslSocket.Base, - Net.CrossSslSocket.OpenSSL, - Net.OpenSSL, - Utils.Utils; - -var - __HttpCli: ICrossHttpClient; - -procedure PrintHelp; -begin - Writeln('HttpClient <url>'); -end; - -procedure PrintEntryList(const AEntryList: TArray<TEntryData>; const AIndent: string); -var - LEntryItem: TEntryData; -begin - for LEntryItem in AEntryList do - begin - Writeln(AIndent + Format('%s: %s', [ - LEntryItem.Name, - LEntryItem.Value - ])); - end; -end; - -procedure PrintExtList(const AExtList: TArray<TExtensionRawData>; const AIndent: string); -var - LExtItem: TExtensionRawData; -begin - for LExtItem in AExtList do - begin - Writeln(AIndent + 'Name: ', LExtItem.Name); - Writeln(AIndent + 'NID: ', LExtItem.NID); - Writeln(AIndent + 'OID: ', LExtItem.OID); - Writeln(AIndent + 'Critical: ', BoolToStr(LExtItem.Critical, True)); - Writeln(AIndent + 'Value: ', TUtils.BytesToHex(LExtItem.Value)); - Writeln; - end; -end; - -procedure PrintGeneralName(const AName: TGeneralName; const AIndent: string); -begin - Writeln(AIndent + 'TypeID: ', AName.TypeID); - Writeln(AIndent + 'TypeName: ', AName.TypeName); - Writeln(AIndent + 'Value: ', AName.Value); -end; - -procedure PrintGeneralNameList(const ANameList: TArray<TGeneralName>; const AIndent: string); -var - LNameItem: TGeneralName; -begin - for LNameItem in ANameList do - begin - PrintGeneralName(LNameItem, AIndent); - Writeln; - end; -end; - -procedure PrintCrlDistPointList(const ACrlDistPointList: TArray<TCrlDistPoint>; const AIndent: string); -var - LCrlDistPointItem: TCrlDistPoint; -begin - for LCrlDistPointItem in ACrlDistPointList do - begin - Writeln(AIndent + 'Reasons: ', LCrlDistPointItem.Reasons); - Writeln(AIndent + 'DpReasons: ', LCrlDistPointItem.DpReasons); - - Writeln(AIndent + 'DistPoint:'); - PrintGeneralNameList(LCrlDistPointItem.DistPoint, AIndent + ' '); - - Writeln(AIndent + 'CRLissuer:'); - PrintGeneralNameList(LCrlDistPointItem.CRLissuer, AIndent + ' '); - - Writeln; - end; -end; - -procedure PrintAuthorityInfoAccesses(const AAuthorityInfoAccesses: TArray<TAuthorityInfoAccess>; const AIndent: string); -var - LAuthorityInfoAccessItem: TAuthorityInfoAccess; -begin - for LAuthorityInfoAccessItem in AAuthorityInfoAccesses do - begin - Writeln(AIndent + 'Method: ', LAuthorityInfoAccessItem.Method); - Writeln(AIndent + 'MethodDesc: ', LAuthorityInfoAccessItem.MethodDesc); - - Writeln(AIndent + 'Location:'); - PrintGeneralName(LAuthorityInfoAccessItem.Location, AIndent + ' '); - - Writeln; - end; -end; - -procedure PrintSctList(const ASctList: TArray<TSct>; const AIndent: string); -var - LSctItem: TSct; -begin - for LSctItem in ASctList do - begin - Writeln(AIndent + 'Version: ', LSctItem.Version); - Writeln(AIndent + 'Sct: ', TUtils.BytesToHex(LSctItem.Sct)); - Writeln(AIndent + 'LogID: ', TUtils.BytesToHex(LSctItem.LogID)); - Writeln(AIndent + 'Timestamp: ', LSctItem.Timestamp); - Writeln(AIndent + 'Ext: ', TUtils.BytesToHex(LSctItem.Ext)); - Writeln(AIndent + 'HashAlg: ', LSctItem.HashAlg); - Writeln(AIndent + 'SigAlg: ', LSctItem.SigAlg); - Writeln(AIndent + 'Sig: ', TUtils.BytesToHex(LSctItem.Sig)); - Writeln(AIndent + 'EntryType: ', LSctItem.EntryType); - Writeln(AIndent + 'Source: ', LSctItem.Source); - Writeln(AIndent + 'ValidationStatus: ', LSctItem.ValidationStatus); - - Writeln; - end; -end; - -procedure PrintBasicConstraints(const ABasicConstraints: TBasicConstraints; const AIndent: string); -begin - Writeln(AIndent + 'CA: ', ABasicConstraints.CA); - Writeln(AIndent + 'PathLen: ', ABasicConstraints.PathLen); -end; - -procedure PringExtKeyUsage(const AExtKeyUsage: TExtKeyUsage; const AIndent: string); -var - LExtKeyUsageItem: TExtKeyUsageItem; -begin - Writeln(AIndent + Format('Flags: 0x%x', [AExtKeyUsage.Flags])); - Writeln; - for LExtKeyUsageItem in AExtKeyUsage.List do - begin - Writeln(AIndent + 'NID: ', LExtKeyUsageItem.NID); - Writeln(AIndent + 'OID: ', LExtKeyUsageItem.OID); - Writeln(AIndent + 'Value: ', LExtKeyUsageItem.Value); - Writeln; - end; -end; - -procedure PrintSslInfo(const ASslInfo: TSslInfo); -begin - Writeln(Format('TLS Server Name: %s', [ - ASslInfo.HostName - ])); - - Writeln(Format('SSL/TLS Protocol: %s,%s,%d,%d', [ - ASslInfo.SslVersion, - ASslInfo.CurrentCipher, - ASslInfo.CertInfo.PubKeyBits, - ASslInfo.CurrentCipherBits - ])); - - Writeln(Format('Server Temp Key: %s %d bits', [ - ASslInfo.TmpKeyType, - ASslInfo.TmpKeyBits - ])); - - Writeln(Format('Public Key: %s %d bits', [ - ASslInfo.CertInfo.PubKeyType, - ASslInfo.CertInfo.PubKeyBits - ])); - - Writeln('Signature Algorithm: ', ASslInfo.CertInfo.SigAlg); - - Writeln(Format('CertVersion: %d', [ - ASslInfo.CertInfo.Version + 1 - ])); - - Writeln(Format('Serial Number: %s', [ - TUtils.BytesToHex(ASslInfo.CertInfo.SerialNumber) - ])); - - Writeln(Format('Expiration Date: %s - %s', [ - FormatDateTime('yyyy-mm-dd hh:nn:ss', ASslInfo.CertInfo.NotBefore), - FormatDateTime('yyyy-mm-dd hh:nn:ss', ASslInfo.CertInfo.NotAfter) - ])); - - Writeln; - - Writeln('Subject:'); - PrintEntryList(ASslInfo.CertInfo.Subject, ' '); - Writeln; - - Writeln('Issuer:'); - PrintEntryList(ASslInfo.CertInfo.Issuer, ' '); - Writeln; - - Writeln('SHA256Digest:'); - Writeln(Format(' Certificate: %s', [ - TUtils.BytesToHex(ASslInfo.CertInfo.SHA256Digest) - ])); - Writeln(Format(' Public Key: %s', [ - TUtils.BytesToHex(ASslInfo.CertInfo.PubKeySHA256Digest) - ])); - Writeln; - - Writeln('Extension:'); - Writeln(' AuthorityKeyID: ', TUtils.BytesToHex(ASslInfo.CertInfo.Extension.AuthorityKeyID)); - Writeln(' SubjectKeyID: ', TUtils.BytesToHex(ASslInfo.CertInfo.Extension.SubjectKeyID)); - Writeln(Format(' Key Usage: 0x%x', [ASslInfo.CertInfo.Extension.KeyUsage])); - - Writeln(' Alt Names:'); - PrintGeneralNameList(ASslInfo.CertInfo.Extension.AltNames, ' '); - - Writeln(' Crl Dist Points:'); - PrintCrlDistPointList(ASslInfo.CertInfo.Extension.CrlDistPoints, ' '); - - Writeln(' Authority Info Accesses:'); - PrintAuthorityInfoAccesses(ASslInfo.CertInfo.Extension.AuthorityInfoAccesses, ' '); - - Writeln(' Basic Constraints:'); - PrintBasicConstraints(ASslInfo.CertInfo.Extension.BasicConstraints, ' '); - Writeln; - - Writeln(' ExtKey Usage:'); - PringExtKeyUsage(ASslInfo.CertInfo.Extension.ExtKeyUsage, ' '); - - Writeln(' Sct List:'); - PrintSctList(ASslInfo.CertInfo.Extension.SctList, ' '); - - Writeln(' RawData:'); - PrintExtList(ASslInfo.CertInfo.Extension.RawData, ' '); - - Writeln('Cert PEM:' + sLineBreak, ASslInfo.CertInfo.PEM); - Writeln('Cert DER:' + sLineBreak, TUtils.BytesToHex(ASslInfo.CertInfo.DER)); - - Writeln; -end; - -procedure TestHttpCli; -var - LUrl: string; -begin - LUrl := ParamStr(1); - if (LUrl = '') then - begin - PrintHelp(); - Exit; - end; - - if (__HttpCli = nil) then - __HttpCli := TCrossHttpClient.Create; - -// __HttpCli.LocalPort := 1111; - __HttpCli.AutoUrlEncode := False; - __HttpCli.DoRequest('GET', LUrl, nil, nil, 0, - nil, - procedure(const ARequest: ICrossHttpClientRequest) - begin -// ARequest.Header['User-Agent'] := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'; - end, - procedure(const AResponse: ICrossHttpClientResponse) - var - LSslConnection: ICrossSslConnection; - LSslInfo: TSslInfo; - begin - if (AResponse <> nil) and (AResponse.Content <> nil) then - begin - LSslConnection := AResponse.Connection as ICrossSslConnection; - - if LSslConnection.Ssl and LSslConnection.GetSslInfo(LSslInfo) then - PrintSslInfo(LSslInfo); - - Writeln('HTTP GET success'); - Writeln(AResponse.StatusCode, ' ', AResponse.StatusText); - Writeln(AResponse.Header.Encode); - Writeln(TUtils.GetString(AResponse.Content)); - end else - Writeln('HTTP GET failed'); - end); -end; - -begin - // 如果 openssl 运行库名称与默认名称不一致, 请自行用以下代码修改 - // TSSLTools.LibSSL := 'libssl.so'; - // TSSLTools.LibCRYPTO := 'libcrypto.so'; - -// ReportMemoryLeaksOnShutdown := True; - - CrossSocketLogEnabled := False; - TestHttpCli; - Readln; -end. - +program HttpClient; + +{$I zLib.inc} + +uses + {$IFDEF UNIX} + cthreads, + {$ENDIF} + LazUTF8, + SysUtils, + Classes, + Net.CrossSocket.Base, + Net.CrossHttpClient, + Net.CrossHttpParams, + Net.CrossSslSocket.Types, + Net.CrossSslSocket.Base, + Net.CrossSslSocket.OpenSSL, + Net.OpenSSL, + Utils.Utils; + +var + __HttpCli: ICrossHttpClient; + +procedure PrintHelp; +begin + Writeln('HttpClient <url>'); +end; + +procedure PrintEntryList(const AEntryList: TArray<TEntryData>; const AIndent: string); +var + LEntryItem: TEntryData; +begin + for LEntryItem in AEntryList do + begin + Writeln(AIndent + Format('%s: %s', [ + LEntryItem.Name, + LEntryItem.Value + ])); + end; +end; + +procedure PrintExtList(const AExtList: TArray<TExtensionRawData>; const AIndent: string); +var + LExtItem: TExtensionRawData; +begin + for LExtItem in AExtList do + begin + Writeln(AIndent + 'Name: ', LExtItem.Name); + Writeln(AIndent + 'NID: ', LExtItem.NID); + Writeln(AIndent + 'OID: ', LExtItem.OID); + Writeln(AIndent + 'Critical: ', BoolToStr(LExtItem.Critical, True)); + Writeln(AIndent + 'Value: ', TUtils.BytesToHex(LExtItem.Value)); + Writeln; + end; +end; + +procedure PrintGeneralName(const AName: TGeneralName; const AIndent: string); +begin + Writeln(AIndent + 'TypeID: ', AName.TypeID); + Writeln(AIndent + 'TypeName: ', AName.TypeName); + Writeln(AIndent + 'Value: ', AName.Value); +end; + +procedure PrintGeneralNameList(const ANameList: TArray<TGeneralName>; const AIndent: string); +var + LNameItem: TGeneralName; +begin + for LNameItem in ANameList do + begin + PrintGeneralName(LNameItem, AIndent); + Writeln; + end; +end; + +procedure PrintCrlDistPointList(const ACrlDistPointList: TArray<TCrlDistPoint>; const AIndent: string); +var + LCrlDistPointItem: TCrlDistPoint; +begin + for LCrlDistPointItem in ACrlDistPointList do + begin + Writeln(AIndent + 'Reasons: ', LCrlDistPointItem.Reasons); + Writeln(AIndent + 'DpReasons: ', LCrlDistPointItem.DpReasons); + + Writeln(AIndent + 'DistPoint:'); + PrintGeneralNameList(LCrlDistPointItem.DistPoint, AIndent + ' '); + + Writeln(AIndent + 'CRLissuer:'); + PrintGeneralNameList(LCrlDistPointItem.CRLissuer, AIndent + ' '); + + Writeln; + end; +end; + +procedure PrintAuthorityInfoAccesses(const AAuthorityInfoAccesses: TArray<TAuthorityInfoAccess>; const AIndent: string); +var + LAuthorityInfoAccessItem: TAuthorityInfoAccess; +begin + for LAuthorityInfoAccessItem in AAuthorityInfoAccesses do + begin + Writeln(AIndent + 'Method: ', LAuthorityInfoAccessItem.Method); + Writeln(AIndent + 'MethodDesc: ', LAuthorityInfoAccessItem.MethodDesc); + + Writeln(AIndent + 'Location:'); + PrintGeneralName(LAuthorityInfoAccessItem.Location, AIndent + ' '); + + Writeln; + end; +end; + +procedure PrintSctList(const ASctList: TArray<TSct>; const AIndent: string); +var + LSctItem: TSct; +begin + for LSctItem in ASctList do + begin + Writeln(AIndent + 'Version: ', LSctItem.Version); + Writeln(AIndent + 'Sct: ', TUtils.BytesToHex(LSctItem.Sct)); + Writeln(AIndent + 'LogID: ', TUtils.BytesToHex(LSctItem.LogID)); + Writeln(AIndent + 'Timestamp: ', LSctItem.Timestamp); + Writeln(AIndent + 'Ext: ', TUtils.BytesToHex(LSctItem.Ext)); + Writeln(AIndent + 'HashAlg: ', LSctItem.HashAlg); + Writeln(AIndent + 'SigAlg: ', LSctItem.SigAlg); + Writeln(AIndent + 'Sig: ', TUtils.BytesToHex(LSctItem.Sig)); + Writeln(AIndent + 'EntryType: ', LSctItem.EntryType); + Writeln(AIndent + 'Source: ', LSctItem.Source); + Writeln(AIndent + 'ValidationStatus: ', LSctItem.ValidationStatus); + + Writeln; + end; +end; + +procedure PrintBasicConstraints(const ABasicConstraints: TBasicConstraints; const AIndent: string); +begin + Writeln(AIndent + 'CA: ', ABasicConstraints.CA); + Writeln(AIndent + 'PathLen: ', ABasicConstraints.PathLen); +end; + +procedure PringExtKeyUsage(const AExtKeyUsage: TExtKeyUsage; const AIndent: string); +var + LExtKeyUsageItem: TExtKeyUsageItem; +begin + Writeln(AIndent + Format('Flags: 0x%x', [AExtKeyUsage.Flags])); + Writeln; + for LExtKeyUsageItem in AExtKeyUsage.List do + begin + Writeln(AIndent + 'NID: ', LExtKeyUsageItem.NID); + Writeln(AIndent + 'OID: ', LExtKeyUsageItem.OID); + Writeln(AIndent + 'Value: ', LExtKeyUsageItem.Value); + Writeln; + end; +end; + +procedure PrintSslInfo(const ASslInfo: TSslInfo); +begin + Writeln(Format('TLS Server Name: %s', [ + ASslInfo.HostName + ])); + + Writeln(Format('SSL/TLS Protocol: %s,%s,%d,%d', [ + ASslInfo.SslVersion, + ASslInfo.CurrentCipher, + ASslInfo.CertInfo.PubKeyBits, + ASslInfo.CurrentCipherBits + ])); + + Writeln(Format('Server Temp Key: %s %d bits', [ + ASslInfo.TmpKeyType, + ASslInfo.TmpKeyBits + ])); + + Writeln(Format('Public Key: %s %d bits', [ + ASslInfo.CertInfo.PubKeyType, + ASslInfo.CertInfo.PubKeyBits + ])); + + Writeln('Signature Algorithm: ', ASslInfo.CertInfo.SigAlg); + + Writeln(Format('CertVersion: %d', [ + ASslInfo.CertInfo.Version + 1 + ])); + + Writeln(Format('Serial Number: %s', [ + TUtils.BytesToHex(ASslInfo.CertInfo.SerialNumber) + ])); + + Writeln(Format('Expiration Date: %s - %s', [ + FormatDateTime('yyyy-mm-dd hh:nn:ss', ASslInfo.CertInfo.NotBefore), + FormatDateTime('yyyy-mm-dd hh:nn:ss', ASslInfo.CertInfo.NotAfter) + ])); + + Writeln; + + Writeln('Subject:'); + PrintEntryList(ASslInfo.CertInfo.Subject, ' '); + Writeln; + + Writeln('Issuer:'); + PrintEntryList(ASslInfo.CertInfo.Issuer, ' '); + Writeln; + + Writeln('SHA256Digest:'); + Writeln(Format(' Certificate: %s', [ + TUtils.BytesToHex(ASslInfo.CertInfo.SHA256Digest) + ])); + Writeln(Format(' Public Key: %s', [ + TUtils.BytesToHex(ASslInfo.CertInfo.PubKeySHA256Digest) + ])); + Writeln; + + Writeln('Extension:'); + Writeln(' AuthorityKeyID: ', TUtils.BytesToHex(ASslInfo.CertInfo.Extension.AuthorityKeyID)); + Writeln(' SubjectKeyID: ', TUtils.BytesToHex(ASslInfo.CertInfo.Extension.SubjectKeyID)); + Writeln(Format(' Key Usage: 0x%x', [ASslInfo.CertInfo.Extension.KeyUsage])); + + Writeln(' Alt Names:'); + PrintGeneralNameList(ASslInfo.CertInfo.Extension.AltNames, ' '); + + Writeln(' Crl Dist Points:'); + PrintCrlDistPointList(ASslInfo.CertInfo.Extension.CrlDistPoints, ' '); + + Writeln(' Authority Info Accesses:'); + PrintAuthorityInfoAccesses(ASslInfo.CertInfo.Extension.AuthorityInfoAccesses, ' '); + + Writeln(' Basic Constraints:'); + PrintBasicConstraints(ASslInfo.CertInfo.Extension.BasicConstraints, ' '); + Writeln; + + Writeln(' ExtKey Usage:'); + PringExtKeyUsage(ASslInfo.CertInfo.Extension.ExtKeyUsage, ' '); + + Writeln(' Sct List:'); + PrintSctList(ASslInfo.CertInfo.Extension.SctList, ' '); + + Writeln(' RawData:'); + PrintExtList(ASslInfo.CertInfo.Extension.RawData, ' '); + + Writeln('Cert PEM:' + sLineBreak, ASslInfo.CertInfo.PEM); + Writeln('Cert DER:' + sLineBreak, TUtils.BytesToHex(ASslInfo.CertInfo.DER)); + + Writeln; +end; + +procedure TestHttpCli; +var + LUrl: string; +begin + LUrl := ParamStr(1); + if (LUrl = '') then + begin + PrintHelp(); + Exit; + end; + + if (__HttpCli = nil) then + __HttpCli := TCrossHttpClient.Create; + +// __HttpCli.LocalPort := 1111; + __HttpCli.AutoUrlEncode := False; + __HttpCli.DoRequest('GET', LUrl, nil, nil, 0, + nil, + procedure(const ARequest: ICrossHttpClientRequest) + begin +// ARequest.Header['User-Agent'] := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'; + end, + procedure(const AResponse: ICrossHttpClientResponse) + var + LSslConnection: ICrossSslConnection; + LSslInfo: TSslInfo; + begin + if (AResponse <> nil) and (AResponse.Content <> nil) then + begin + LSslConnection := AResponse.Connection as ICrossSslConnection; + + if LSslConnection.Ssl and LSslConnection.GetSslInfo(LSslInfo) then + PrintSslInfo(LSslInfo); + + Writeln('HTTP GET success'); + Writeln(AResponse.StatusCode, ' ', AResponse.StatusText); + Writeln(AResponse.Header.Encode); + Writeln(TUtils.GetString(AResponse.Content)); + end else + Writeln('HTTP GET failed'); + end); +end; + +begin + // 如果 openssl 运行库名称与默认名称不一致, 请自行用以下代码修改 + // TSSLTools.LibSSL := 'libssl.so'; + // TSSLTools.LibCRYPTO := 'libcrypto.so'; + +// ReportMemoryLeaksOnShutdown := True; + + CrossSocketLogEnabled := False; + TestHttpCli; + Readln; +end. + diff --git a/Net/Demos/FPC/HttpClient/HttpClient.lps b/Net/Demos/FPC/HttpClient/HttpClient.lps index 6d736b9..e43421a 100644 --- a/Net/Demos/FPC/HttpClient/HttpClient.lps +++ b/Net/Demos/FPC/HttpClient/HttpClient.lps @@ -1,259 +1,259 @@ -<?xml version="1.0" encoding="UTF-8"?> -<CONFIG> - <ProjectSession> - <PathDelim Value="\"/> - <Version Value="12"/> - <BuildModes Active="Linux-ARM64"/> - <Units> - <Unit> - <Filename Value="HttpClient.lpr"/> - <IsPartOfProject Value="True"/> - <TopLine Value="251"/> - <CursorPos X="69" Y="274"/> - <UsageCount Value="145"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.OpenSSL.pas"/> - <EditorIndex Value="-1"/> - <TopLine Value="31"/> - <CursorPos X="44" Y="45"/> - <UsageCount Value="14"/> - <Bookmarks Count="3"> - <Item0 X="33" Y="2932" Left="1" Top="2888" ID="3"/> - <Item1 X="10" Y="3096" Left="1" Top="3057" ID="1"/> - <Item2 X="31" Y="3251" Left="1" Top="3221" ID="2"/> - </Bookmarks> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> - <EditorIndex Value="8"/> - <UsageCount Value="65"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <EditorIndex Value="1"/> - <TopLine Value="7"/> - <CursorPos X="40" Y="37"/> - <UsageCount Value="29"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal.Beta\fpcsrc\packages\hash\tests\tsha1test.pp"/> - <UnitName Value="sha1test"/> - <EditorIndex Value="21"/> - <CursorPos X="16" Y="10"/> - <UsageCount Value="70"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\packages\hash\src\sha1.pp"/> - <EditorIndex Value="22"/> - <TopLine Value="271"/> - <CursorPos X="7" Y="24"/> - <UsageCount Value="70"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\packages\hash\src\md5.pp"/> - <EditorIndex Value="23"/> - <UsageCount Value="70"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> - <EditorIndex Value="18"/> - <CursorPos Y="78"/> - <UsageCount Value="70"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\cnvcl\Source\Crypto\CnSHA1.pas"/> - <EditorIndex Value="20"/> - <TopLine Value="16"/> - <UsageCount Value="70"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\cnvcl\Source\Crypto\CnSHA2.pas"/> - <EditorIndex Value="19"/> - <TopLine Value="1487"/> - <UsageCount Value="70"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="F:\Download\source-main\source-main\packages\fcl-hash\src\fphashutils.pp"/> - <EditorIndex Value="-1"/> - <TopLine Value="19"/> - <UsageCount Value="4"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.SocketAPI.pas"/> - <EditorIndex Value="9"/> - <TopLine Value="158"/> - <CursorPos X="36" Y="165"/> - <UsageCount Value="70"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysmarshalh.inc"/> - <EditorIndex Value="17"/> - <CursorPos X="3" Y="3"/> - <UsageCount Value="70"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\inc\objpash.inc"/> - <EditorIndex Value="15"/> - <TopLine Value="771"/> - <CursorPos X="23" Y="787"/> - <UsageCount Value="70"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\win\sysutils.pp"/> - <UnitName Value="SysUtils"/> - <EditorIndex Value="14"/> - <UsageCount Value="70"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\Utils\Utils.Rtti.pas"/> - <EditorIndex Value="3"/> - <CursorPos X="15" Y="4"/> - <UsageCount Value="62"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\packages\libffi\src\ffi.manager.pp"/> - <EditorIndex Value="4"/> - <UsageCount Value="59"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\packages\libffi\src\ffi.pp"/> - <IsVisibleTab Value="True"/> - <EditorIndex Value="5"/> - <TopLine Value="581"/> - <CursorPos X="10" Y="588"/> - <UsageCount Value="59"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSocket.Epoll.pas"/> - <EditorIndex Value="6"/> - <TopLine Value="729"/> - <CursorPos Y="727"/> - <UsageCount Value="58"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\packages\rtl-extra\src\inc\socketsh.inc"/> - <EditorIndex Value="13"/> - <TopLine Value="45"/> - <CursorPos X="14" Y="70"/> - <UsageCount Value="57"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSocket.Kqueue.pas"/> - <EditorIndex Value="7"/> - <TopLine Value="756"/> - <CursorPos X="60" Y="788"/> - <UsageCount Value="55"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysmarshal.inc"/> - <EditorIndex Value="12"/> - <TopLine Value="204"/> - <CursorPos X="3" Y="238"/> - <UsageCount Value="54"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\inc\objpas.inc"/> - <EditorIndex Value="16"/> - <TopLine Value="1483"/> - <CursorPos X="3" Y="1490"/> - <UsageCount Value="54"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\unix\baseunix.pp"/> - <EditorIndex Value="10"/> - <CursorPos X="27" Y="11"/> - <UsageCount Value="54"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\linux\errno.inc"/> - <EditorIndex Value="11"/> - <UsageCount Value="54"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSslSocket.Types.pas"/> - <EditorIndex Value="2"/> - <TopLine Value="154"/> - <CursorPos X="3" Y="163"/> - <UsageCount Value="25"/> - <Loaded Value="True"/> - </Unit> - </Units> - <JumpHistory HistoryIndex="8"> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.Types.pas"/> - <Caret Line="163" Column="3" TopLine="154"/> - </Position> - <Position> - <Filename Value="HttpClient.lpr"/> - <Caret Line="297" TopLine="250"/> - </Position> - <Position> - <Filename Value="HttpClient.lpr"/> - <Caret Line="17" Column="3"/> - </Position> - <Position> - <Filename Value="HttpClient.lpr"/> - <Caret Line="268" Column="51" TopLine="251"/> - </Position> - <Position> - <Filename Value="HttpClient.lpr"/> - <Caret Line="297" TopLine="250"/> - </Position> - <Position> - <Filename Value="HttpClient.lpr"/> - <Caret Line="35" Column="23" TopLine="11"/> - </Position> - <Position> - <Filename Value="HttpClient.lpr"/> - <Caret Line="261" Column="21" TopLine="237"/> - </Position> - <Position> - <Filename Value="HttpClient.lpr"/> - <Caret Line="274" Column="69" TopLine="251"/> - </Position> - <Position> - <Filename Value="HttpClient.lpr"/> - <Caret Line="261" Column="21" TopLine="237"/> - </Position> - </JumpHistory> - <RunParams> - <FormatVersion Value="2"/> - <Modes ActiveMode=""/> - </RunParams> - </ProjectSession> - <Debugging> - <BreakPoints> - <Item> - <Kind Value="bpkSource"/> - <WatchScope Value="wpsLocal"/> - <WatchKind Value="wpkWrite"/> - <Source Value="..\..\..\Net.OpenSSL.pas"/> - <Line Value="2025"/> - </Item> - </BreakPoints> - </Debugging> -</CONFIG> +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectSession> + <PathDelim Value="\"/> + <Version Value="12"/> + <BuildModes Active="Linux-ARM64"/> + <Units> + <Unit> + <Filename Value="HttpClient.lpr"/> + <IsPartOfProject Value="True"/> + <TopLine Value="251"/> + <CursorPos X="69" Y="274"/> + <UsageCount Value="145"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.OpenSSL.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="31"/> + <CursorPos X="44" Y="45"/> + <UsageCount Value="14"/> + <Bookmarks Count="3"> + <Item0 X="33" Y="2932" Left="1" Top="2888" ID="3"/> + <Item1 X="10" Y="3096" Left="1" Top="3057" ID="1"/> + <Item2 X="31" Y="3251" Left="1" Top="3221" ID="2"/> + </Bookmarks> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> + <EditorIndex Value="8"/> + <UsageCount Value="65"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <EditorIndex Value="1"/> + <TopLine Value="7"/> + <CursorPos X="40" Y="37"/> + <UsageCount Value="29"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal.Beta\fpcsrc\packages\hash\tests\tsha1test.pp"/> + <UnitName Value="sha1test"/> + <EditorIndex Value="21"/> + <CursorPos X="16" Y="10"/> + <UsageCount Value="70"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\packages\hash\src\sha1.pp"/> + <EditorIndex Value="22"/> + <TopLine Value="271"/> + <CursorPos X="7" Y="24"/> + <UsageCount Value="70"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\packages\hash\src\md5.pp"/> + <EditorIndex Value="23"/> + <UsageCount Value="70"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> + <EditorIndex Value="18"/> + <CursorPos Y="78"/> + <UsageCount Value="70"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\cnvcl\Source\Crypto\CnSHA1.pas"/> + <EditorIndex Value="20"/> + <TopLine Value="16"/> + <UsageCount Value="70"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\cnvcl\Source\Crypto\CnSHA2.pas"/> + <EditorIndex Value="19"/> + <TopLine Value="1487"/> + <UsageCount Value="70"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="F:\Download\source-main\source-main\packages\fcl-hash\src\fphashutils.pp"/> + <EditorIndex Value="-1"/> + <TopLine Value="19"/> + <UsageCount Value="4"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.SocketAPI.pas"/> + <EditorIndex Value="9"/> + <TopLine Value="158"/> + <CursorPos X="36" Y="165"/> + <UsageCount Value="70"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysmarshalh.inc"/> + <EditorIndex Value="17"/> + <CursorPos X="3" Y="3"/> + <UsageCount Value="70"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\inc\objpash.inc"/> + <EditorIndex Value="15"/> + <TopLine Value="771"/> + <CursorPos X="23" Y="787"/> + <UsageCount Value="70"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\win\sysutils.pp"/> + <UnitName Value="SysUtils"/> + <EditorIndex Value="14"/> + <UsageCount Value="70"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\Utils\Utils.Rtti.pas"/> + <EditorIndex Value="3"/> + <CursorPos X="15" Y="4"/> + <UsageCount Value="62"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\packages\libffi\src\ffi.manager.pp"/> + <EditorIndex Value="4"/> + <UsageCount Value="59"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\packages\libffi\src\ffi.pp"/> + <IsVisibleTab Value="True"/> + <EditorIndex Value="5"/> + <TopLine Value="581"/> + <CursorPos X="10" Y="588"/> + <UsageCount Value="59"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSocket.Epoll.pas"/> + <EditorIndex Value="6"/> + <TopLine Value="729"/> + <CursorPos Y="727"/> + <UsageCount Value="58"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\packages\rtl-extra\src\inc\socketsh.inc"/> + <EditorIndex Value="13"/> + <TopLine Value="45"/> + <CursorPos X="14" Y="70"/> + <UsageCount Value="57"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSocket.Kqueue.pas"/> + <EditorIndex Value="7"/> + <TopLine Value="756"/> + <CursorPos X="60" Y="788"/> + <UsageCount Value="55"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysmarshal.inc"/> + <EditorIndex Value="12"/> + <TopLine Value="204"/> + <CursorPos X="3" Y="238"/> + <UsageCount Value="54"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\inc\objpas.inc"/> + <EditorIndex Value="16"/> + <TopLine Value="1483"/> + <CursorPos X="3" Y="1490"/> + <UsageCount Value="54"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\unix\baseunix.pp"/> + <EditorIndex Value="10"/> + <CursorPos X="27" Y="11"/> + <UsageCount Value="54"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\linux\errno.inc"/> + <EditorIndex Value="11"/> + <UsageCount Value="54"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSslSocket.Types.pas"/> + <EditorIndex Value="2"/> + <TopLine Value="154"/> + <CursorPos X="3" Y="163"/> + <UsageCount Value="25"/> + <Loaded Value="True"/> + </Unit> + </Units> + <JumpHistory HistoryIndex="8"> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.Types.pas"/> + <Caret Line="163" Column="3" TopLine="154"/> + </Position> + <Position> + <Filename Value="HttpClient.lpr"/> + <Caret Line="297" TopLine="250"/> + </Position> + <Position> + <Filename Value="HttpClient.lpr"/> + <Caret Line="17" Column="3"/> + </Position> + <Position> + <Filename Value="HttpClient.lpr"/> + <Caret Line="268" Column="51" TopLine="251"/> + </Position> + <Position> + <Filename Value="HttpClient.lpr"/> + <Caret Line="297" TopLine="250"/> + </Position> + <Position> + <Filename Value="HttpClient.lpr"/> + <Caret Line="35" Column="23" TopLine="11"/> + </Position> + <Position> + <Filename Value="HttpClient.lpr"/> + <Caret Line="261" Column="21" TopLine="237"/> + </Position> + <Position> + <Filename Value="HttpClient.lpr"/> + <Caret Line="274" Column="69" TopLine="251"/> + </Position> + <Position> + <Filename Value="HttpClient.lpr"/> + <Caret Line="261" Column="21" TopLine="237"/> + </Position> + </JumpHistory> + <RunParams> + <FormatVersion Value="2"/> + <Modes ActiveMode=""/> + </RunParams> + </ProjectSession> + <Debugging> + <BreakPoints> + <Item> + <Kind Value="bpkSource"/> + <WatchScope Value="wpsLocal"/> + <WatchKind Value="wpkWrite"/> + <Source Value="..\..\..\Net.OpenSSL.pas"/> + <Line Value="2025"/> + </Item> + </BreakPoints> + </Debugging> +</CONFIG> diff --git a/Net/Demos/FPC/HttpServer/HttpServer.lpi b/Net/Demos/FPC/HttpServer/HttpServer.lpi index 3b5e623..2455a95 100644 --- a/Net/Demos/FPC/HttpServer/HttpServer.lpi +++ b/Net/Demos/FPC/HttpServer/HttpServer.lpi @@ -1,230 +1,230 @@ -<?xml version="1.0" encoding="UTF-8"?> -<CONFIG> - <ProjectOptions> - <Version Value="12"/> - <PathDelim Value="\"/> - <General> - <Flags> - <MainUnitHasCreateFormStatements Value="False"/> - <MainUnitHasTitleStatement Value="False"/> - <MainUnitHasScaledStatement Value="False"/> - </Flags> - <SessionStorage Value="InProjectDir"/> - <Title Value="HttpServer"/> - <UseAppBundle Value="False"/> - <ResourceType Value="res"/> - </General> - <BuildModes> - <Item Name="Windows-X64" Default="True"/> - <Item Name="Linux-X64"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpServer"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="x86_64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - <CustomOptions Value="-d__DEBUG__"/> - </Other> - </CompilerOptions> - </Item> - <Item Name="Linux-ARM64"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpServer"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="aarch64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - </Other> - </CompilerOptions> - </Item> - <Item Name="Linux-龙芯"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpServer"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="loongarch64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - </Other> - </CompilerOptions> - </Item> - <Item Name="MacOS-ARM64"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpServer"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="aarch64"/> - <TargetOS Value="darwin"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - </Other> - </CompilerOptions> - </Item> - </BuildModes> - <PublishOptions> - <Version Value="2"/> - <UseFileFilters Value="True"/> - </PublishOptions> - <RunParams> - <FormatVersion Value="2"/> - </RunParams> - <Units> - <Unit> - <Filename Value="HttpServer.lpr"/> - <IsPartOfProject Value="True"/> - </Unit> - </Units> - </ProjectOptions> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpServer"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="x86_64"/> - <TargetOS Value="win64"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - <CustomOptions Value="-d__DEBUG__"/> - <OtherDefines Count="1"> - <Define0 Value="__DEBUG__"/> - </OtherDefines> - </Other> - </CompilerOptions> - <Debugging> - <Exceptions> - <Item> - <Name Value="EAbort"/> - </Item> - <Item> - <Name Value="ECodetoolError"/> - </Item> - <Item> - <Name Value="EFOpenError"/> - </Item> - </Exceptions> - </Debugging> -</CONFIG> +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectOptions> + <Version Value="12"/> + <PathDelim Value="\"/> + <General> + <Flags> + <MainUnitHasCreateFormStatements Value="False"/> + <MainUnitHasTitleStatement Value="False"/> + <MainUnitHasScaledStatement Value="False"/> + </Flags> + <SessionStorage Value="InProjectDir"/> + <Title Value="HttpServer"/> + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <BuildModes> + <Item Name="Windows-X64" Default="True"/> + <Item Name="Linux-X64"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpServer"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="x86_64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + <CustomOptions Value="-d__DEBUG__"/> + </Other> + </CompilerOptions> + </Item> + <Item Name="Linux-ARM64"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpServer"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="aarch64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + </Other> + </CompilerOptions> + </Item> + <Item Name="Linux-龙芯"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpServer"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="loongarch64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + </Other> + </CompilerOptions> + </Item> + <Item Name="MacOS-ARM64"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpServer"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="aarch64"/> + <TargetOS Value="darwin"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + </Other> + </CompilerOptions> + </Item> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <Units> + <Unit> + <Filename Value="HttpServer.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\HttpServer"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="x86_64"/> + <TargetOS Value="win64"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + <CustomOptions Value="-d__DEBUG__"/> + <OtherDefines Count="1"> + <Define0 Value="__DEBUG__"/> + </OtherDefines> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/Net/Demos/FPC/HttpServer/HttpServer.lpr b/Net/Demos/FPC/HttpServer/HttpServer.lpr index bf45255..0584a92 100644 --- a/Net/Demos/FPC/HttpServer/HttpServer.lpr +++ b/Net/Demos/FPC/HttpServer/HttpServer.lpr @@ -1,95 +1,95 @@ -program HttpServer; - -{$I zLib.inc} - -uses - {$IFDEF UNIX} - cthreads, - {$ENDIF} - LazUTF8 - ,SysUtils - ,Classes - ,Net.CrossSocket.Base - ,Net.CrossHttpServer - ,Net.CrossHttpParams - ,Net.OpenSSL - ,Utils.Utils - ,Utils.Hash - ; - -const - OSVersion: string = {$I %FPCTARGETOS%} + '-' + {$I %FPCTARGETCPU%} + ' (FPC ' + {$I %FPCVERSION%} + ')'; - -var - __HttpServer: ICrossHttpServer; - -procedure TestCrossHttpServer; -var - LResponseStr: string; -begin - LResponseStr := OSVersion + '<br>Hello World!'; - - __HttpServer := TCrossHttpServer.Create(0, True); - if __HttpServer.Ssl then - begin - __HttpServer.SetCertificateFile('server.crt'); - __HttpServer.SetPrivateKeyFile('server.key'); - end; - - __HttpServer.Port := 8090; - __HttpServer.Start( - procedure(const AListen: ICrossListen; const ASuccess: Boolean) - begin - if ASuccess then - begin - if __HttpServer.Ssl then - Writeln('HTTP server(ssl: ' + TSSLTools.LibSSL + ' & ' + TSSLTools.LibCRYPTO + ') listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']') - else - Writeln('HTTP server listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']'); - end; - end); - - __HttpServer.Get('/', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) - begin - AResponse.Send(LResponseStr); - AHandled := True; - end); - - __HttpServer.Post('/upload', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) - var - LHashStr: string; - LFormField: TFormField; - begin - LHashStr := ''; - if (ARequest.BodyType = btMultiPart) then - begin - for LFormField in (ARequest.Body as THttpMultiPartFormData) do - begin - if (LFormField.ContentType <> '') then - begin - if (LHashStr <> '') then - LHashStr := LHashStr + sLineBreak; - - LHashStr := LHashStr + 'FileName: ' + LFormField.FileName + sLineBreak; - LHashStr := LHashStr + 'MD5: ' + THashMD5.GetHashString(LFormField.Value) + sLineBreak; - LHashStr := LHashStr + 'SHA1: ' + THashSHA1.GetHashString(LFormField.Value) + sLineBreak; - end; - end; - end; - - AResponse.Send(LHashStr); - AHandled := True; - end); -end; - -begin - // 如果 openssl 运行库名称与默认名称不一致, 请自行用以下代码修改 - // TSSLTools.LibSSL := 'libssl.so'; - // TSSLTools.LibCRYPTO := 'libcrypto.so'; - - TestCrossHttpServer; - Readln; -end. - +program HttpServer; + +{$I zLib.inc} + +uses + {$IFDEF UNIX} + cthreads, + {$ENDIF} + LazUTF8 + ,SysUtils + ,Classes + ,Net.CrossSocket.Base + ,Net.CrossHttpServer + ,Net.CrossHttpParams + ,Net.OpenSSL + ,Utils.Utils + ,Utils.Hash + ; + +const + OSVersion: string = {$I %FPCTARGETOS%} + '-' + {$I %FPCTARGETCPU%} + ' (FPC ' + {$I %FPCVERSION%} + ')'; + +var + __HttpServer: ICrossHttpServer; + +procedure TestCrossHttpServer; +var + LResponseStr: string; +begin + LResponseStr := OSVersion + '<br>Hello World!'; + + __HttpServer := TCrossHttpServer.Create(0, True); + if __HttpServer.Ssl then + begin + __HttpServer.SetCertificateFile('server.crt'); + __HttpServer.SetPrivateKeyFile('server.key'); + end; + + __HttpServer.Port := 8090; + __HttpServer.Start( + procedure(const AListen: ICrossListen; const ASuccess: Boolean) + begin + if ASuccess then + begin + if __HttpServer.Ssl then + Writeln('HTTP server(ssl: ' + TSSLTools.LibSSL + ' & ' + TSSLTools.LibCRYPTO + ') listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']') + else + Writeln('HTTP server listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']'); + end; + end); + + __HttpServer.Get('/', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) + begin + AResponse.Send(LResponseStr); + AHandled := True; + end); + + __HttpServer.Post('/upload', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) + var + LHashStr: string; + LFormField: TFormField; + begin + LHashStr := ''; + if (ARequest.BodyType = btMultiPart) then + begin + for LFormField in (ARequest.Body as THttpMultiPartFormData) do + begin + if (LFormField.ContentType <> '') then + begin + if (LHashStr <> '') then + LHashStr := LHashStr + sLineBreak; + + LHashStr := LHashStr + 'FileName: ' + LFormField.FileName + sLineBreak; + LHashStr := LHashStr + 'MD5: ' + THashMD5.GetHashString(LFormField.Value) + sLineBreak; + LHashStr := LHashStr + 'SHA1: ' + THashSHA1.GetHashString(LFormField.Value) + sLineBreak; + end; + end; + end; + + AResponse.Send(LHashStr); + AHandled := True; + end); +end; + +begin + // 如果 openssl 运行库名称与默认名称不一致, 请自行用以下代码修改 + // TSSLTools.LibSSL := 'libssl.so'; + // TSSLTools.LibCRYPTO := 'libcrypto.so'; + + TestCrossHttpServer; + Readln; +end. + diff --git a/Net/Demos/FPC/HttpServer/HttpServer.lps b/Net/Demos/FPC/HttpServer/HttpServer.lps index c083f4f..56c55a1 100644 --- a/Net/Demos/FPC/HttpServer/HttpServer.lps +++ b/Net/Demos/FPC/HttpServer/HttpServer.lps @@ -1,205 +1,205 @@ -<?xml version="1.0" encoding="UTF-8"?> -<CONFIG> - <ProjectSession> - <PathDelim Value="\"/> - <Version Value="12"/> - <BuildModes Active="Linux-龙芯"/> - <Units> - <Unit> - <Filename Value="HttpServer.lpr"/> - <IsPartOfProject Value="True"/> - <IsVisibleTab Value="True"/> - <TopLine Value="37"/> - <CursorPos X="38" Y="46"/> - <UsageCount Value="142"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossWebSocketServer.pas"/> - <EditorIndex Value="-1"/> - <TopLine Value="211"/> - <CursorPos X="20" Y="231"/> - <UsageCount Value="67"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossHttpServer.pas"/> - <EditorIndex Value="3"/> - <TopLine Value="3524"/> - <CursorPos X="17" Y="3528"/> - <UsageCount Value="68"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <EditorIndex Value="4"/> - <TopLine Value="75"/> - <CursorPos X="40" Y="83"/> - <UsageCount Value="47"/> - <Bookmarks Count="1"> - <Item0 X="13" Y="644" ID="1"/> - </Bookmarks> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.OpenSSL.pas"/> - <EditorIndex Value="5"/> - <TopLine Value="1047"/> - <CursorPos X="25" Y="557"/> - <UsageCount Value="49"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\lazarus\components\lazutils\lazutf8.pas"/> - <UnitName Value="LazUTF8"/> - <EditorIndex Value="-1"/> - <TopLine Value="8"/> - <CursorPos X="38" Y="31"/> - <UsageCount Value="9"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> - <EditorIndex Value="1"/> - <TopLine Value="962"/> - <CursorPos X="20" Y="969"/> - <UsageCount Value="11"/> - <Bookmarks Count="1"> - <Item0 Y="1386" ID="2"/> - </Bookmarks> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSocket.Epoll.pas"/> - <EditorIndex Value="2"/> - <TopLine Value="113"/> - <CursorPos X="46" Y="126"/> - <UsageCount Value="11"/> - <Loaded Value="True"/> - </Unit> - </Units> - <JumpHistory HistoryIndex="29"> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="634" Column="13" TopLine="595"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> - <Caret Line="1395" Column="37" TopLine="1390"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="642" Column="41" TopLine="595"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> - <Caret Line="1393" Column="35" TopLine="1370"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="628" Column="37" TopLine="549"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="98" TopLine="58"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> - <Caret Line="791" Column="21" TopLine="764"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> - <Caret Line="1395" TopLine="1394"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="507" Column="48" TopLine="504"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="100" Column="23" TopLine="73"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> - <Caret Line="790" TopLine="764"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> - <Caret Line="1342" TopLine="1312"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> - <Caret Line="752" Column="18" TopLine="727"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossHttpServer.pas"/> - <Caret Line="2121" Column="24" TopLine="2094"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="97" Column="19" TopLine="66"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="499" Column="41" TopLine="459"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="564" Column="15" TopLine="524"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="631" Column="114" TopLine="596"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="98" Column="68" TopLine="49"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="124" Column="12" TopLine="96"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="150" Column="12" TopLine="113"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="367" Column="12" TopLine="327"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="397" Column="12" TopLine="357"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="408" Column="12" TopLine="368"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="504" Column="12" TopLine="464"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="510" Column="12" TopLine="473"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="571" Column="40" TopLine="553"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="103" Column="15" TopLine="76"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="567" Column="3" TopLine="534"/> - </Position> - </JumpHistory> - <RunParams> - <FormatVersion Value="2"/> - <Modes ActiveMode=""/> - </RunParams> - </ProjectSession> -</CONFIG> +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectSession> + <PathDelim Value="\"/> + <Version Value="12"/> + <BuildModes Active="Linux-龙芯"/> + <Units> + <Unit> + <Filename Value="HttpServer.lpr"/> + <IsPartOfProject Value="True"/> + <IsVisibleTab Value="True"/> + <TopLine Value="37"/> + <CursorPos X="38" Y="46"/> + <UsageCount Value="142"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossWebSocketServer.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="211"/> + <CursorPos X="20" Y="231"/> + <UsageCount Value="67"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossHttpServer.pas"/> + <EditorIndex Value="3"/> + <TopLine Value="3524"/> + <CursorPos X="17" Y="3528"/> + <UsageCount Value="68"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <EditorIndex Value="4"/> + <TopLine Value="75"/> + <CursorPos X="40" Y="83"/> + <UsageCount Value="47"/> + <Bookmarks Count="1"> + <Item0 X="13" Y="644" ID="1"/> + </Bookmarks> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.OpenSSL.pas"/> + <EditorIndex Value="5"/> + <TopLine Value="1047"/> + <CursorPos X="25" Y="557"/> + <UsageCount Value="49"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\lazarus\components\lazutils\lazutf8.pas"/> + <UnitName Value="LazUTF8"/> + <EditorIndex Value="-1"/> + <TopLine Value="8"/> + <CursorPos X="38" Y="31"/> + <UsageCount Value="9"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> + <EditorIndex Value="1"/> + <TopLine Value="962"/> + <CursorPos X="20" Y="969"/> + <UsageCount Value="11"/> + <Bookmarks Count="1"> + <Item0 Y="1386" ID="2"/> + </Bookmarks> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSocket.Epoll.pas"/> + <EditorIndex Value="2"/> + <TopLine Value="113"/> + <CursorPos X="46" Y="126"/> + <UsageCount Value="11"/> + <Loaded Value="True"/> + </Unit> + </Units> + <JumpHistory HistoryIndex="29"> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="634" Column="13" TopLine="595"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> + <Caret Line="1395" Column="37" TopLine="1390"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="642" Column="41" TopLine="595"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> + <Caret Line="1393" Column="35" TopLine="1370"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="628" Column="37" TopLine="549"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="98" TopLine="58"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> + <Caret Line="791" Column="21" TopLine="764"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> + <Caret Line="1395" TopLine="1394"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="507" Column="48" TopLine="504"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="100" Column="23" TopLine="73"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> + <Caret Line="790" TopLine="764"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> + <Caret Line="1342" TopLine="1312"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> + <Caret Line="752" Column="18" TopLine="727"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossHttpServer.pas"/> + <Caret Line="2121" Column="24" TopLine="2094"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="97" Column="19" TopLine="66"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="499" Column="41" TopLine="459"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="564" Column="15" TopLine="524"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="631" Column="114" TopLine="596"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="98" Column="68" TopLine="49"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="124" Column="12" TopLine="96"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="150" Column="12" TopLine="113"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="367" Column="12" TopLine="327"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="397" Column="12" TopLine="357"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="408" Column="12" TopLine="368"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="504" Column="12" TopLine="464"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="510" Column="12" TopLine="473"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="571" Column="40" TopLine="553"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="103" Column="15" TopLine="76"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="567" Column="3" TopLine="534"/> + </Position> + </JumpHistory> + <RunParams> + <FormatVersion Value="2"/> + <Modes ActiveMode=""/> + </RunParams> + </ProjectSession> +</CONFIG> diff --git a/Net/Demos/FPC/WebSocketClient/WebSocketClient.lpi b/Net/Demos/FPC/WebSocketClient/WebSocketClient.lpi index 8c03025..b78cb8a 100644 --- a/Net/Demos/FPC/WebSocketClient/WebSocketClient.lpi +++ b/Net/Demos/FPC/WebSocketClient/WebSocketClient.lpi @@ -1,189 +1,189 @@ -<?xml version="1.0" encoding="UTF-8"?> -<CONFIG> - <ProjectOptions> - <Version Value="12"/> - <PathDelim Value="\"/> - <General> - <Flags> - <MainUnitHasCreateFormStatements Value="False"/> - <MainUnitHasTitleStatement Value="False"/> - <MainUnitHasScaledStatement Value="False"/> - </Flags> - <SessionStorage Value="InProjectDir"/> - <Title Value="WebSocketClient"/> - <UseAppBundle Value="False"/> - <ResourceType Value="res"/> - </General> - <BuildModes> - <Item Name="Windows-X64" Default="True"/> - <Item Name="Linux-X64"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketClient"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="x86_64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - </Other> - </CompilerOptions> - </Item> - <Item Name="Linux-ARM64"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketClient"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="aarch64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - </Other> - </CompilerOptions> - </Item> - <Item Name="Linux-龙芯"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketClient"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="loongarch64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - </Other> - </CompilerOptions> - </Item> - </BuildModes> - <PublishOptions> - <Version Value="2"/> - <UseFileFilters Value="True"/> - </PublishOptions> - <RunParams> - <FormatVersion Value="2"/> - </RunParams> - <Units> - <Unit> - <Filename Value="WebSocketClient.lpr"/> - <IsPartOfProject Value="True"/> - </Unit> - </Units> - </ProjectOptions> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketClient"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="x86_64"/> - <TargetOS Value="win64"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - </Other> - </CompilerOptions> - <Debugging> - <Exceptions> - <Item> - <Name Value="EAbort"/> - </Item> - <Item> - <Name Value="ECodetoolError"/> - </Item> - <Item> - <Name Value="EFOpenError"/> - </Item> - </Exceptions> - </Debugging> -</CONFIG> +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectOptions> + <Version Value="12"/> + <PathDelim Value="\"/> + <General> + <Flags> + <MainUnitHasCreateFormStatements Value="False"/> + <MainUnitHasTitleStatement Value="False"/> + <MainUnitHasScaledStatement Value="False"/> + </Flags> + <SessionStorage Value="InProjectDir"/> + <Title Value="WebSocketClient"/> + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <BuildModes> + <Item Name="Windows-X64" Default="True"/> + <Item Name="Linux-X64"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketClient"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="x86_64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + </Other> + </CompilerOptions> + </Item> + <Item Name="Linux-ARM64"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketClient"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="aarch64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + </Other> + </CompilerOptions> + </Item> + <Item Name="Linux-龙芯"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketClient"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="loongarch64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + </Other> + </CompilerOptions> + </Item> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <Units> + <Unit> + <Filename Value="WebSocketClient.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketClient"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="x86_64"/> + <TargetOS Value="win64"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/Net/Demos/FPC/WebSocketClient/WebSocketClient.lpr b/Net/Demos/FPC/WebSocketClient/WebSocketClient.lpr index 1f5668b..39cd980 100644 --- a/Net/Demos/FPC/WebSocketClient/WebSocketClient.lpr +++ b/Net/Demos/FPC/WebSocketClient/WebSocketClient.lpr @@ -1,100 +1,100 @@ -program WebSocketClient; - -{$I zLib.inc} - -uses - {$IFDEF UNIX} - cthreads, - {$ENDIF} - LazUTF8 - ,SysUtils - ,Classes - ,Net.CrossSocket.Base - ,Net.CrossWebSocketClient - ,Net.CrossWebSocketParser - ,Net.OpenSSL - ,Utils.Utils - ; - -var - __WebSocket: ICrossWebSocket; - -procedure TestWebSocketClient; -begin - __WebSocket := TCrossWebSocket.Create('wss://127.0.0.1:8090/test_web_socket'); - - __WebSocket.OnOpen( - procedure - begin - Writeln('Open'); - __WebSocket.Ping; - end); - - __WebSocket.OnClose( - procedure - begin - Writeln('Close'); - end); - - __WebSocket.OnPing( - procedure - begin - Writeln('Ping'); - end); - - __WebSocket.OnPong( - procedure - begin - Writeln('Pong'); - __WebSocket.Send('你好AAA!', - procedure(const ASuccess: Boolean) - begin - Writeln('你好AAA! ', ASuccess); - end); - - __WebSocket.Send('你好BBB!', - procedure(const ASuccess: Boolean) - begin - Writeln('你好BBB! ', ASuccess); - end); - - __WebSocket.Send('你好CCC!', - procedure(const ASuccess: Boolean) - begin - Writeln('你好CCC! ', ASuccess); - end); - - __WebSocket.Send('你好DDD!', - procedure(const ASuccess: Boolean) - begin - Writeln('你好DDD! ', ASuccess); - end); - end); - - __WebSocket.OnMessage( - procedure(const AMessageType: TWsMessageType; const AMessageData: TBytes) - var - LMessage: string; - begin - case AMessageType of - wtText: - LMessage := TUtils.GetString(AMessageData); - else - LMessage := TUtils.BytesToHex(AMessageData); - end; - - Writeln('[message]:', LMessage); - end); - - __WebSocket.Open; -end; - -begin - // 如果 openssl 运行库名称与默认名称不一致, 请自行用以下代码修改 - // TSSLTools.LibSSL := 'libssl.so'; - // TSSLTools.LibCRYPTO := 'libcrypto.so'; - - TestWebSocketClient; - Readln; -end. - +program WebSocketClient; + +{$I zLib.inc} + +uses + {$IFDEF UNIX} + cthreads, + {$ENDIF} + LazUTF8 + ,SysUtils + ,Classes + ,Net.CrossSocket.Base + ,Net.CrossWebSocketClient + ,Net.CrossWebSocketParser + ,Net.OpenSSL + ,Utils.Utils + ; + +var + __WebSocket: ICrossWebSocket; + +procedure TestWebSocketClient; +begin + __WebSocket := TCrossWebSocket.Create('wss://127.0.0.1:8090/test_web_socket'); + + __WebSocket.OnOpen( + procedure + begin + Writeln('Open'); + __WebSocket.Ping; + end); + + __WebSocket.OnClose( + procedure + begin + Writeln('Close'); + end); + + __WebSocket.OnPing( + procedure + begin + Writeln('Ping'); + end); + + __WebSocket.OnPong( + procedure + begin + Writeln('Pong'); + __WebSocket.Send('你好AAA!', + procedure(const ASuccess: Boolean) + begin + Writeln('你好AAA! ', ASuccess); + end); + + __WebSocket.Send('你好BBB!', + procedure(const ASuccess: Boolean) + begin + Writeln('你好BBB! ', ASuccess); + end); + + __WebSocket.Send('你好CCC!', + procedure(const ASuccess: Boolean) + begin + Writeln('你好CCC! ', ASuccess); + end); + + __WebSocket.Send('你好DDD!', + procedure(const ASuccess: Boolean) + begin + Writeln('你好DDD! ', ASuccess); + end); + end); + + __WebSocket.OnMessage( + procedure(const AMessageType: TWsMessageType; const AMessageData: TBytes) + var + LMessage: string; + begin + case AMessageType of + wtText: + LMessage := TUtils.GetString(AMessageData); + else + LMessage := TUtils.BytesToHex(AMessageData); + end; + + Writeln('[message]:', LMessage); + end); + + __WebSocket.Open; +end; + +begin + // 如果 openssl 运行库名称与默认名称不一致, 请自行用以下代码修改 + // TSSLTools.LibSSL := 'libssl.so'; + // TSSLTools.LibCRYPTO := 'libcrypto.so'; + + TestWebSocketClient; + Readln; +end. + diff --git a/Net/Demos/FPC/WebSocketClient/WebSocketClient.lps b/Net/Demos/FPC/WebSocketClient/WebSocketClient.lps index e364b38..d4d22c5 100644 --- a/Net/Demos/FPC/WebSocketClient/WebSocketClient.lps +++ b/Net/Demos/FPC/WebSocketClient/WebSocketClient.lps @@ -1,260 +1,260 @@ -<?xml version="1.0" encoding="UTF-8"?> -<CONFIG> - <ProjectSession> - <PathDelim Value="\"/> - <Version Value="12"/> - <BuildModes Active="Linux-ARM64"/> - <Units> - <Unit> - <Filename Value="WebSocketClient.lpr"/> - <IsPartOfProject Value="True"/> - <IsVisibleTab Value="True"/> - <TopLine Value="44"/> - <CursorPos X="36" Y="67"/> - <UsageCount Value="277"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> - <EditorIndex Value="1"/> - <TopLine Value="8"/> - <CursorPos X="70" Y="37"/> - <UsageCount Value="132"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossWebSocketServer.pas"/> - <EditorIndex Value="-1"/> - <TopLine Value="449"/> - <UsageCount Value="24"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> - <EditorIndex Value="8"/> - <TopLine Value="3"/> - <CursorPos X="106" Y="9"/> - <UsageCount Value="120"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <EditorIndex Value="7"/> - <TopLine Value="580"/> - <CursorPos Y="603"/> - <UsageCount Value="118"/> - <Bookmarks Count="3"> - <Item0 Y="563" ID="2"/> - <Item1 X="5" Y="263" ID="3"/> - <Item2 X="8" Y="373" ID="9"/> - </Bookmarks> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.OpenSSL.pas"/> - <EditorIndex Value="9"/> - <TopLine Value="1015"/> - <CursorPos X="3" Y="1017"/> - <UsageCount Value="124"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> - <EditorIndex Value="-1"/> - <TopLine Value="74"/> - <CursorPos X="11" Y="99"/> - <UsageCount Value="9"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSslSocket.Base.pas"/> - <EditorIndex Value="-1"/> - <TopLine Value="97"/> - <CursorPos X="17" Y="123"/> - <UsageCount Value="7"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\packages\rtl-generics\src\generics.collections.pas"/> - <UnitName Value="Generics.Collections"/> - <EditorIndex Value="5"/> - <TopLine Value="1262"/> - <CursorPos X="20" Y="1287"/> - <UsageCount Value="53"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossWebSocketParser.pas"/> - <EditorIndex Value="6"/> - <TopLine Value="256"/> - <CursorPos X="32" Y="186"/> - <UsageCount Value="53"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> - <EditorIndex Value="2"/> - <CursorPos X="43" Y="286"/> - <UsageCount Value="53"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\inc\dynlib.inc"/> - <EditorIndex Value="10"/> - <TopLine Value="36"/> - <CursorPos X="28" Y="61"/> - <UsageCount Value="100"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\inc\astrings.inc"/> - <EditorIndex Value="11"/> - <TopLine Value="888"/> - <CursorPos X="10" Y="888"/> - <UsageCount Value="100"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> - <EditorIndex Value="4"/> - <TopLine Value="2242"/> - <CursorPos X="2" Y="2269"/> - <UsageCount Value="53"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\..\cnvcl\Source\Crypto\CnSHA2.pas"/> - <EditorIndex Value="-1"/> - <TopLine Value="809"/> - <CursorPos X="64" Y="812"/> - <UsageCount Value="1"/> - </Unit> - <Unit> - <Filename Value="..\..\..\..\zLib.inc"/> - <EditorIndex Value="3"/> - <UsageCount Value="53"/> - <Loaded Value="True"/> - </Unit> - </Units> - <JumpHistory HistoryIndex="29"> - <Position> - <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> - <Caret Line="21" Column="3"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> - <Caret Line="19" Column="3"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> - <Caret Line="20"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> - <Caret Line="29" Column="3" TopLine="4"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> - <Caret Line="31" Column="3" TopLine="6"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> - <Caret Line="25"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> - <Caret Line="9" Column="106" TopLine="3"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> - <Caret Line="410" Column="26" TopLine="386"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> - <Caret Line="1189" Column="34" TopLine="1164"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> - <Caret Line="1196" Column="24" TopLine="1171"/> - </Position> - <Position> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> - <Caret Line="301" Column="3" TopLine="289"/> - </Position> - <Position> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> - <Caret Line="292" Column="10" TopLine="283"/> - </Position> - <Position> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> - <Caret Line="1927" Column="21" TopLine="1885"/> - </Position> - <Position> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> - </Position> - <Position> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> - <Caret Line="1927" Column="21" TopLine="1885"/> - </Position> - <Position> - <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> - <Caret Line="2269" Column="2" TopLine="2242"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> - <Caret Line="747" Column="21" TopLine="722"/> - </Position> - <Position> - <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> - <Caret Line="752" Column="46" TopLine="733"/> - </Position> - <Position> - <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> - <Caret Line="437" Column="49" TopLine="412"/> - </Position> - <Position> - <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> - <Caret Line="380" Column="43" TopLine="355"/> - </Position> - <Position> - <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> - <Caret Line="517" Column="3" TopLine="515"/> - </Position> - <Position> - <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> - <Caret Line="39" Column="20" TopLine="14"/> - </Position> - <Position> - <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> - <Caret Line="517" Column="3" TopLine="515"/> - </Position> - <Position> - <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> - <Caret Line="39" Column="20" TopLine="2"/> - </Position> - <Position> - <Filename Value="..\..\..\..\zLib.inc"/> - </Position> - <Position> - <Filename Value="WebSocketClient.lpr"/> - <Caret Line="30" Column="35"/> - </Position> - <Position> - <Filename Value="WebSocketClient.lpr"/> - <Caret Line="49" Column="38" TopLine="30"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> - <Caret Line="192" Column="66" TopLine="166"/> - </Position> - <Position> - <Filename Value="WebSocketClient.lpr"/> - <Caret Line="68" Column="54" TopLine="38"/> - </Position> - </JumpHistory> - <RunParams> - <FormatVersion Value="2"/> - <Modes ActiveMode=""/> - </RunParams> - </ProjectSession> -</CONFIG> +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectSession> + <PathDelim Value="\"/> + <Version Value="12"/> + <BuildModes Active="Linux-ARM64"/> + <Units> + <Unit> + <Filename Value="WebSocketClient.lpr"/> + <IsPartOfProject Value="True"/> + <IsVisibleTab Value="True"/> + <TopLine Value="44"/> + <CursorPos X="36" Y="67"/> + <UsageCount Value="277"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> + <EditorIndex Value="1"/> + <TopLine Value="8"/> + <CursorPos X="70" Y="37"/> + <UsageCount Value="132"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossWebSocketServer.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="449"/> + <UsageCount Value="24"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> + <EditorIndex Value="8"/> + <TopLine Value="3"/> + <CursorPos X="106" Y="9"/> + <UsageCount Value="120"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <EditorIndex Value="7"/> + <TopLine Value="580"/> + <CursorPos Y="603"/> + <UsageCount Value="118"/> + <Bookmarks Count="3"> + <Item0 Y="563" ID="2"/> + <Item1 X="5" Y="263" ID="3"/> + <Item2 X="8" Y="373" ID="9"/> + </Bookmarks> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.OpenSSL.pas"/> + <EditorIndex Value="9"/> + <TopLine Value="1015"/> + <CursorPos X="3" Y="1017"/> + <UsageCount Value="124"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="74"/> + <CursorPos X="11" Y="99"/> + <UsageCount Value="9"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSslSocket.Base.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="97"/> + <CursorPos X="17" Y="123"/> + <UsageCount Value="7"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\packages\rtl-generics\src\generics.collections.pas"/> + <UnitName Value="Generics.Collections"/> + <EditorIndex Value="5"/> + <TopLine Value="1262"/> + <CursorPos X="20" Y="1287"/> + <UsageCount Value="53"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossWebSocketParser.pas"/> + <EditorIndex Value="6"/> + <TopLine Value="256"/> + <CursorPos X="32" Y="186"/> + <UsageCount Value="53"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> + <EditorIndex Value="2"/> + <CursorPos X="43" Y="286"/> + <UsageCount Value="53"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\inc\dynlib.inc"/> + <EditorIndex Value="10"/> + <TopLine Value="36"/> + <CursorPos X="28" Y="61"/> + <UsageCount Value="100"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\inc\astrings.inc"/> + <EditorIndex Value="11"/> + <TopLine Value="888"/> + <CursorPos X="10" Y="888"/> + <UsageCount Value="100"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> + <EditorIndex Value="4"/> + <TopLine Value="2242"/> + <CursorPos X="2" Y="2269"/> + <UsageCount Value="53"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\cnvcl\Source\Crypto\CnSHA2.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="809"/> + <CursorPos X="64" Y="812"/> + <UsageCount Value="1"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\zLib.inc"/> + <EditorIndex Value="3"/> + <UsageCount Value="53"/> + <Loaded Value="True"/> + </Unit> + </Units> + <JumpHistory HistoryIndex="29"> + <Position> + <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> + <Caret Line="21" Column="3"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> + <Caret Line="19" Column="3"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> + <Caret Line="20"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> + <Caret Line="29" Column="3" TopLine="4"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> + <Caret Line="31" Column="3" TopLine="6"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> + <Caret Line="25"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossHttpClient.pas"/> + <Caret Line="9" Column="106" TopLine="3"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> + <Caret Line="410" Column="26" TopLine="386"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> + <Caret Line="1189" Column="34" TopLine="1164"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> + <Caret Line="1196" Column="24" TopLine="1171"/> + </Position> + <Position> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> + <Caret Line="301" Column="3" TopLine="289"/> + </Position> + <Position> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> + <Caret Line="292" Column="10" TopLine="283"/> + </Position> + <Position> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> + <Caret Line="1927" Column="21" TopLine="1885"/> + </Position> + <Position> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> + </Position> + <Position> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> + <Caret Line="1927" Column="21" TopLine="1885"/> + </Position> + <Position> + <Filename Value="..\..\..\..\..\..\..\FreePascal\fpcsrc\rtl\objpas\sysutils\sysstr.inc"/> + <Caret Line="2269" Column="2" TopLine="2242"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> + <Caret Line="747" Column="21" TopLine="722"/> + </Position> + <Position> + <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> + <Caret Line="752" Column="46" TopLine="733"/> + </Position> + <Position> + <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> + <Caret Line="437" Column="49" TopLine="412"/> + </Position> + <Position> + <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> + <Caret Line="380" Column="43" TopLine="355"/> + </Position> + <Position> + <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> + <Caret Line="517" Column="3" TopLine="515"/> + </Position> + <Position> + <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> + <Caret Line="39" Column="20" TopLine="14"/> + </Position> + <Position> + <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> + <Caret Line="517" Column="3" TopLine="515"/> + </Position> + <Position> + <Filename Value="..\..\..\..\Utils\Utils.Hash.pas"/> + <Caret Line="39" Column="20" TopLine="2"/> + </Position> + <Position> + <Filename Value="..\..\..\..\zLib.inc"/> + </Position> + <Position> + <Filename Value="WebSocketClient.lpr"/> + <Caret Line="30" Column="35"/> + </Position> + <Position> + <Filename Value="WebSocketClient.lpr"/> + <Caret Line="49" Column="38" TopLine="30"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossWebSocketClient.pas"/> + <Caret Line="192" Column="66" TopLine="166"/> + </Position> + <Position> + <Filename Value="WebSocketClient.lpr"/> + <Caret Line="68" Column="54" TopLine="38"/> + </Position> + </JumpHistory> + <RunParams> + <FormatVersion Value="2"/> + <Modes ActiveMode=""/> + </RunParams> + </ProjectSession> +</CONFIG> diff --git a/Net/Demos/FPC/WebSocketServer/WebSocketServer.lpi b/Net/Demos/FPC/WebSocketServer/WebSocketServer.lpi index c61c06e..f9f5da4 100644 --- a/Net/Demos/FPC/WebSocketServer/WebSocketServer.lpi +++ b/Net/Demos/FPC/WebSocketServer/WebSocketServer.lpi @@ -1,189 +1,189 @@ -<?xml version="1.0" encoding="UTF-8"?> -<CONFIG> - <ProjectOptions> - <Version Value="12"/> - <PathDelim Value="\"/> - <General> - <Flags> - <MainUnitHasCreateFormStatements Value="False"/> - <MainUnitHasTitleStatement Value="False"/> - <MainUnitHasScaledStatement Value="False"/> - </Flags> - <SessionStorage Value="InProjectDir"/> - <Title Value="WebSocketServer"/> - <UseAppBundle Value="False"/> - <ResourceType Value="res"/> - </General> - <BuildModes> - <Item Name="Windows-X64" Default="True"/> - <Item Name="Linux-X64"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketServer"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="x86_64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - </Other> - </CompilerOptions> - </Item> - <Item Name="Linux-ARM64"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketServer"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="aarch64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - </Other> - </CompilerOptions> - </Item> - <Item Name="Linux-龙芯"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketServer"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="loongarch64"/> - <TargetOS Value="linux"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - </Other> - </CompilerOptions> - </Item> - </BuildModes> - <PublishOptions> - <Version Value="2"/> - <UseFileFilters Value="True"/> - </PublishOptions> - <RunParams> - <FormatVersion Value="2"/> - </RunParams> - <Units> - <Unit> - <Filename Value="WebSocketServer.lpr"/> - <IsPartOfProject Value="True"/> - </Unit> - </Units> - </ProjectOptions> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketServer"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> - <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <TargetCPU Value="x86_64"/> - <TargetOS Value="win64"/> - <Optimizations> - <OptimizationLevel Value="2"/> - </Optimizations> - <SmallerCode Value="True"/> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - <RunWithoutDebug Value="True"/> - <StripSymbols Value="True"/> - </Debugging> - <LinkSmart Value="True"/> - </Linking> - <Other> - <ConfigFile> - <WriteConfigFilePath Value=""/> - </ConfigFile> - </Other> - </CompilerOptions> - <Debugging> - <Exceptions> - <Item> - <Name Value="EAbort"/> - </Item> - <Item> - <Name Value="ECodetoolError"/> - </Item> - <Item> - <Name Value="EFOpenError"/> - </Item> - </Exceptions> - </Debugging> -</CONFIG> +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectOptions> + <Version Value="12"/> + <PathDelim Value="\"/> + <General> + <Flags> + <MainUnitHasCreateFormStatements Value="False"/> + <MainUnitHasTitleStatement Value="False"/> + <MainUnitHasScaledStatement Value="False"/> + </Flags> + <SessionStorage Value="InProjectDir"/> + <Title Value="WebSocketServer"/> + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <BuildModes> + <Item Name="Windows-X64" Default="True"/> + <Item Name="Linux-X64"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketServer"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="x86_64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + </Other> + </CompilerOptions> + </Item> + <Item Name="Linux-ARM64"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketServer"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="aarch64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + </Other> + </CompilerOptions> + </Item> + <Item Name="Linux-龙芯"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketServer"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="loongarch64"/> + <TargetOS Value="linux"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + </Other> + </CompilerOptions> + </Item> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <Units> + <Unit> + <Filename Value="WebSocketServer.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\WebSocketServer"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir);..\..\..\.."/> + <OtherUnitFiles Value="..\..\..\..\Net;..\..\..\..\Utils;..\..\..\..\DelphiToFPC"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="x86_64"/> + <TargetOS Value="win64"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + <SmallerCode Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <ConfigFile> + <WriteConfigFilePath Value=""/> + </ConfigFile> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/Net/Demos/FPC/WebSocketServer/WebSocketServer.lpr b/Net/Demos/FPC/WebSocketServer/WebSocketServer.lpr index 39f1b26..87cd77e 100644 --- a/Net/Demos/FPC/WebSocketServer/WebSocketServer.lpr +++ b/Net/Demos/FPC/WebSocketServer/WebSocketServer.lpr @@ -1,111 +1,111 @@ -program WebSocketServer; - -{$I zLib.inc} - -uses - {$IFDEF UNIX} - cthreads, - {$ENDIF} - LazUTF8 - ,SysUtils - ,Classes - ,Net.CrossSocket.Base - ,Net.CrossHttpServer - ,Net.CrossWebSocketServer - ,Net.CrossWebSocketParser - ,Net.OpenSSL - ,Utils.Utils - ; - -const - OSVersion: string = {$I %FPCTARGETOS%} + '-' + {$I %FPCTARGETCPU%} + ' (FPC ' + {$I %FPCVERSION%} + ')'; - -var - __HttpServer: ICrossWebSocketServer; - -procedure TestCrossHttpServer; -var - LResponseStr: string; -begin - __HttpServer := TCrossWebSocketServer.Create(2, True); - if __HttpServer.Ssl then - begin - __HttpServer.SetCertificateFile('server.crt'); - __HttpServer.SetPrivateKeyFile('server.key'); - end; - - __HttpServer.Port := 8090; - __HttpServer.Start( - procedure(const AListen: ICrossListen; const ASuccess: Boolean) - begin - if ASuccess then - begin - if __HttpServer.Ssl then - Writeln('WebSocket server(ssl: ' + TSSLTools.LibSSL + ' & ' + TSSLTools.LibCRYPTO + ') listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']') - else - Writeln('WebSocket server listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']'); - end; - end); - - __HttpServer.Get('/', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) - begin - LResponseStr := OSVersion + '<br>Hello World!'; - AResponse.Send(LResponseStr); - AHandled := True; - end); - - __HttpServer.OnOpen( - procedure(const AConnection: ICrossWebSocketConnection) - begin - Writeln(Format('[%s : %d]Open', [AConnection.PeerAddr, AConnection.PeerPort])); - end); - - __HttpServer.OnClose( - procedure(const AConnection: ICrossWebSocketConnection) - begin - Writeln(Format('[%s : %d]Close', [AConnection.PeerAddr, AConnection.PeerPort])); - end); - -__HttpServer.OnPing( - procedure(const AConnection: ICrossWebSocketConnection) - begin - Writeln(Format('[%s : %d]Ping', [AConnection.PeerAddr, AConnection.PeerPort])); - end); - - __HttpServer.OnPong( - procedure(const AConnection: ICrossWebSocketConnection) - begin - Writeln(Format('[%s : %d]Pong', [AConnection.PeerAddr, AConnection.PeerPort])); - end); - - __HttpServer.OnMessage( - procedure(const AConnection: ICrossWebSocketConnection; - const AType: TWsMessageType; const AData: TBytes) - var - LMessage: string; - begin - if (AType = wtText) then - LMessage := TUtils.GetString(AData) - else - LMessage := TUtils.BytesToHex(AData); - - Writeln(Format('[message][%s : %d]', [AConnection.PeerAddr, AConnection.PeerPort]), LMessage); - - AConnection.WsSend('<response>' + LMessage, - procedure(const AWsConnection: ICrossWebSocketConnection; const ASuccess: Boolean) - begin - Writeln(LMessage, ASuccess); - end); - end); -end; - -begin - // 如果 openssl 运行库名称与默认名称不一致, 请自行用以下代码修改 - // TSSLTools.LibSSL := 'libssl.so'; - // TSSLTools.LibCRYPTO := 'libcrypto.so'; - - TestCrossHttpServer; - Readln; -end. - +program WebSocketServer; + +{$I zLib.inc} + +uses + {$IFDEF UNIX} + cthreads, + {$ENDIF} + LazUTF8 + ,SysUtils + ,Classes + ,Net.CrossSocket.Base + ,Net.CrossHttpServer + ,Net.CrossWebSocketServer + ,Net.CrossWebSocketParser + ,Net.OpenSSL + ,Utils.Utils + ; + +const + OSVersion: string = {$I %FPCTARGETOS%} + '-' + {$I %FPCTARGETCPU%} + ' (FPC ' + {$I %FPCVERSION%} + ')'; + +var + __HttpServer: ICrossWebSocketServer; + +procedure TestCrossHttpServer; +var + LResponseStr: string; +begin + __HttpServer := TCrossWebSocketServer.Create(2, True); + if __HttpServer.Ssl then + begin + __HttpServer.SetCertificateFile('server.crt'); + __HttpServer.SetPrivateKeyFile('server.key'); + end; + + __HttpServer.Port := 8090; + __HttpServer.Start( + procedure(const AListen: ICrossListen; const ASuccess: Boolean) + begin + if ASuccess then + begin + if __HttpServer.Ssl then + Writeln('WebSocket server(ssl: ' + TSSLTools.LibSSL + ' & ' + TSSLTools.LibCRYPTO + ') listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']') + else + Writeln('WebSocket server listen on [', AListen.LocalAddr, ':' , AListen.LocalPort, ']'); + end; + end); + + __HttpServer.Get('/', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) + begin + LResponseStr := OSVersion + '<br>Hello World!'; + AResponse.Send(LResponseStr); + AHandled := True; + end); + + __HttpServer.OnOpen( + procedure(const AConnection: ICrossWebSocketConnection) + begin + Writeln(Format('[%s : %d]Open', [AConnection.PeerAddr, AConnection.PeerPort])); + end); + + __HttpServer.OnClose( + procedure(const AConnection: ICrossWebSocketConnection) + begin + Writeln(Format('[%s : %d]Close', [AConnection.PeerAddr, AConnection.PeerPort])); + end); + +__HttpServer.OnPing( + procedure(const AConnection: ICrossWebSocketConnection) + begin + Writeln(Format('[%s : %d]Ping', [AConnection.PeerAddr, AConnection.PeerPort])); + end); + + __HttpServer.OnPong( + procedure(const AConnection: ICrossWebSocketConnection) + begin + Writeln(Format('[%s : %d]Pong', [AConnection.PeerAddr, AConnection.PeerPort])); + end); + + __HttpServer.OnMessage( + procedure(const AConnection: ICrossWebSocketConnection; + const AType: TWsMessageType; const AData: TBytes) + var + LMessage: string; + begin + if (AType = wtText) then + LMessage := TUtils.GetString(AData) + else + LMessage := TUtils.BytesToHex(AData); + + Writeln(Format('[message][%s : %d]', [AConnection.PeerAddr, AConnection.PeerPort]), LMessage); + + AConnection.WsSend('<response>' + LMessage, + procedure(const AWsConnection: ICrossWebSocketConnection; const ASuccess: Boolean) + begin + Writeln(LMessage, ASuccess); + end); + end); +end; + +begin + // 如果 openssl 运行库名称与默认名称不一致, 请自行用以下代码修改 + // TSSLTools.LibSSL := 'libssl.so'; + // TSSLTools.LibCRYPTO := 'libcrypto.so'; + + TestCrossHttpServer; + Readln; +end. + diff --git a/Net/Demos/FPC/WebSocketServer/WebSocketServer.lps b/Net/Demos/FPC/WebSocketServer/WebSocketServer.lps index b985e15..20fefb3 100644 --- a/Net/Demos/FPC/WebSocketServer/WebSocketServer.lps +++ b/Net/Demos/FPC/WebSocketServer/WebSocketServer.lps @@ -1,241 +1,241 @@ -<?xml version="1.0" encoding="UTF-8"?> -<CONFIG> - <ProjectSession> - <PathDelim Value="\"/> - <Version Value="12"/> - <BuildModes Active="Linux-龙芯"/> - <Units> - <Unit> - <Filename Value="WebSocketServer.lpr"/> - <IsPartOfProject Value="True"/> - <IsVisibleTab Value="True"/> - <TopLine Value="24"/> - <CursorPos X="42" Y="44"/> - <UsageCount Value="93"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossWebSocketServer.pas"/> - <EditorIndex Value="8"/> - <UsageCount Value="46"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <EditorIndex Value="1"/> - <TopLine Value="545"/> - <CursorPos X="49" Y="629"/> - <UsageCount Value="46"/> - <Bookmarks Count="2"> - <Item0 X="3" Y="263" ID="2"/> - <Item1 X="16" Y="172" ID="1"/> - </Bookmarks> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.OpenSSL.pas"/> - <EditorIndex Value="3"/> - <TopLine Value="88"/> - <CursorPos X="16" Y="118"/> - <UsageCount Value="46"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> - <EditorIndex Value="7"/> - <TopLine Value="691"/> - <CursorPos X="15" Y="719"/> - <UsageCount Value="46"/> - <Loaded Value="True"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSocket.Epoll.pas"/> - <EditorIndex Value="-1"/> - <TopLine Value="65"/> - <CursorPos X="17" Y="91"/> - <UsageCount Value="16"/> - </Unit> - <Unit> - <Filename Value="D:\GitHub\openssl\ssl\ssl_lib.c"/> - <EditorIndex Value="4"/> - <TopLine Value="4653"/> - <CursorPos X="30" Y="4697"/> - <UsageCount Value="35"/> - <Loaded Value="True"/> - <DefaultSyntaxHighlighter Value="C++"/> - </Unit> - <Unit> - <Filename Value="D:\GitHub\openssl\ssl\statem\statem.c"/> - <EditorIndex Value="6"/> - <TopLine Value="65"/> - <CursorPos X="25" Y="91"/> - <UsageCount Value="35"/> - <Loaded Value="True"/> - <DefaultSyntaxHighlighter Value="C++"/> - </Unit> - <Unit> - <Filename Value="D:\GitHub\openssl\ssl\statem\statem_lib.c"/> - <EditorIndex Value="5"/> - <TopLine Value="1427"/> - <CursorPos X="51" Y="1471"/> - <UsageCount Value="35"/> - <Loaded Value="True"/> - <DefaultSyntaxHighlighter Value="C++"/> - </Unit> - <Unit> - <Filename Value="D:\GitHub\openssl\util\other.syms"/> - <EditorIndex Value="-1"/> - <TopLine Value="645"/> - <CursorPos X="12" Y="213"/> - <UsageCount Value="6"/> - <DefaultSyntaxHighlighter Value="None"/> - </Unit> - <Unit> - <Filename Value="D:\GitHub\openssl\doc\man3\BIO_ctrl.pod"/> - <EditorIndex Value="9"/> - <CursorPos X="12" Y="7"/> - <UsageCount Value="30"/> - <Loaded Value="True"/> - <DefaultSyntaxHighlighter Value="None"/> - </Unit> - <Unit> - <Filename Value="D:\GitHub\openssl\include\openssl\bio.h.in"/> - <EditorIndex Value="10"/> - <TopLine Value="558"/> - <CursorPos X="66" Y="604"/> - <UsageCount Value="30"/> - <Loaded Value="True"/> - <DefaultSyntaxHighlighter Value="None"/> - </Unit> - <Unit> - <Filename Value="..\..\..\Net.CrossSslSocket.Base.pas"/> - <EditorIndex Value="2"/> - <CursorPos X="3" Y="17"/> - <UsageCount Value="28"/> - <Loaded Value="True"/> - </Unit> - </Units> - <JumpHistory HistoryIndex="28"> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="296" Column="61" TopLine="284"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="53" Column="14" TopLine="32"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="220" Column="52" TopLine="201"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="58" Column="14" TopLine="27"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="291" Column="3" TopLine="284"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="90" Column="17" TopLine="62"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="92" Column="38" TopLine="62"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="547" Column="32" TopLine="513"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="105" Column="53" TopLine="75"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.Base.pas"/> - <Caret Line="117" Column="3" TopLine="91"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.Base.pas"/> - <Caret Line="44" Column="3" TopLine="18"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="105" Column="53" TopLine="36"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.Base.pas"/> - <Caret Line="110" Column="3" TopLine="84"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.Base.pas"/> - <Caret Line="17" Column="3"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="105" Column="53" TopLine="66"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="101" Column="23" TopLine="66"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="591" Column="44" TopLine="571"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> - <Caret Line="744" Column="14" TopLine="728"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossWebSocketServer.pas"/> - <Caret Line="974" Column="89" TopLine="968"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="575" Column="83" TopLine="562"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="324" Column="16" TopLine="319"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="178" Column="16" TopLine="135"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="347" Column="50" TopLine="347"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="187" Column="30" TopLine="151"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="224" Column="3" TopLine="198"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="53" Column="14" TopLine="34"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="72" Column="20" TopLine="34"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="231" Column="54" TopLine="199"/> - </Position> - <Position> - <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> - <Caret Line="72" Column="23" TopLine="34"/> - </Position> - </JumpHistory> - <RunParams> - <FormatVersion Value="2"/> - <Modes ActiveMode=""/> - </RunParams> - </ProjectSession> -</CONFIG> +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectSession> + <PathDelim Value="\"/> + <Version Value="12"/> + <BuildModes Active="Linux-龙芯"/> + <Units> + <Unit> + <Filename Value="WebSocketServer.lpr"/> + <IsPartOfProject Value="True"/> + <IsVisibleTab Value="True"/> + <TopLine Value="24"/> + <CursorPos X="42" Y="44"/> + <UsageCount Value="93"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossWebSocketServer.pas"/> + <EditorIndex Value="8"/> + <UsageCount Value="46"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <EditorIndex Value="1"/> + <TopLine Value="545"/> + <CursorPos X="49" Y="629"/> + <UsageCount Value="46"/> + <Bookmarks Count="2"> + <Item0 X="3" Y="263" ID="2"/> + <Item1 X="16" Y="172" ID="1"/> + </Bookmarks> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.OpenSSL.pas"/> + <EditorIndex Value="3"/> + <TopLine Value="88"/> + <CursorPos X="16" Y="118"/> + <UsageCount Value="46"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> + <EditorIndex Value="7"/> + <TopLine Value="691"/> + <CursorPos X="15" Y="719"/> + <UsageCount Value="46"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSocket.Epoll.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="65"/> + <CursorPos X="17" Y="91"/> + <UsageCount Value="16"/> + </Unit> + <Unit> + <Filename Value="D:\GitHub\openssl\ssl\ssl_lib.c"/> + <EditorIndex Value="4"/> + <TopLine Value="4653"/> + <CursorPos X="30" Y="4697"/> + <UsageCount Value="35"/> + <Loaded Value="True"/> + <DefaultSyntaxHighlighter Value="C++"/> + </Unit> + <Unit> + <Filename Value="D:\GitHub\openssl\ssl\statem\statem.c"/> + <EditorIndex Value="6"/> + <TopLine Value="65"/> + <CursorPos X="25" Y="91"/> + <UsageCount Value="35"/> + <Loaded Value="True"/> + <DefaultSyntaxHighlighter Value="C++"/> + </Unit> + <Unit> + <Filename Value="D:\GitHub\openssl\ssl\statem\statem_lib.c"/> + <EditorIndex Value="5"/> + <TopLine Value="1427"/> + <CursorPos X="51" Y="1471"/> + <UsageCount Value="35"/> + <Loaded Value="True"/> + <DefaultSyntaxHighlighter Value="C++"/> + </Unit> + <Unit> + <Filename Value="D:\GitHub\openssl\util\other.syms"/> + <EditorIndex Value="-1"/> + <TopLine Value="645"/> + <CursorPos X="12" Y="213"/> + <UsageCount Value="6"/> + <DefaultSyntaxHighlighter Value="None"/> + </Unit> + <Unit> + <Filename Value="D:\GitHub\openssl\doc\man3\BIO_ctrl.pod"/> + <EditorIndex Value="9"/> + <CursorPos X="12" Y="7"/> + <UsageCount Value="30"/> + <Loaded Value="True"/> + <DefaultSyntaxHighlighter Value="None"/> + </Unit> + <Unit> + <Filename Value="D:\GitHub\openssl\include\openssl\bio.h.in"/> + <EditorIndex Value="10"/> + <TopLine Value="558"/> + <CursorPos X="66" Y="604"/> + <UsageCount Value="30"/> + <Loaded Value="True"/> + <DefaultSyntaxHighlighter Value="None"/> + </Unit> + <Unit> + <Filename Value="..\..\..\Net.CrossSslSocket.Base.pas"/> + <EditorIndex Value="2"/> + <CursorPos X="3" Y="17"/> + <UsageCount Value="28"/> + <Loaded Value="True"/> + </Unit> + </Units> + <JumpHistory HistoryIndex="28"> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="296" Column="61" TopLine="284"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="53" Column="14" TopLine="32"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="220" Column="52" TopLine="201"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="58" Column="14" TopLine="27"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="291" Column="3" TopLine="284"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="90" Column="17" TopLine="62"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="92" Column="38" TopLine="62"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="547" Column="32" TopLine="513"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="105" Column="53" TopLine="75"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.Base.pas"/> + <Caret Line="117" Column="3" TopLine="91"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.Base.pas"/> + <Caret Line="44" Column="3" TopLine="18"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="105" Column="53" TopLine="36"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.Base.pas"/> + <Caret Line="110" Column="3" TopLine="84"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.Base.pas"/> + <Caret Line="17" Column="3"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="105" Column="53" TopLine="66"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="101" Column="23" TopLine="66"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="591" Column="44" TopLine="571"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSocket.Base.pas"/> + <Caret Line="744" Column="14" TopLine="728"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossWebSocketServer.pas"/> + <Caret Line="974" Column="89" TopLine="968"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="575" Column="83" TopLine="562"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="324" Column="16" TopLine="319"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="178" Column="16" TopLine="135"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="347" Column="50" TopLine="347"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="187" Column="30" TopLine="151"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="224" Column="3" TopLine="198"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="53" Column="14" TopLine="34"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="72" Column="20" TopLine="34"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="231" Column="54" TopLine="199"/> + </Position> + <Position> + <Filename Value="..\..\..\Net.CrossSslSocket.OpenSSL.pas"/> + <Caret Line="72" Column="23" TopLine="34"/> + </Position> + </JumpHistory> + <RunParams> + <FormatVersion Value="2"/> + <Modes ActiveMode=""/> + </RunParams> + </ProjectSession> +</CONFIG> diff --git a/Net/Demos/Old/CrossHttpConsole/CrossHttpConsole.dpr b/Net/Demos/Old/CrossHttpConsole/CrossHttpConsole.dpr index 2ade5f8..d8e8f66 100644 --- a/Net/Demos/Old/CrossHttpConsole/CrossHttpConsole.dpr +++ b/Net/Demos/Old/CrossHttpConsole/CrossHttpConsole.dpr @@ -1,39 +1,39 @@ -program CrossHttpConsole; - -{$APPTYPE CONSOLE} - -{$R *.res} - -uses - System.SysUtils, - System.Classes, - uAppCfg in 'uAppCfg.pas', - Utils.Utils, - uDM in 'uDM.pas' {DM: TDataModule}; - -const - APP_NAME = {$IFDEF __CROSS_SSL__}'CrossHttpServer(SSL)'{$ELSE}'CrossHttpServer'{$ENDIF}; - -begin - ReportMemoryLeaksOnShutdown := True; - Writeln(TOSVersion.ToString); - - try - with TDM.Create(nil) do - try - Start(); - Writeln(APP_NAME, ' start at port:', HttpServer.Port, ', IO threads:', HttpServer.IoThreads); - Writeln('Press enter stop'); - Readln; - Stop(); - Writeln(APP_NAME, ' stop'); - Writeln('Press enter quit'); - Readln; - finally - Free; - end; - except - on E: Exception do - Writeln(E.ClassName, ': ', E.Message); - end; -end. +program CrossHttpConsole; + +{$APPTYPE CONSOLE} + +{$R *.res} + +uses + System.SysUtils, + System.Classes, + uAppCfg in 'uAppCfg.pas', + Utils.Utils, + uDM in 'uDM.pas' {DM: TDataModule}; + +const + APP_NAME = {$IFDEF __CROSS_SSL__}'CrossHttpServer(SSL)'{$ELSE}'CrossHttpServer'{$ENDIF}; + +begin + ReportMemoryLeaksOnShutdown := True; + Writeln(TOSVersion.ToString); + + try + with TDM.Create(nil) do + try + Start(); + Writeln(APP_NAME, ' start at port:', HttpServer.Port, ', IO threads:', HttpServer.IoThreads); + Writeln('Press enter stop'); + Readln; + Stop(); + Writeln(APP_NAME, ' stop'); + Writeln('Press enter quit'); + Readln; + finally + Free; + end; + except + on E: Exception do + Writeln(E.ClassName, ': ', E.Message); + end; +end. diff --git a/Net/Demos/Old/CrossHttpConsole/CrossHttpConsole.dproj b/Net/Demos/Old/CrossHttpConsole/CrossHttpConsole.dproj index d686c10..ecc67ec 100644 --- a/Net/Demos/Old/CrossHttpConsole/CrossHttpConsole.dproj +++ b/Net/Demos/Old/CrossHttpConsole/CrossHttpConsole.dproj @@ -1,809 +1,809 @@ -<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup> - <ProjectGuid>{AEB300D9-80E9-4C21-8A15-B3759A7D490D}</ProjectGuid> - <ProjectVersion>18.2</ProjectVersion> - <FrameworkType>VCL</FrameworkType> - <MainSource>CrossHttpConsole.dpr</MainSource> - <Base>True</Base> - <Config Condition="'$(Config)'==''">Debug</Config> - <Platform Condition="'$(Platform)'==''">OSX32</Platform> - <TargetedPlatforms>135</TargetedPlatforms> - <AppType>Console</AppType> - </PropertyGroup> - <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''"> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''"> - <Base_Android>true</Base_Android> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='iOSDevice32' and '$(Base)'=='true') or '$(Base_iOSDevice32)'!=''"> - <Base_iOSDevice32>true</Base_iOSDevice32> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''"> - <Base_iOSDevice64>true</Base_iOSDevice64> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='iOSSimulator' and '$(Base)'=='true') or '$(Base_iOSSimulator)'!=''"> - <Base_iOSSimulator>true</Base_iOSSimulator> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Linux64' and '$(Base)'=='true') or '$(Base_Linux64)'!=''"> - <Base_Linux64>true</Base_Linux64> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Base)'=='true') or '$(Base_OSX32)'!=''"> - <Base_OSX32>true</Base_OSX32> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''"> - <Base_Win32>true</Base_Win32> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''"> - <Base_Win64>true</Base_Win64> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''"> - <Cfg_1>true</Cfg_1> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Linux64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Linux64)'!=''"> - <Cfg_1_Linux64>true</Cfg_1_Linux64> - <CfgParent>Cfg_1</CfgParent> - <Cfg_1>true</Cfg_1> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Cfg_1)'=='true') or '$(Cfg_1_OSX32)'!=''"> - <Cfg_1_OSX32>true</Cfg_1_OSX32> - <CfgParent>Cfg_1</CfgParent> - <Cfg_1>true</Cfg_1> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''"> - <Cfg_1_Win32>true</Cfg_1_Win32> - <CfgParent>Cfg_1</CfgParent> - <Cfg_1>true</Cfg_1> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''"> - <Cfg_2>true</Cfg_2> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Cfg_2)'=='true') or '$(Cfg_2_iOSDevice64)'!=''"> - <Cfg_2_iOSDevice64>true</Cfg_2_iOSDevice64> - <CfgParent>Cfg_2</CfgParent> - <Cfg_2>true</Cfg_2> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Linux64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Linux64)'!=''"> - <Cfg_2_Linux64>true</Cfg_2_Linux64> - <CfgParent>Cfg_2</CfgParent> - <Cfg_2>true</Cfg_2> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Cfg_2)'=='true') or '$(Cfg_2_OSX32)'!=''"> - <Cfg_2_OSX32>true</Cfg_2_OSX32> - <CfgParent>Cfg_2</CfgParent> - <Cfg_2>true</Cfg_2> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''"> - <Cfg_2_Win32>true</Cfg_2_Win32> - <CfgParent>Cfg_2</CfgParent> - <Cfg_2>true</Cfg_2> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="'$(Base)'!=''"> - <DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput> - <DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput> - <DCC_E>false</DCC_E> - <DCC_N>false</DCC_N> - <DCC_S>false</DCC_S> - <DCC_F>false</DCC_F> - <DCC_K>false</DCC_K> - <DCC_UsePackage>RESTComponents;emsclientfiredac;FireDACIBDriver;emsclient;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;FireDAC;FireDACSqliteDriver;soaprtl;soapmidas;$(DCC_UsePackage)</DCC_UsePackage> - <DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace> - <SanitizedProjectName>CrossHttpConsole</SanitizedProjectName> - <DCC_Define>__CROSS_SSL__;$(DCC_Define)</DCC_Define> - <DCC_UnitSearchPath>..\..;..\..\..\Utils;$(DCC_UnitSearchPath)</DCC_UnitSearchPath> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_Android)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;$(DCC_UsePackage)</DCC_UsePackage> - <Android_LauncherIcon36>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png</Android_LauncherIcon36> - <Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48> - <Android_LauncherIcon72>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png</Android_LauncherIcon72> - <Android_LauncherIcon96>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png</Android_LauncherIcon96> - <Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144> - <Android_SplashImage426>$(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png</Android_SplashImage426> - <Android_SplashImage470>$(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png</Android_SplashImage470> - <Android_SplashImage640>$(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png</Android_SplashImage640> - <Android_SplashImage960>$(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png</Android_SplashImage960> - <EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar</EnabledSysJars> - <VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys> - <BT_BuildType>Debug</BT_BuildType> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_iOSDevice32)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage> - <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera</VerInfo_Keys> - <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily> - <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> - <BT_BuildType>Debug</BT_BuildType> - <VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_iOSDevice64)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage> - <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera</VerInfo_Keys> - <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily> - <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> - <BT_BuildType>Debug</BT_BuildType> - <VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_iOSSimulator)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_Linux64)'!=''"> - <DCC_UsePackage>DataSnapServerMidas;FireDACADSDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;inetdb;emsedge;IndyCore;dsnap;DataSnapCommon;DataSnapConnectors;bindengine;FireDACOracleDriver;FireDACMySQLDriver;FireDACCommonODBC;DataSnapClient;IndySystem;FireDACDb2Driver;FireDACInfxDriver;emshosting;FireDACPgDriver;FireDACASADriver;FireDACTDataDriver;DbxCommonDriver;DataSnapServer;xmlrtl;DataSnapNativeClient;rtl;DbxClientDriver;CustomIPTransport;bindcomp;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;$(DCC_UsePackage)</DCC_UsePackage> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_OSX32)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DataSnapServerMidas;DBXInterBaseDriver;DataSnapFireDAC;tethering;FireDACMSSQLDriver;bindcompfmx;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;DataSnapServer;xmlrtl;DataSnapNativeClient;ibxbindings;fmxobj;FireDACDSDriver;rtl;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;bindcomp;DBXInformixDriver;IndyIPClient;dbxcds;FireDACODBCDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;inetdbxpress;fmxase;$(DCC_UsePackage)</DCC_UsePackage> - <DCC_ConsoleTarget>true</DCC_ConsoleTarget> - <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts</VerInfo_Keys> - <BT_BuildType>Debug</BT_BuildType> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_Win32)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;DataSnapFireDAC;tethering;svnui;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;Intraweb;svn;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;FireDACInfxDriver;fmxFireDAC;vclimg;TeeDB;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;ibxbindings;fmxobj;FireDACDSDriver;rtl;vclwinx;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;inetdbxpress;fmxase;$(DCC_UsePackage)</DCC_UsePackage> - <DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace> - <BT_BuildType>Debug</BT_BuildType> - <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys> - <VerInfo_Locale>1033</VerInfo_Locale> - <DCC_ConsoleTarget>true</DCC_ConsoleTarget> - <UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44> - <UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_Win64)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;DataSnapFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;Intraweb;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;FireDACInfxDriver;fmxFireDAC;vclimg;TeeDB;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;ibxbindings;fmxobj;FireDACDSDriver;rtl;vclwinx;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;inetdbxpress;fmxase;$(DCC_UsePackage)</DCC_UsePackage> - <DCC_ConsoleTarget>true</DCC_ConsoleTarget> - <UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44> - <UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150> - <DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace> - <BT_BuildType>Debug</BT_BuildType> - <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys> - <VerInfo_Locale>1033</VerInfo_Locale> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_1)'!=''"> - <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define> - <DCC_DebugDCUs>true</DCC_DebugDCUs> - <DCC_Optimize>false</DCC_Optimize> - <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames> - <DCC_DebugInfoInExe>true</DCC_DebugInfoInExe> - <DCC_RemoteDebug>true</DCC_RemoteDebug> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_1_Linux64)'!=''"> - <Debugger_DebugSourcePath>D:\VclFmxRtl\zLib\Net\;$(Debugger_DebugSourcePath)</Debugger_DebugSourcePath> - <Debugger_Launcher>/usr/bin/xterm -e "%debuggee%"</Debugger_Launcher> - <Manifest_File>(None)</Manifest_File> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_1_OSX32)'!=''"> - <Debugger_DebugSourcePath>D:\VclFmxRtl\zLib\Net2\;D:\Design\Delphi\VclFmxRtl\zLib\Net\;D:\VclFmxRtl\zLib\Net\;$(Debugger_DebugSourcePath)</Debugger_DebugSourcePath> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_1_Win32)'!=''"> - <DCC_RemoteDebug>false</DCC_RemoteDebug> - <VerInfo_Locale>1033</VerInfo_Locale> - <Manifest_File>(None)</Manifest_File> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_2)'!=''"> - <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols> - <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define> - <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo> - <DCC_DebugInformation>0</DCC_DebugInformation> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_2_iOSDevice64)'!=''"> - <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> - <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily> - <VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_2_Linux64)'!=''"> - <Debugger_Launcher>/usr/bin/xterm -e "%debuggee%"</Debugger_Launcher> - <Manifest_File>(None)</Manifest_File> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_2_OSX32)'!=''"> - <Debugger_Launcher>/usr/X11/bin/xterm -e "%debuggee%"</Debugger_Launcher> - <Manifest_File>(None)</Manifest_File> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''"> - <DCC_MapFile>3</DCC_MapFile> - <DCC_DebugInformation>2</DCC_DebugInformation> - <DCC_LocalDebugSymbols>true</DCC_LocalDebugSymbols> - <VerInfo_Locale>1033</VerInfo_Locale> - <Manifest_File>(None)</Manifest_File> - </PropertyGroup> - <ItemGroup> - <DelphiCompile Include="$(MainSource)"> - <MainSource>MainSource</MainSource> - </DelphiCompile> - <DCCReference Include="uAppCfg.pas"/> - <DCCReference Include="uDM.pas"> - <Form>DM</Form> - <DesignClass>TDataModule</DesignClass> - </DCCReference> - <BuildConfiguration Include="Release"> - <Key>Cfg_2</Key> - <CfgParent>Base</CfgParent> - </BuildConfiguration> - <BuildConfiguration Include="Base"> - <Key>Base</Key> - </BuildConfiguration> - <BuildConfiguration Include="Debug"> - <Key>Cfg_1</Key> - <CfgParent>Base</CfgParent> - </BuildConfiguration> - </ItemGroup> - <ProjectExtensions> - <Borland.Personality>Delphi.Personality.12</Borland.Personality> - <Borland.ProjectType>Application</Borland.ProjectType> - <BorlandProject> - <Delphi.Personality> - <Source> - <Source Name="MainSource">CrossHttpConsole.dpr</Source> - </Source> - <Excluded_Packages> - <Excluded_Packages Name="$(BDSBIN)\TVidGrab.bpl">Datastead TVideoGrabber SDK 10.6.2.2</Excluded_Packages> - <Excluded_Packages Name="$(BDSBIN)\bcboffice2k250.bpl">Embarcadero C++Builder Office 2000 Servers Package</Excluded_Packages> - <Excluded_Packages Name="$(BDSBIN)\bcbofficexp250.bpl">Embarcadero C++Builder Office XP Servers Package</Excluded_Packages> - <Excluded_Packages Name="$(BDSBIN)\dcloffice2k250.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages> - <Excluded_Packages Name="$(BDSBIN)\dclofficexp250.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages> - </Excluded_Packages> - </Delphi.Personality> - <Deployment Version="3"> - <DeployFile LocalName="d:\delphi\d10.2\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png" Configuration="Debug" Class="UWP_DelphiLogo150"> - <Platform Name="Linux64"> - <RemoteDir>Assets\</RemoteDir> - <RemoteName>Logo150x150.png</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="Linux64\Release\CrossHttpConsole" Configuration="Release" Class="ProjectOutput"> - <Platform Name="Linux64"> - <RemoteName>CrossHttpConsole</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="d:\delphi\d10.2\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png" Configuration="Debug" Class="UWP_DelphiLogo44"> - <Platform Name="OSX32"> - <RemoteDir>Assets\</RemoteDir> - <RemoteName>Logo44x44.png</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="d:\delphi\d10.2\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png" Configuration="Debug" Class="UWP_DelphiLogo150"> - <Platform Name="OSX32"> - <RemoteDir>Assets\</RemoteDir> - <RemoteName>Logo150x150.png</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="iOSDevice64\Release\CrossHttpConsole.info.plist" Configuration="Release" Class="ProjectiOSInfoPList"> - <Platform Name="iOSDevice64"> - <RemoteName>Info.plist</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="iOSDevice64\Release\CrossHttpConsole" Configuration="Release" Class="ProjectOutput"> - <Platform Name="iOSDevice64"> - <RemoteName>CrossHttpConsole</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="iOSDevice64\Release\ResourceRules.plist" Configuration="Release" Class="ProjectiOSDeviceResourceRules"> - <Platform Name="iOSDevice64"> - <RemoteName>ResourceRules.plist</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule"> - <Platform Name="iOSSimulator"> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="$(BDS)\Redist\osx32\libcgsqlite3.dylib" Class="DependencyModule"> - <Platform Name="OSX32"> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="d:\delphi\d10.2\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png" Configuration="Debug" Class="UWP_DelphiLogo44"> - <Platform Name="Linux64"> - <RemoteDir>Assets\</RemoteDir> - <RemoteName>Logo44x44.png</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule"> - <Platform Name="OSX32"> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="Win32\Debug\CrossHttpConsole.exe" Configuration="Debug" Class="ProjectOutput"> - <Platform Name="Win32"> - <RemoteName>CrossHttpConsole.exe</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="Linux64\Debug\CrossHttpConsole" Configuration="Debug" Class="ProjectOutput"> - <Platform Name="Linux64"> - <RemoteName>CrossHttpConsole</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="iOSDevice64\Release\CrossHttpConsole.entitlements" Configuration="Release" Class="ProjectiOSEntitlements"> - <Platform Name="iOSDevice64"> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="$(BDS)\Redist\iossimulator\libPCRE.dylib" Class="DependencyModule"> - <Platform Name="iOSSimulator"> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="OSX32\Debug\CrossHttpConsole" Configuration="Debug" Class="ProjectOutput"> - <Platform Name="OSX32"> - <RemoteName>CrossHttpConsole</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="OSX32\Release\CrossHttpConsole" Configuration="Release" Class="ProjectOutput"> - <Platform Name="OSX32"> - <RemoteName>CrossHttpConsole</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="iOSDevice64\Release\CrossHttpConsole.dSYM" Configuration="Release" Class="ProjectiOSDeviceDebug"> - <Platform Name="iOSDevice64"> - <RemoteName>CrossHttpConsole</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployClass Name="AdditionalDebugSymbols"> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - <Platform Name="OSX32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="Win32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>0</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidClassesDexFile"> - <Platform Name="Android"> - <RemoteDir>classes</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidGDBServer"> - <Platform Name="Android"> - <RemoteDir>library\lib\armeabi-v7a</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidLibnativeArmeabiFile"> - <Platform Name="Android"> - <RemoteDir>library\lib\armeabi</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidLibnativeMipsFile"> - <Platform Name="Android"> - <RemoteDir>library\lib\mips</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidServiceOutput"> - <Platform Name="Android"> - <RemoteDir>library\lib\armeabi-v7a</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidSplashImageDef"> - <Platform Name="Android"> - <RemoteDir>res\drawable</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidSplashStyles"> - <Platform Name="Android"> - <RemoteDir>res\values</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_DefaultAppIcon"> - <Platform Name="Android"> - <RemoteDir>res\drawable</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_LauncherIcon144"> - <Platform Name="Android"> - <RemoteDir>res\drawable-xxhdpi</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_LauncherIcon36"> - <Platform Name="Android"> - <RemoteDir>res\drawable-ldpi</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_LauncherIcon48"> - <Platform Name="Android"> - <RemoteDir>res\drawable-mdpi</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_LauncherIcon72"> - <Platform Name="Android"> - <RemoteDir>res\drawable-hdpi</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_LauncherIcon96"> - <Platform Name="Android"> - <RemoteDir>res\drawable-xhdpi</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_SplashImage426"> - <Platform Name="Android"> - <RemoteDir>res\drawable-small</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_SplashImage470"> - <Platform Name="Android"> - <RemoteDir>res\drawable-normal</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_SplashImage640"> - <Platform Name="Android"> - <RemoteDir>res\drawable-large</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_SplashImage960"> - <Platform Name="Android"> - <RemoteDir>res\drawable-xlarge</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="DebugSymbols"> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - <Platform Name="OSX32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="Win32"> - <Operation>0</Operation> - </Platform> - </DeployClass> - <DeployClass Name="DependencyFramework"> - <Platform Name="OSX32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>1</Operation> - <Extensions>.framework</Extensions> - </Platform> - <Platform Name="Win32"> - <Operation>0</Operation> - </Platform> - </DeployClass> - <DeployClass Name="DependencyModule"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="OSX32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="Win32"> - <Operation>0</Operation> - <Extensions>.dll;.bpl</Extensions> - </Platform> - </DeployClass> - <DeployClass Required="true" Name="DependencyPackage"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="OSX32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="Win32"> - <Operation>0</Operation> - <Extensions>.bpl</Extensions> - </Platform> - </DeployClass> - <DeployClass Name="File"> - <Platform Name="Android"> - <Operation>0</Operation> - </Platform> - <Platform Name="iOSDevice32"> - <Operation>0</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>0</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>0</Operation> - </Platform> - <Platform Name="OSX32"> - <RemoteDir>Contents\Resources\StartUp\</RemoteDir> - <Operation>0</Operation> - </Platform> - <Platform Name="Win32"> - <Operation>0</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPad_Launch1024"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPad_Launch1536"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPad_Launch2048"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPad_Launch768"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPhone_Launch320"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPhone_Launch640"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPhone_Launch640x1136"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectAndroidManifest"> - <Platform Name="Android"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectiOSDeviceDebug"> - <Platform Name="iOSDevice32"> - <RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectiOSDeviceResourceRules"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectiOSEntitlements"> - <Platform Name="iOSDevice32"> - <RemoteDir>..\</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <RemoteDir>..\</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectiOSInfoPList"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectiOSResource"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectOSXEntitlements"> - <Platform Name="OSX32"> - <RemoteDir>..\</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectOSXInfoPList"> - <Platform Name="OSX32"> - <RemoteDir>Contents</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectOSXResource"> - <Platform Name="OSX32"> - <RemoteDir>Contents\Resources</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Required="true" Name="ProjectOutput"> - <Platform Name="Android"> - <RemoteDir>library\lib\armeabi-v7a</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - <Platform Name="Linux64"> - <Operation>1</Operation> - </Platform> - <Platform Name="OSX32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="Win32"> - <Operation>0</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectUWPManifest"> - <Platform Name="Win32"> - <Operation>1</Operation> - </Platform> - <Platform Name="Win64"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="UWP_DelphiLogo150"> - <Platform Name="Win32"> - <RemoteDir>Assets</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="Win64"> - <RemoteDir>Assets</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="UWP_DelphiLogo44"> - <Platform Name="Win32"> - <RemoteDir>Assets</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="Win64"> - <RemoteDir>Assets</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/> - <ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/> - <ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/> - <ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/> - <ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/> - <ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/> - <ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/> - <ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/> - </Deployment> - <Platforms> - <Platform value="Android">False</Platform> - <Platform value="iOSDevice32">False</Platform> - <Platform value="iOSDevice64">False</Platform> - <Platform value="iOSSimulator">False</Platform> - <Platform value="Linux64">True</Platform> - <Platform value="OSX32">True</Platform> - <Platform value="Win32">True</Platform> - <Platform value="Win64">True</Platform> - </Platforms> - </BorlandProject> - <ProjectFileVersion>12</ProjectFileVersion> - </ProjectExtensions> - <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/> - <Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/> - <Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/> -</Project> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <ProjectGuid>{AEB300D9-80E9-4C21-8A15-B3759A7D490D}</ProjectGuid> + <ProjectVersion>18.2</ProjectVersion> + <FrameworkType>VCL</FrameworkType> + <MainSource>CrossHttpConsole.dpr</MainSource> + <Base>True</Base> + <Config Condition="'$(Config)'==''">Debug</Config> + <Platform Condition="'$(Platform)'==''">OSX32</Platform> + <TargetedPlatforms>135</TargetedPlatforms> + <AppType>Console</AppType> + </PropertyGroup> + <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''"> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''"> + <Base_Android>true</Base_Android> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='iOSDevice32' and '$(Base)'=='true') or '$(Base_iOSDevice32)'!=''"> + <Base_iOSDevice32>true</Base_iOSDevice32> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''"> + <Base_iOSDevice64>true</Base_iOSDevice64> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='iOSSimulator' and '$(Base)'=='true') or '$(Base_iOSSimulator)'!=''"> + <Base_iOSSimulator>true</Base_iOSSimulator> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Linux64' and '$(Base)'=='true') or '$(Base_Linux64)'!=''"> + <Base_Linux64>true</Base_Linux64> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Base)'=='true') or '$(Base_OSX32)'!=''"> + <Base_OSX32>true</Base_OSX32> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''"> + <Base_Win32>true</Base_Win32> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''"> + <Base_Win64>true</Base_Win64> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''"> + <Cfg_1>true</Cfg_1> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Linux64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Linux64)'!=''"> + <Cfg_1_Linux64>true</Cfg_1_Linux64> + <CfgParent>Cfg_1</CfgParent> + <Cfg_1>true</Cfg_1> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Cfg_1)'=='true') or '$(Cfg_1_OSX32)'!=''"> + <Cfg_1_OSX32>true</Cfg_1_OSX32> + <CfgParent>Cfg_1</CfgParent> + <Cfg_1>true</Cfg_1> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''"> + <Cfg_1_Win32>true</Cfg_1_Win32> + <CfgParent>Cfg_1</CfgParent> + <Cfg_1>true</Cfg_1> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''"> + <Cfg_2>true</Cfg_2> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Cfg_2)'=='true') or '$(Cfg_2_iOSDevice64)'!=''"> + <Cfg_2_iOSDevice64>true</Cfg_2_iOSDevice64> + <CfgParent>Cfg_2</CfgParent> + <Cfg_2>true</Cfg_2> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Linux64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Linux64)'!=''"> + <Cfg_2_Linux64>true</Cfg_2_Linux64> + <CfgParent>Cfg_2</CfgParent> + <Cfg_2>true</Cfg_2> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Cfg_2)'=='true') or '$(Cfg_2_OSX32)'!=''"> + <Cfg_2_OSX32>true</Cfg_2_OSX32> + <CfgParent>Cfg_2</CfgParent> + <Cfg_2>true</Cfg_2> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''"> + <Cfg_2_Win32>true</Cfg_2_Win32> + <CfgParent>Cfg_2</CfgParent> + <Cfg_2>true</Cfg_2> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="'$(Base)'!=''"> + <DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput> + <DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput> + <DCC_E>false</DCC_E> + <DCC_N>false</DCC_N> + <DCC_S>false</DCC_S> + <DCC_F>false</DCC_F> + <DCC_K>false</DCC_K> + <DCC_UsePackage>RESTComponents;emsclientfiredac;FireDACIBDriver;emsclient;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;FireDAC;FireDACSqliteDriver;soaprtl;soapmidas;$(DCC_UsePackage)</DCC_UsePackage> + <DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace> + <SanitizedProjectName>CrossHttpConsole</SanitizedProjectName> + <DCC_Define>__CROSS_SSL__;$(DCC_Define)</DCC_Define> + <DCC_UnitSearchPath>..\..;..\..\..\Utils;$(DCC_UnitSearchPath)</DCC_UnitSearchPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_Android)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;$(DCC_UsePackage)</DCC_UsePackage> + <Android_LauncherIcon36>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png</Android_LauncherIcon36> + <Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48> + <Android_LauncherIcon72>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png</Android_LauncherIcon72> + <Android_LauncherIcon96>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png</Android_LauncherIcon96> + <Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144> + <Android_SplashImage426>$(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png</Android_SplashImage426> + <Android_SplashImage470>$(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png</Android_SplashImage470> + <Android_SplashImage640>$(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png</Android_SplashImage640> + <Android_SplashImage960>$(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png</Android_SplashImage960> + <EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar</EnabledSysJars> + <VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys> + <BT_BuildType>Debug</BT_BuildType> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_iOSDevice32)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage> + <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera</VerInfo_Keys> + <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + <BT_BuildType>Debug</BT_BuildType> + <VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_iOSDevice64)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage> + <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera</VerInfo_Keys> + <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + <BT_BuildType>Debug</BT_BuildType> + <VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_iOSSimulator)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_Linux64)'!=''"> + <DCC_UsePackage>DataSnapServerMidas;FireDACADSDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;inetdb;emsedge;IndyCore;dsnap;DataSnapCommon;DataSnapConnectors;bindengine;FireDACOracleDriver;FireDACMySQLDriver;FireDACCommonODBC;DataSnapClient;IndySystem;FireDACDb2Driver;FireDACInfxDriver;emshosting;FireDACPgDriver;FireDACASADriver;FireDACTDataDriver;DbxCommonDriver;DataSnapServer;xmlrtl;DataSnapNativeClient;rtl;DbxClientDriver;CustomIPTransport;bindcomp;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;$(DCC_UsePackage)</DCC_UsePackage> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_OSX32)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DataSnapServerMidas;DBXInterBaseDriver;DataSnapFireDAC;tethering;FireDACMSSQLDriver;bindcompfmx;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;DataSnapServer;xmlrtl;DataSnapNativeClient;ibxbindings;fmxobj;FireDACDSDriver;rtl;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;bindcomp;DBXInformixDriver;IndyIPClient;dbxcds;FireDACODBCDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;inetdbxpress;fmxase;$(DCC_UsePackage)</DCC_UsePackage> + <DCC_ConsoleTarget>true</DCC_ConsoleTarget> + <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts</VerInfo_Keys> + <BT_BuildType>Debug</BT_BuildType> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_Win32)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;DataSnapFireDAC;tethering;svnui;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;Intraweb;svn;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;FireDACInfxDriver;fmxFireDAC;vclimg;TeeDB;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;ibxbindings;fmxobj;FireDACDSDriver;rtl;vclwinx;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;inetdbxpress;fmxase;$(DCC_UsePackage)</DCC_UsePackage> + <DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace> + <BT_BuildType>Debug</BT_BuildType> + <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys> + <VerInfo_Locale>1033</VerInfo_Locale> + <DCC_ConsoleTarget>true</DCC_ConsoleTarget> + <UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44> + <UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_Win64)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;DataSnapFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;Intraweb;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;FireDACInfxDriver;fmxFireDAC;vclimg;TeeDB;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;ibxbindings;fmxobj;FireDACDSDriver;rtl;vclwinx;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;inetdbxpress;fmxase;$(DCC_UsePackage)</DCC_UsePackage> + <DCC_ConsoleTarget>true</DCC_ConsoleTarget> + <UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44> + <UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150> + <DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace> + <BT_BuildType>Debug</BT_BuildType> + <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys> + <VerInfo_Locale>1033</VerInfo_Locale> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_1)'!=''"> + <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define> + <DCC_DebugDCUs>true</DCC_DebugDCUs> + <DCC_Optimize>false</DCC_Optimize> + <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames> + <DCC_DebugInfoInExe>true</DCC_DebugInfoInExe> + <DCC_RemoteDebug>true</DCC_RemoteDebug> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_1_Linux64)'!=''"> + <Debugger_DebugSourcePath>D:\VclFmxRtl\zLib\Net\;$(Debugger_DebugSourcePath)</Debugger_DebugSourcePath> + <Debugger_Launcher>/usr/bin/xterm -e "%debuggee%"</Debugger_Launcher> + <Manifest_File>(None)</Manifest_File> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_1_OSX32)'!=''"> + <Debugger_DebugSourcePath>D:\VclFmxRtl\zLib\Net2\;D:\Design\Delphi\VclFmxRtl\zLib\Net\;D:\VclFmxRtl\zLib\Net\;$(Debugger_DebugSourcePath)</Debugger_DebugSourcePath> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_1_Win32)'!=''"> + <DCC_RemoteDebug>false</DCC_RemoteDebug> + <VerInfo_Locale>1033</VerInfo_Locale> + <Manifest_File>(None)</Manifest_File> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_2)'!=''"> + <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols> + <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define> + <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo> + <DCC_DebugInformation>0</DCC_DebugInformation> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_2_iOSDevice64)'!=''"> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily> + <VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_2_Linux64)'!=''"> + <Debugger_Launcher>/usr/bin/xterm -e "%debuggee%"</Debugger_Launcher> + <Manifest_File>(None)</Manifest_File> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_2_OSX32)'!=''"> + <Debugger_Launcher>/usr/X11/bin/xterm -e "%debuggee%"</Debugger_Launcher> + <Manifest_File>(None)</Manifest_File> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''"> + <DCC_MapFile>3</DCC_MapFile> + <DCC_DebugInformation>2</DCC_DebugInformation> + <DCC_LocalDebugSymbols>true</DCC_LocalDebugSymbols> + <VerInfo_Locale>1033</VerInfo_Locale> + <Manifest_File>(None)</Manifest_File> + </PropertyGroup> + <ItemGroup> + <DelphiCompile Include="$(MainSource)"> + <MainSource>MainSource</MainSource> + </DelphiCompile> + <DCCReference Include="uAppCfg.pas"/> + <DCCReference Include="uDM.pas"> + <Form>DM</Form> + <DesignClass>TDataModule</DesignClass> + </DCCReference> + <BuildConfiguration Include="Release"> + <Key>Cfg_2</Key> + <CfgParent>Base</CfgParent> + </BuildConfiguration> + <BuildConfiguration Include="Base"> + <Key>Base</Key> + </BuildConfiguration> + <BuildConfiguration Include="Debug"> + <Key>Cfg_1</Key> + <CfgParent>Base</CfgParent> + </BuildConfiguration> + </ItemGroup> + <ProjectExtensions> + <Borland.Personality>Delphi.Personality.12</Borland.Personality> + <Borland.ProjectType>Application</Borland.ProjectType> + <BorlandProject> + <Delphi.Personality> + <Source> + <Source Name="MainSource">CrossHttpConsole.dpr</Source> + </Source> + <Excluded_Packages> + <Excluded_Packages Name="$(BDSBIN)\TVidGrab.bpl">Datastead TVideoGrabber SDK 10.6.2.2</Excluded_Packages> + <Excluded_Packages Name="$(BDSBIN)\bcboffice2k250.bpl">Embarcadero C++Builder Office 2000 Servers Package</Excluded_Packages> + <Excluded_Packages Name="$(BDSBIN)\bcbofficexp250.bpl">Embarcadero C++Builder Office XP Servers Package</Excluded_Packages> + <Excluded_Packages Name="$(BDSBIN)\dcloffice2k250.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages> + <Excluded_Packages Name="$(BDSBIN)\dclofficexp250.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages> + </Excluded_Packages> + </Delphi.Personality> + <Deployment Version="3"> + <DeployFile LocalName="d:\delphi\d10.2\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png" Configuration="Debug" Class="UWP_DelphiLogo150"> + <Platform Name="Linux64"> + <RemoteDir>Assets\</RemoteDir> + <RemoteName>Logo150x150.png</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="Linux64\Release\CrossHttpConsole" Configuration="Release" Class="ProjectOutput"> + <Platform Name="Linux64"> + <RemoteName>CrossHttpConsole</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="d:\delphi\d10.2\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png" Configuration="Debug" Class="UWP_DelphiLogo44"> + <Platform Name="OSX32"> + <RemoteDir>Assets\</RemoteDir> + <RemoteName>Logo44x44.png</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="d:\delphi\d10.2\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png" Configuration="Debug" Class="UWP_DelphiLogo150"> + <Platform Name="OSX32"> + <RemoteDir>Assets\</RemoteDir> + <RemoteName>Logo150x150.png</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="iOSDevice64\Release\CrossHttpConsole.info.plist" Configuration="Release" Class="ProjectiOSInfoPList"> + <Platform Name="iOSDevice64"> + <RemoteName>Info.plist</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="iOSDevice64\Release\CrossHttpConsole" Configuration="Release" Class="ProjectOutput"> + <Platform Name="iOSDevice64"> + <RemoteName>CrossHttpConsole</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="iOSDevice64\Release\ResourceRules.plist" Configuration="Release" Class="ProjectiOSDeviceResourceRules"> + <Platform Name="iOSDevice64"> + <RemoteName>ResourceRules.plist</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule"> + <Platform Name="iOSSimulator"> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="$(BDS)\Redist\osx32\libcgsqlite3.dylib" Class="DependencyModule"> + <Platform Name="OSX32"> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="d:\delphi\d10.2\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png" Configuration="Debug" Class="UWP_DelphiLogo44"> + <Platform Name="Linux64"> + <RemoteDir>Assets\</RemoteDir> + <RemoteName>Logo44x44.png</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule"> + <Platform Name="OSX32"> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="Win32\Debug\CrossHttpConsole.exe" Configuration="Debug" Class="ProjectOutput"> + <Platform Name="Win32"> + <RemoteName>CrossHttpConsole.exe</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="Linux64\Debug\CrossHttpConsole" Configuration="Debug" Class="ProjectOutput"> + <Platform Name="Linux64"> + <RemoteName>CrossHttpConsole</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="iOSDevice64\Release\CrossHttpConsole.entitlements" Configuration="Release" Class="ProjectiOSEntitlements"> + <Platform Name="iOSDevice64"> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="$(BDS)\Redist\iossimulator\libPCRE.dylib" Class="DependencyModule"> + <Platform Name="iOSSimulator"> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="OSX32\Debug\CrossHttpConsole" Configuration="Debug" Class="ProjectOutput"> + <Platform Name="OSX32"> + <RemoteName>CrossHttpConsole</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="OSX32\Release\CrossHttpConsole" Configuration="Release" Class="ProjectOutput"> + <Platform Name="OSX32"> + <RemoteName>CrossHttpConsole</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="iOSDevice64\Release\CrossHttpConsole.dSYM" Configuration="Release" Class="ProjectiOSDeviceDebug"> + <Platform Name="iOSDevice64"> + <RemoteName>CrossHttpConsole</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployClass Name="AdditionalDebugSymbols"> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + <Platform Name="OSX32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="Win32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>0</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidClassesDexFile"> + <Platform Name="Android"> + <RemoteDir>classes</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidGDBServer"> + <Platform Name="Android"> + <RemoteDir>library\lib\armeabi-v7a</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidLibnativeArmeabiFile"> + <Platform Name="Android"> + <RemoteDir>library\lib\armeabi</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidLibnativeMipsFile"> + <Platform Name="Android"> + <RemoteDir>library\lib\mips</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidServiceOutput"> + <Platform Name="Android"> + <RemoteDir>library\lib\armeabi-v7a</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidSplashImageDef"> + <Platform Name="Android"> + <RemoteDir>res\drawable</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidSplashStyles"> + <Platform Name="Android"> + <RemoteDir>res\values</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_DefaultAppIcon"> + <Platform Name="Android"> + <RemoteDir>res\drawable</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_LauncherIcon144"> + <Platform Name="Android"> + <RemoteDir>res\drawable-xxhdpi</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_LauncherIcon36"> + <Platform Name="Android"> + <RemoteDir>res\drawable-ldpi</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_LauncherIcon48"> + <Platform Name="Android"> + <RemoteDir>res\drawable-mdpi</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_LauncherIcon72"> + <Platform Name="Android"> + <RemoteDir>res\drawable-hdpi</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_LauncherIcon96"> + <Platform Name="Android"> + <RemoteDir>res\drawable-xhdpi</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_SplashImage426"> + <Platform Name="Android"> + <RemoteDir>res\drawable-small</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_SplashImage470"> + <Platform Name="Android"> + <RemoteDir>res\drawable-normal</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_SplashImage640"> + <Platform Name="Android"> + <RemoteDir>res\drawable-large</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_SplashImage960"> + <Platform Name="Android"> + <RemoteDir>res\drawable-xlarge</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="DebugSymbols"> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + <Platform Name="OSX32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="Win32"> + <Operation>0</Operation> + </Platform> + </DeployClass> + <DeployClass Name="DependencyFramework"> + <Platform Name="OSX32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>1</Operation> + <Extensions>.framework</Extensions> + </Platform> + <Platform Name="Win32"> + <Operation>0</Operation> + </Platform> + </DeployClass> + <DeployClass Name="DependencyModule"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="OSX32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="Win32"> + <Operation>0</Operation> + <Extensions>.dll;.bpl</Extensions> + </Platform> + </DeployClass> + <DeployClass Required="true" Name="DependencyPackage"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="OSX32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="Win32"> + <Operation>0</Operation> + <Extensions>.bpl</Extensions> + </Platform> + </DeployClass> + <DeployClass Name="File"> + <Platform Name="Android"> + <Operation>0</Operation> + </Platform> + <Platform Name="iOSDevice32"> + <Operation>0</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>0</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>0</Operation> + </Platform> + <Platform Name="OSX32"> + <RemoteDir>Contents\Resources\StartUp\</RemoteDir> + <Operation>0</Operation> + </Platform> + <Platform Name="Win32"> + <Operation>0</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPad_Launch1024"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPad_Launch1536"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPad_Launch2048"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPad_Launch768"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPhone_Launch320"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPhone_Launch640"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPhone_Launch640x1136"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectAndroidManifest"> + <Platform Name="Android"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectiOSDeviceDebug"> + <Platform Name="iOSDevice32"> + <RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectiOSDeviceResourceRules"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectiOSEntitlements"> + <Platform Name="iOSDevice32"> + <RemoteDir>..\</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <RemoteDir>..\</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectiOSInfoPList"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectiOSResource"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectOSXEntitlements"> + <Platform Name="OSX32"> + <RemoteDir>..\</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectOSXInfoPList"> + <Platform Name="OSX32"> + <RemoteDir>Contents</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectOSXResource"> + <Platform Name="OSX32"> + <RemoteDir>Contents\Resources</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Required="true" Name="ProjectOutput"> + <Platform Name="Android"> + <RemoteDir>library\lib\armeabi-v7a</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + <Platform Name="Linux64"> + <Operation>1</Operation> + </Platform> + <Platform Name="OSX32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="Win32"> + <Operation>0</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectUWPManifest"> + <Platform Name="Win32"> + <Operation>1</Operation> + </Platform> + <Platform Name="Win64"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="UWP_DelphiLogo150"> + <Platform Name="Win32"> + <RemoteDir>Assets</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="Win64"> + <RemoteDir>Assets</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="UWP_DelphiLogo44"> + <Platform Name="Win32"> + <RemoteDir>Assets</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="Win64"> + <RemoteDir>Assets</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/> + <ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/> + <ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/> + <ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/> + <ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/> + <ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/> + <ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/> + <ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/> + </Deployment> + <Platforms> + <Platform value="Android">False</Platform> + <Platform value="iOSDevice32">False</Platform> + <Platform value="iOSDevice64">False</Platform> + <Platform value="iOSSimulator">False</Platform> + <Platform value="Linux64">True</Platform> + <Platform value="OSX32">True</Platform> + <Platform value="Win32">True</Platform> + <Platform value="Win64">True</Platform> + </Platforms> + </BorlandProject> + <ProjectFileVersion>12</ProjectFileVersion> + </ProjectExtensions> + <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/> + <Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/> + <Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/> +</Project> diff --git a/Net/Demos/Old/CrossHttpConsole/uAppCfg.pas b/Net/Demos/Old/CrossHttpConsole/uAppCfg.pas index d1c1ce1..35af863 100644 --- a/Net/Demos/Old/CrossHttpConsole/uAppCfg.pas +++ b/Net/Demos/Old/CrossHttpConsole/uAppCfg.pas @@ -1,85 +1,85 @@ -unit uAppCfg; - -interface - -uses - System.Classes, System.SysUtils, System.IniFiles, System.Generics.Collections; - -type - TAppConfig = class - private - class var FInstance: TAppConfig; - class constructor Create; - class destructor Destroy; - private - FIni: TMemIniFile; - FDirMaps: TStrings; - function GetListenPort: Word; - function GetRootPath: string; - function GetDirMaps: TStrings; - public - constructor Create; - destructor Destroy; override; - - property ListenPort: Word read GetListenPort; - property DirMaps: TStrings read GetDirMaps; - property RootPath: string read GetRootPath; - end; - - function AppCfg: TAppConfig; - -implementation - -uses - Utils.Utils; - -function AppCfg: TAppConfig; -begin - Exit(TAppConfig.FInstance); -end; - -{ TAppConfig } - -constructor TAppConfig.Create; -begin - FIni := TMemIniFile.Create(TUtils.AppPath + TUtils.AppName + '.ini'); - FDirMaps := TStringList.Create; -end; - -destructor TAppConfig.Destroy; -begin - FreeAndNil(FIni); - FreeAndNil(FDirMaps); - inherited Destroy; -end; - -class constructor TAppConfig.Create; -begin - FInstance := TAppConfig.Create; -end; - -class destructor TAppConfig.Destroy; -begin - FreeAndNil(FInstance); -end; - -function TAppConfig.GetDirMaps: TStrings; -begin - if (FDirMaps.Count <= 0) then - FIni.ReadSectionValues('DirMaps', FDirMaps); - if (FDirMaps.Count <= 0) then - FDirMaps.Values['/'] := TUtils.AppPath; - Result := FDirMaps; -end; - -function TAppConfig.GetListenPort: Word; -begin - Result := FIni.ReadInteger('Server', 'Port', 8000); -end; - -function TAppConfig.GetRootPath: string; -begin - Result := FIni.ReadString('Server', 'RootPath', TUtils.AppPath); -end; - -end. +unit uAppCfg; + +interface + +uses + System.Classes, System.SysUtils, System.IniFiles, System.Generics.Collections; + +type + TAppConfig = class + private + class var FInstance: TAppConfig; + class constructor Create; + class destructor Destroy; + private + FIni: TMemIniFile; + FDirMaps: TStrings; + function GetListenPort: Word; + function GetRootPath: string; + function GetDirMaps: TStrings; + public + constructor Create; + destructor Destroy; override; + + property ListenPort: Word read GetListenPort; + property DirMaps: TStrings read GetDirMaps; + property RootPath: string read GetRootPath; + end; + + function AppCfg: TAppConfig; + +implementation + +uses + Utils.Utils; + +function AppCfg: TAppConfig; +begin + Exit(TAppConfig.FInstance); +end; + +{ TAppConfig } + +constructor TAppConfig.Create; +begin + FIni := TMemIniFile.Create(TUtils.AppPath + TUtils.AppName + '.ini'); + FDirMaps := TStringList.Create; +end; + +destructor TAppConfig.Destroy; +begin + FreeAndNil(FIni); + FreeAndNil(FDirMaps); + inherited Destroy; +end; + +class constructor TAppConfig.Create; +begin + FInstance := TAppConfig.Create; +end; + +class destructor TAppConfig.Destroy; +begin + FreeAndNil(FInstance); +end; + +function TAppConfig.GetDirMaps: TStrings; +begin + if (FDirMaps.Count <= 0) then + FIni.ReadSectionValues('DirMaps', FDirMaps); + if (FDirMaps.Count <= 0) then + FDirMaps.Values['/'] := TUtils.AppPath; + Result := FDirMaps; +end; + +function TAppConfig.GetListenPort: Word; +begin + Result := FIni.ReadInteger('Server', 'Port', 8000); +end; + +function TAppConfig.GetRootPath: string; +begin + Result := FIni.ReadString('Server', 'RootPath', TUtils.AppPath); +end; + +end. diff --git a/Net/Demos/Old/CrossHttpConsole/uDM.dfm b/Net/Demos/Old/CrossHttpConsole/uDM.dfm index 8b60dae..f4a3a47 100644 --- a/Net/Demos/Old/CrossHttpConsole/uDM.dfm +++ b/Net/Demos/Old/CrossHttpConsole/uDM.dfm @@ -1,7 +1,7 @@ -object DM: TDM - OldCreateOrder = False - OnCreate = DataModuleCreate - OnDestroy = DataModuleDestroy - Height = 150 - Width = 215 -end +object DM: TDM + OldCreateOrder = False + OnCreate = DataModuleCreate + OnDestroy = DataModuleDestroy + Height = 150 + Width = 215 +end diff --git a/Net/Demos/Old/CrossHttpConsole/uDM.pas b/Net/Demos/Old/CrossHttpConsole/uDM.pas index 922f512..1a65a10 100644 --- a/Net/Demos/Old/CrossHttpConsole/uDM.pas +++ b/Net/Demos/Old/CrossHttpConsole/uDM.pas @@ -1,462 +1,462 @@ -unit uDM; - -interface - -uses - Net.CrossSslSocket, - Net.CrossSslDemoCert, - System.SysUtils, System.Classes, System.Generics.Collections, - Net.CrossSocket.Base, - Net.CrossSocket, - Net.CrossHttpServer, - Net.CrossHttpMiddleware, - Net.CrossHttpUtils; - -type - IProgress = interface - ['{7372CE20-BBC7-4F35-932B-E148B52D89B1}'] - function GetID: Int64; - function GetMax: Single; - function GetPosition: Single; - function GetTimestamp: TDateTime; - - procedure SetMax(const AValue: Single); - procedure SetPosition(const AValue: Single); - - function ToString: string; - - property ID: Int64 read GetID; - property Max: Single read GetMax write SetMax; - property Position: Single read GetPosition write SetPosition; - property Timestamp: TDateTime read GetTimestamp; - end; - - TProgress = class(TInterfacedObject, IProgress) - private class var - FGlobalProgressID: Int64; - FGlobalProgress: TDictionary<Int64, IProgress>; - private - class constructor Create; - class destructor Destroy; - private - FID: Int64; - FMax: Single; - FPosition: Single; - FTimestamp: TDateTime; - - function GetID: Int64; - function GetMax: Single; - function GetPosition: Single; - function GetTimestamp: TDateTime; - - procedure SetMax(const AValue: Single); - procedure SetPosition(const AValue: Single); - public - constructor Create; - - function ToString: string; override; - - class function New: IProgress; - class function Get(const AID: Int64): IProgress; - class function Remove(const AID: Int64): Boolean; - - property ID: Int64 read GetID; - property Max: Single read GetMax write SetMax; - property Position: Single read GetPosition write SetPosition; - property Timestamp: TDateTime read GetTimestamp; - end; - - TDM = class(TDataModule) - procedure DataModuleCreate(Sender: TObject); - procedure DataModuleDestroy(Sender: TObject); - private - FHttpServer: ICrossHttpServer; - FShutdown: Boolean; - - procedure _CreateRouter; - procedure _CreateWatchThread; - - procedure _OnConnected(const Sender: TObject; const AConnection: ICrossConnection); - procedure _OnDisconnected(const Sender: TObject; const AConnection: ICrossConnection); - public - procedure Start; - procedure Stop; - - property HttpServer: ICrossHttpServer read FHttpServer; - end; - -var - DM: TDM; - -implementation - -uses - System.Hash, - Net.CrossHttpParams, System.Diagnostics, System.IOUtils, - System.RegularExpressions, Utils.RegEx, System.Threading, System.Math, - System.NetEncoding, Utils.Logger, Utils.Utils, uAppCfg; - -{%CLASSGROUP 'Vcl.Controls.TControl'} - -{$R *.dfm} - -{ TProgress } - -constructor TProgress.Create; -begin - FID := AtomicIncrement(FGlobalProgressID); -end; - -class constructor TProgress.Create; -begin - FGlobalProgress := TDictionary<Int64, IProgress>.Create; -end; - -class destructor TProgress.Destroy; -begin - FreeAndNil(FGlobalProgress); -end; - -class function TProgress.Get(const AID: Int64): IProgress; -begin - TMonitor.Enter(FGlobalProgress); - try - FGlobalProgress.TryGetValue(AID, Result); - finally - TMonitor.Exit(FGlobalProgress); - end; -end; - -function TProgress.GetID: Int64; -begin - Result := FID; -end; - -function TProgress.GetMax: Single; -begin - Result := FMax; -end; - -function TProgress.GetTimestamp: TDateTime; -begin - Result := FTimestamp; -end; - -class function TProgress.New: IProgress; -begin - Result := TProgress.Create; - - TMonitor.Enter(FGlobalProgress); - try - FGlobalProgress.AddOrSetValue(Result.ID, Result); - finally - TMonitor.Exit(FGlobalProgress); - end; -end; - -class function TProgress.Remove(const AID: Int64): Boolean; -begin - TMonitor.Enter(FGlobalProgress); - try - Result := FGlobalProgress.ContainsKey(AID); - if Result then - FGlobalProgress.Remove(AID); - finally - TMonitor.Exit(FGlobalProgress); - end; -end; - -function TProgress.GetPosition: Single; -begin - Result := FPosition; -end; - -procedure TProgress.SetMax(const AValue: Single); -begin - FMax := AValue; -end; - -procedure TProgress.SetPosition(const AValue: Single); -begin - if (AValue <= FMax) then - FPosition := AValue - else - FPosition := FMax; - FTimestamp := Now; -end; - -function TProgress.ToString: string; -begin - Result := Format('{"id":%d,"position":%f,"max":%f,"time":"%s"}', - [ - FID, - FPosition, - FMax, - FormatDateTime('YYYY-MM-DD HH:NN:SS:ZZZ', FTimestamp) - ]); -end; - -procedure TDM.DataModuleCreate(Sender: TObject); -begin - FHttpServer := TCrossHttpServer.Create(0, {$IFDEF __CROSS_SSL__}True{$ELSE}False{$ENDIF}); - {$IFDEF __CROSS_SSL__} - if FHttpServer.SSL then - begin - FHttpServer.SetCertificate(SSL_SERVER_CERT); - FHttpServer.SetPrivateKey(SSL_SERVER_PKEY); - end; - {$ENDIF} -// FHttpServer.Addr := IPv4_ALL; // IPv4 -// FHttpServer.Addr := IPv6_ALL; // IPv6 - FHttpServer.Addr := IPv4v6_ALL; // IPv4v6 - FHttpServer.Port := AppCfg.ListenPort; - FHttpServer.Compressible := True; - - FHttpServer.OnConnected := _OnConnected; - FHttpServer.OnDisconnected := _OnDisconnected; - - _CreateRouter; - _CreateWatchThread; -end; - -procedure TDM.DataModuleDestroy(Sender: TObject); -begin - FHttpServer := nil; -end; - -procedure TDM.Start; -begin - FHttpServer.Start; -end; - -procedure TDM.Stop; -begin - FHttpServer.Stop; - FShutdown := True; - Sleep(150); -end; - -procedure TDM._CreateRouter; -var - I: Integer; -begin -// FHttpServer.Sessions := TSessions.Create; - -// FHttpServer -// .Use('/login', TNetCrossMiddleware.AuthenticateDigest( -// procedure(ARequest: ICrossHttpRequest; const AUserName: string; var ACorrectPassword: string) -// begin -// if (AUserName = 'root') then -// ACorrectPassword := 'root'; -// end, -// '/login')) -// .Get('/login', -// procedure(ARequest: ICrossHttpRequest; AResponse: ICrossHttpResponse; var AHandled: Boolean) -// begin -// AResponse.Send('Login Success!'); -// end) -// .Use('/hello', TNetCrossMiddleware.AuthenticateBasic( -// procedure(ARequest: ICrossHttpRequest; const AUserName: string; var ACorrectPassword: string) -// begin -// if (AUserName = 'root') then -// ACorrectPassword := 'root'; -// end, -// '/hello')) -// .Get('/hello', -// procedure(ARequest: ICrossHttpRequest; AResponse: ICrossHttpResponse; var AHandled: Boolean) -// begin -// AHandled := False; -// AResponse.Send('Hello World111'); -// end) -// .Get('/hello', -// procedure(ARequest: ICrossHttpRequest; AResponse: ICrossHttpResponse; var AHandled: Boolean) -// begin -// AHandled := False; -// AResponse.Send('Hello World222'); -// end) - ; - - FHttpServer - .Get('/hello', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) - begin - AResponse.Send('Hello World'); - end) - .Get('/null', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) - begin - AResponse.Send(''); - end) - .Get('/yeah', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) - begin - AResponse.Send(TUtils.RandomStr( - 'abcdefghijklmnopqrstuvwxyz', - 256 * 1024)); - end) - .Get('/progress/:id(\d+)', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) - var - LProgID: Int64; - LProg: IProgress; - begin - LProgID := ARequest.Params['id'].ToInt64; - LProg := TProgress.Get(LProgID); - - if (LProg <> nil) then - AResponse.Json(LProg.ToString) - else - AResponse.Send('非法id'); - end) - .Delete('/progress/:id(\d+)', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) - var - LProgID: Int64; - begin - LProgID := ARequest.Params['id'].ToInt64; - - if TProgress.Remove(LProgID) then - AResponse.Send('删除任务进度成功') - else - AResponse.Send('非法id'); - end) - .Get('task', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) - begin - TTask.Run( - procedure - var - I: Integer; - LWatch: TStopwatch; - LSeconds: Integer; - LProg: IProgress; - begin - LProg := TProgress.New; - LProg.Max := 10; - LProg.Position := 0; - - AResponse.Json(LProg.ToString); - - LWatch := TStopwatch.StartNew; - for I := 1 to 10 do - begin - LSeconds := RandomRange(1, 10 + 1); - Sleep(LSeconds * 500); - - LProg.Position := I; - end; - LWatch.Stop; - end); - end) - .Dir('/static', 'D:\') - .Dir('/g', 'G:\') - .Get('/file', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) - var - LStream: TStream; - begin - LStream := TFile.OpenRead('d:\2.txt'); - AResponse.ContentType := TMediaType.TEXT_HTML; - AResponse.SendNoCompress(LStream, - StrToInt64Def(ARequest.Query['pos'], 0), - StrToInt64Def(ARequest.Query['count'], 0), - procedure(const AConnection: ICrossConnection; const ASuccess: Boolean) - begin - FreeAndNil(LStream); - end); - end) - .Get('/stream', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) - var - LStream: TMemoryStream; - begin - LStream := TMemoryStream.Create; - LStream.LoadFromFile('d:\2.txt'); - AResponse.ContentType := TMediaType.TEXT_HTML; - AResponse.SendZCompress(LStream, - StrToInt64Def(ARequest.Query['pos'], 0), - StrToInt64Def(ARequest.Query['count'], 0), - TCompressType.ctGZip, - procedure(const AConnection: ICrossConnection; const ASuccess: Boolean) - begin - FreeAndNil(LStream); - end); - end) - .Get('/bytes', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) - var - LBytes: TBytes; - begin - LBytes := TFile.ReadAllBytes('d:\2.txt'); - AResponse.ContentType := TMediaType.TEXT_HTML; - AResponse.SendNoCompress(LBytes, - StrToInt64Def(ARequest.Query['pos'], 0), - StrToInt64Def(ARequest.Query['count'], 0), - procedure(const AConnection: ICrossConnection; const ASuccess: Boolean) - begin - LBytes := nil; - end); - end) - .Post('/post', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) - var - LResult: string; - begin - case ARequest.BodyType of - btNone: - LResult := 'Body是空的'; - - btUrlEncoded: - LResult := 'Body第一个参数是: ' + (ARequest.Body as THttpUrlParams).Items[0].Name + '=' + (ARequest.Body as THttpUrlParams).Items[0].Value; - - btMultiPart: - LResult := 'Body第一个参数是: ' + (ARequest.Body as THttpMultiPartFormData).Items[0].Name + '=' + (ARequest.Body as THttpMultiPartFormData).Items[0].AsString; - - btBinary: - LResult := 'Body是二进制数据'; - end; - - AResponse.Send(LResult); - end) - ; - - for I := 0 to AppCfg.DirMaps.Count - 1 do - begin - FHttpServer.Dir( - AppCfg.DirMaps.Names[I], - AppCfg.DirMaps.ValueFromIndex[I]); - end; -end; - -procedure TDM._CreateWatchThread; -begin - TThread.CreateAnonymousThread( - procedure - var - LLastConCount, LCurConCount: Integer; - begin - LLastConCount := 0; - while not FShutdown do - begin - LCurConCount := FHttpServer.ConnectionsCount; - if (LCurConCount <> LLastConCount) then - begin - LLastConCount := LCurConCount; - Writeln('conn count:', LCurConCount); - end; - Sleep(100); - end; - end).Start; -end; - -procedure TDM._OnConnected(const Sender: TObject; const AConnection: ICrossConnection); -begin -// if (FHttpServer.ConnectionsCount > 100) then -// AConnection.Close; -end; - -procedure TDM._OnDisconnected(const Sender: TObject; const AConnection: ICrossConnection); -begin -end; - -end. +unit uDM; + +interface + +uses + Net.CrossSslSocket, + Net.CrossSslDemoCert, + System.SysUtils, System.Classes, System.Generics.Collections, + Net.CrossSocket.Base, + Net.CrossSocket, + Net.CrossHttpServer, + Net.CrossHttpMiddleware, + Net.CrossHttpUtils; + +type + IProgress = interface + ['{7372CE20-BBC7-4F35-932B-E148B52D89B1}'] + function GetID: Int64; + function GetMax: Single; + function GetPosition: Single; + function GetTimestamp: TDateTime; + + procedure SetMax(const AValue: Single); + procedure SetPosition(const AValue: Single); + + function ToString: string; + + property ID: Int64 read GetID; + property Max: Single read GetMax write SetMax; + property Position: Single read GetPosition write SetPosition; + property Timestamp: TDateTime read GetTimestamp; + end; + + TProgress = class(TInterfacedObject, IProgress) + private class var + FGlobalProgressID: Int64; + FGlobalProgress: TDictionary<Int64, IProgress>; + private + class constructor Create; + class destructor Destroy; + private + FID: Int64; + FMax: Single; + FPosition: Single; + FTimestamp: TDateTime; + + function GetID: Int64; + function GetMax: Single; + function GetPosition: Single; + function GetTimestamp: TDateTime; + + procedure SetMax(const AValue: Single); + procedure SetPosition(const AValue: Single); + public + constructor Create; + + function ToString: string; override; + + class function New: IProgress; + class function Get(const AID: Int64): IProgress; + class function Remove(const AID: Int64): Boolean; + + property ID: Int64 read GetID; + property Max: Single read GetMax write SetMax; + property Position: Single read GetPosition write SetPosition; + property Timestamp: TDateTime read GetTimestamp; + end; + + TDM = class(TDataModule) + procedure DataModuleCreate(Sender: TObject); + procedure DataModuleDestroy(Sender: TObject); + private + FHttpServer: ICrossHttpServer; + FShutdown: Boolean; + + procedure _CreateRouter; + procedure _CreateWatchThread; + + procedure _OnConnected(const Sender: TObject; const AConnection: ICrossConnection); + procedure _OnDisconnected(const Sender: TObject; const AConnection: ICrossConnection); + public + procedure Start; + procedure Stop; + + property HttpServer: ICrossHttpServer read FHttpServer; + end; + +var + DM: TDM; + +implementation + +uses + System.Hash, + Net.CrossHttpParams, System.Diagnostics, System.IOUtils, + System.RegularExpressions, Utils.RegEx, System.Threading, System.Math, + System.NetEncoding, Utils.Logger, Utils.Utils, uAppCfg; + +{%CLASSGROUP 'Vcl.Controls.TControl'} + +{$R *.dfm} + +{ TProgress } + +constructor TProgress.Create; +begin + FID := AtomicIncrement(FGlobalProgressID); +end; + +class constructor TProgress.Create; +begin + FGlobalProgress := TDictionary<Int64, IProgress>.Create; +end; + +class destructor TProgress.Destroy; +begin + FreeAndNil(FGlobalProgress); +end; + +class function TProgress.Get(const AID: Int64): IProgress; +begin + TMonitor.Enter(FGlobalProgress); + try + FGlobalProgress.TryGetValue(AID, Result); + finally + TMonitor.Exit(FGlobalProgress); + end; +end; + +function TProgress.GetID: Int64; +begin + Result := FID; +end; + +function TProgress.GetMax: Single; +begin + Result := FMax; +end; + +function TProgress.GetTimestamp: TDateTime; +begin + Result := FTimestamp; +end; + +class function TProgress.New: IProgress; +begin + Result := TProgress.Create; + + TMonitor.Enter(FGlobalProgress); + try + FGlobalProgress.AddOrSetValue(Result.ID, Result); + finally + TMonitor.Exit(FGlobalProgress); + end; +end; + +class function TProgress.Remove(const AID: Int64): Boolean; +begin + TMonitor.Enter(FGlobalProgress); + try + Result := FGlobalProgress.ContainsKey(AID); + if Result then + FGlobalProgress.Remove(AID); + finally + TMonitor.Exit(FGlobalProgress); + end; +end; + +function TProgress.GetPosition: Single; +begin + Result := FPosition; +end; + +procedure TProgress.SetMax(const AValue: Single); +begin + FMax := AValue; +end; + +procedure TProgress.SetPosition(const AValue: Single); +begin + if (AValue <= FMax) then + FPosition := AValue + else + FPosition := FMax; + FTimestamp := Now; +end; + +function TProgress.ToString: string; +begin + Result := Format('{"id":%d,"position":%f,"max":%f,"time":"%s"}', + [ + FID, + FPosition, + FMax, + FormatDateTime('YYYY-MM-DD HH:NN:SS:ZZZ', FTimestamp) + ]); +end; + +procedure TDM.DataModuleCreate(Sender: TObject); +begin + FHttpServer := TCrossHttpServer.Create(0, {$IFDEF __CROSS_SSL__}True{$ELSE}False{$ENDIF}); + {$IFDEF __CROSS_SSL__} + if FHttpServer.SSL then + begin + FHttpServer.SetCertificate(SSL_SERVER_CERT); + FHttpServer.SetPrivateKey(SSL_SERVER_PKEY); + end; + {$ENDIF} +// FHttpServer.Addr := IPv4_ALL; // IPv4 +// FHttpServer.Addr := IPv6_ALL; // IPv6 + FHttpServer.Addr := IPv4v6_ALL; // IPv4v6 + FHttpServer.Port := AppCfg.ListenPort; + FHttpServer.Compressible := True; + + FHttpServer.OnConnected := _OnConnected; + FHttpServer.OnDisconnected := _OnDisconnected; + + _CreateRouter; + _CreateWatchThread; +end; + +procedure TDM.DataModuleDestroy(Sender: TObject); +begin + FHttpServer := nil; +end; + +procedure TDM.Start; +begin + FHttpServer.Start; +end; + +procedure TDM.Stop; +begin + FHttpServer.Stop; + FShutdown := True; + Sleep(150); +end; + +procedure TDM._CreateRouter; +var + I: Integer; +begin +// FHttpServer.Sessions := TSessions.Create; + +// FHttpServer +// .Use('/login', TNetCrossMiddleware.AuthenticateDigest( +// procedure(ARequest: ICrossHttpRequest; const AUserName: string; var ACorrectPassword: string) +// begin +// if (AUserName = 'root') then +// ACorrectPassword := 'root'; +// end, +// '/login')) +// .Get('/login', +// procedure(ARequest: ICrossHttpRequest; AResponse: ICrossHttpResponse; var AHandled: Boolean) +// begin +// AResponse.Send('Login Success!'); +// end) +// .Use('/hello', TNetCrossMiddleware.AuthenticateBasic( +// procedure(ARequest: ICrossHttpRequest; const AUserName: string; var ACorrectPassword: string) +// begin +// if (AUserName = 'root') then +// ACorrectPassword := 'root'; +// end, +// '/hello')) +// .Get('/hello', +// procedure(ARequest: ICrossHttpRequest; AResponse: ICrossHttpResponse; var AHandled: Boolean) +// begin +// AHandled := False; +// AResponse.Send('Hello World111'); +// end) +// .Get('/hello', +// procedure(ARequest: ICrossHttpRequest; AResponse: ICrossHttpResponse; var AHandled: Boolean) +// begin +// AHandled := False; +// AResponse.Send('Hello World222'); +// end) + ; + + FHttpServer + .Get('/hello', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) + begin + AResponse.Send('Hello World'); + end) + .Get('/null', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) + begin + AResponse.Send(''); + end) + .Get('/yeah', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) + begin + AResponse.Send(TUtils.RandomStr( + 'abcdefghijklmnopqrstuvwxyz', + 256 * 1024)); + end) + .Get('/progress/:id(\d+)', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) + var + LProgID: Int64; + LProg: IProgress; + begin + LProgID := ARequest.Params['id'].ToInt64; + LProg := TProgress.Get(LProgID); + + if (LProg <> nil) then + AResponse.Json(LProg.ToString) + else + AResponse.Send('非法id'); + end) + .Delete('/progress/:id(\d+)', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) + var + LProgID: Int64; + begin + LProgID := ARequest.Params['id'].ToInt64; + + if TProgress.Remove(LProgID) then + AResponse.Send('删除任务进度成功') + else + AResponse.Send('非法id'); + end) + .Get('task', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) + begin + TTask.Run( + procedure + var + I: Integer; + LWatch: TStopwatch; + LSeconds: Integer; + LProg: IProgress; + begin + LProg := TProgress.New; + LProg.Max := 10; + LProg.Position := 0; + + AResponse.Json(LProg.ToString); + + LWatch := TStopwatch.StartNew; + for I := 1 to 10 do + begin + LSeconds := RandomRange(1, 10 + 1); + Sleep(LSeconds * 500); + + LProg.Position := I; + end; + LWatch.Stop; + end); + end) + .Dir('/static', 'D:\') + .Dir('/g', 'G:\') + .Get('/file', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) + var + LStream: TStream; + begin + LStream := TFile.OpenRead('d:\2.txt'); + AResponse.ContentType := TMediaType.TEXT_HTML; + AResponse.SendNoCompress(LStream, + StrToInt64Def(ARequest.Query['pos'], 0), + StrToInt64Def(ARequest.Query['count'], 0), + procedure(const AConnection: ICrossConnection; const ASuccess: Boolean) + begin + FreeAndNil(LStream); + end); + end) + .Get('/stream', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) + var + LStream: TMemoryStream; + begin + LStream := TMemoryStream.Create; + LStream.LoadFromFile('d:\2.txt'); + AResponse.ContentType := TMediaType.TEXT_HTML; + AResponse.SendZCompress(LStream, + StrToInt64Def(ARequest.Query['pos'], 0), + StrToInt64Def(ARequest.Query['count'], 0), + TCompressType.ctGZip, + procedure(const AConnection: ICrossConnection; const ASuccess: Boolean) + begin + FreeAndNil(LStream); + end); + end) + .Get('/bytes', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) + var + LBytes: TBytes; + begin + LBytes := TFile.ReadAllBytes('d:\2.txt'); + AResponse.ContentType := TMediaType.TEXT_HTML; + AResponse.SendNoCompress(LBytes, + StrToInt64Def(ARequest.Query['pos'], 0), + StrToInt64Def(ARequest.Query['count'], 0), + procedure(const AConnection: ICrossConnection; const ASuccess: Boolean) + begin + LBytes := nil; + end); + end) + .Post('/post', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse) + var + LResult: string; + begin + case ARequest.BodyType of + btNone: + LResult := 'Body是空的'; + + btUrlEncoded: + LResult := 'Body第一个参数是: ' + (ARequest.Body as THttpUrlParams).Items[0].Name + '=' + (ARequest.Body as THttpUrlParams).Items[0].Value; + + btMultiPart: + LResult := 'Body第一个参数是: ' + (ARequest.Body as THttpMultiPartFormData).Items[0].Name + '=' + (ARequest.Body as THttpMultiPartFormData).Items[0].AsString; + + btBinary: + LResult := 'Body是二进制数据'; + end; + + AResponse.Send(LResult); + end) + ; + + for I := 0 to AppCfg.DirMaps.Count - 1 do + begin + FHttpServer.Dir( + AppCfg.DirMaps.Names[I], + AppCfg.DirMaps.ValueFromIndex[I]); + end; +end; + +procedure TDM._CreateWatchThread; +begin + TThread.CreateAnonymousThread( + procedure + var + LLastConCount, LCurConCount: Integer; + begin + LLastConCount := 0; + while not FShutdown do + begin + LCurConCount := FHttpServer.ConnectionsCount; + if (LCurConCount <> LLastConCount) then + begin + LLastConCount := LCurConCount; + Writeln('conn count:', LCurConCount); + end; + Sleep(100); + end; + end).Start; +end; + +procedure TDM._OnConnected(const Sender: TObject; const AConnection: ICrossConnection); +begin +// if (FHttpServer.ConnectionsCount > 100) then +// AConnection.Close; +end; + +procedure TDM._OnDisconnected(const Sender: TObject; const AConnection: ICrossConnection); +begin +end; + +end. diff --git a/Net/Demos/Old/CrossWebSocket/CrossWebSocketServer.dpr b/Net/Demos/Old/CrossWebSocket/CrossWebSocketServer.dpr index be2a46e..b83e8e9 100644 --- a/Net/Demos/Old/CrossWebSocket/CrossWebSocketServer.dpr +++ b/Net/Demos/Old/CrossWebSocket/CrossWebSocketServer.dpr @@ -1,14 +1,14 @@ -program CrossWebSocketServer; - -uses - System.StartUpCopy, - FMX.Forms, - uCrossWebSocketServerDemo in 'uCrossWebSocketServerDemo.pas' {fmCrossWebSocketServerDemo}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TfmCrossWebSocketServerDemo, fmCrossWebSocketServerDemo); - Application.Run; -end. +program CrossWebSocketServer; + +uses + System.StartUpCopy, + FMX.Forms, + uCrossWebSocketServerDemo in 'uCrossWebSocketServerDemo.pas' {fmCrossWebSocketServerDemo}; + +{$R *.res} + +begin + Application.Initialize; + Application.CreateForm(TfmCrossWebSocketServerDemo, fmCrossWebSocketServerDemo); + Application.Run; +end. diff --git a/Net/Demos/Old/CrossWebSocket/CrossWebSocketServer.dproj b/Net/Demos/Old/CrossWebSocket/CrossWebSocketServer.dproj index c185f76..ac53a12 100644 --- a/Net/Demos/Old/CrossWebSocket/CrossWebSocketServer.dproj +++ b/Net/Demos/Old/CrossWebSocket/CrossWebSocketServer.dproj @@ -1,811 +1,811 @@ -<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup> - <ProjectGuid>{00BB3B9E-B439-4377-A203-3C4F0C15B1F9}</ProjectGuid> - <ProjectVersion>18.4</ProjectVersion> - <FrameworkType>FMX</FrameworkType> - <MainSource>CrossWebSocketServer.dpr</MainSource> - <Base>True</Base> - <Config Condition="'$(Config)'==''">Debug</Config> - <Platform Condition="'$(Platform)'==''">Win32</Platform> - <TargetedPlatforms>1119</TargetedPlatforms> - <AppType>Application</AppType> - </PropertyGroup> - <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''"> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''"> - <Base_Android>true</Base_Android> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='iOSDevice32' and '$(Base)'=='true') or '$(Base_iOSDevice32)'!=''"> - <Base_iOSDevice32>true</Base_iOSDevice32> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''"> - <Base_iOSDevice64>true</Base_iOSDevice64> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='iOSSimulator' and '$(Base)'=='true') or '$(Base_iOSSimulator)'!=''"> - <Base_iOSSimulator>true</Base_iOSSimulator> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Base)'=='true') or '$(Base_OSX32)'!=''"> - <Base_OSX32>true</Base_OSX32> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''"> - <Base_Win32>true</Base_Win32> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''"> - <Base_Win64>true</Base_Win64> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''"> - <Cfg_1>true</Cfg_1> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''"> - <Cfg_1_Win32>true</Cfg_1_Win32> - <CfgParent>Cfg_1</CfgParent> - <Cfg_1>true</Cfg_1> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''"> - <Cfg_1_Win64>true</Cfg_1_Win64> - <CfgParent>Cfg_1</CfgParent> - <Cfg_1>true</Cfg_1> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''"> - <Cfg_2>true</Cfg_2> - <CfgParent>Base</CfgParent> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''"> - <Cfg_2_Win32>true</Cfg_2_Win32> - <CfgParent>Cfg_2</CfgParent> - <Cfg_2>true</Cfg_2> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''"> - <Cfg_2_Win64>true</Cfg_2_Win64> - <CfgParent>Cfg_2</CfgParent> - <Cfg_2>true</Cfg_2> - <Base>true</Base> - </PropertyGroup> - <PropertyGroup Condition="'$(Base)'!=''"> - <DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput> - <DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput> - <DCC_E>false</DCC_E> - <DCC_N>false</DCC_N> - <DCC_S>false</DCC_S> - <DCC_F>false</DCC_F> - <DCC_K>false</DCC_K> - <DCC_UsePackage>RESTComponents;FlexCel_Pdf;emsclientfiredac;FlexCel_Report;FireDACIBDriver;emsclient;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;FireDAC;FlexCel_XlsAdapter;FireDACSqliteDriver;soaprtl;FlexCel_Core;soapmidas;FlexCel_Render;$(DCC_UsePackage)</DCC_UsePackage> - <DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace> - <AUP_ACCESS_COARSE_LOCATION>true</AUP_ACCESS_COARSE_LOCATION> - <AUP_ACCESS_FINE_LOCATION>true</AUP_ACCESS_FINE_LOCATION> - <AUP_CALL_PHONE>true</AUP_CALL_PHONE> - <AUP_CAMERA>true</AUP_CAMERA> - <AUP_INTERNET>true</AUP_INTERNET> - <AUP_READ_CALENDAR>true</AUP_READ_CALENDAR> - <AUP_READ_EXTERNAL_STORAGE>true</AUP_READ_EXTERNAL_STORAGE> - <AUP_WRITE_CALENDAR>true</AUP_WRITE_CALENDAR> - <AUP_WRITE_EXTERNAL_STORAGE>true</AUP_WRITE_EXTERNAL_STORAGE> - <AUP_READ_PHONE_STATE>true</AUP_READ_PHONE_STATE> - <Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon> - <Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns> - <SanitizedProjectName>CrossWebSocketServer</SanitizedProjectName> - <DCC_Define>__CROSS_SSL__x;__MBED_TLS__x;$(DCC_Define)</DCC_Define> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_Android)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;FMX_FlexCel_Core;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;Marvin.Comps.MDL.General;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;TeeBI;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;FMX_FlexCel_Components;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;$(DCC_UsePackage)</DCC_UsePackage> - <VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys> - <BT_BuildType>Debug</BT_BuildType> - <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> - <Android_LauncherIcon36>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png</Android_LauncherIcon36> - <Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48> - <Android_LauncherIcon72>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png</Android_LauncherIcon72> - <Android_LauncherIcon96>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png</Android_LauncherIcon96> - <Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144> - <Android_SplashImage426>$(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png</Android_SplashImage426> - <Android_SplashImage470>$(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png</Android_SplashImage470> - <Android_SplashImage640>$(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png</Android_SplashImage640> - <Android_SplashImage960>$(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png</Android_SplashImage960> - <EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar</EnabledSysJars> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_iOSDevice32)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;FMX_FlexCel_Core;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;FMX_FlexCel_Components;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage> - <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera;CFBundleShortVersionString=1.0.0</VerInfo_Keys> - <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily> - <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> - <BT_BuildType>Debug</BT_BuildType> - <VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId> - <iPhone_AppIcon57>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png</iPhone_AppIcon57> - <iPhone_AppIcon60>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png</iPhone_AppIcon60> - <iPhone_AppIcon87>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png</iPhone_AppIcon87> - <iPhone_AppIcon114>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png</iPhone_AppIcon114> - <iPhone_AppIcon120>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png</iPhone_AppIcon120> - <iPhone_AppIcon180>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png</iPhone_AppIcon180> - <iPhone_Launch320>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png</iPhone_Launch320> - <iPhone_Launch640>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png</iPhone_Launch640> - <iPhone_Launch640x1136>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png</iPhone_Launch640x1136> - <iPhone_Launch750>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png</iPhone_Launch750> - <iPhone_Launch1242>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png</iPhone_Launch1242> - <iPhone_Launch2208>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png</iPhone_Launch2208> - <iPhone_Spotlight29>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png</iPhone_Spotlight29> - <iPhone_Spotlight40>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png</iPhone_Spotlight40> - <iPhone_Spotlight58>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png</iPhone_Spotlight58> - <iPhone_Spotlight80>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png</iPhone_Spotlight80> - <iPad_AppIcon72>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png</iPad_AppIcon72> - <iPad_AppIcon76>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png</iPad_AppIcon76> - <iPad_AppIcon144>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png</iPad_AppIcon144> - <iPad_AppIcon152>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png</iPad_AppIcon152> - <iPad_Launch768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png</iPad_Launch768> - <iPad_Launch768x1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png</iPad_Launch768x1024> - <iPad_Launch1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png</iPad_Launch1024> - <iPad_Launch1024x768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png</iPad_Launch1024x768> - <iPad_Launch1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png</iPad_Launch1536> - <iPad_Launch1536x2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png</iPad_Launch1536x2048> - <iPad_Launch2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png</iPad_Launch2048> - <iPad_Launch2048x1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png</iPad_Launch2048x1536> - <iPad_SpotLight40>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png</iPad_SpotLight40> - <iPad_SpotLight50>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png</iPad_SpotLight50> - <iPad_SpotLight80>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png</iPad_SpotLight80> - <iPad_SpotLight100>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png</iPad_SpotLight100> - <iPad_Setting29>$(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png</iPad_Setting29> - <iPad_Setting58>$(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png</iPad_Setting58> - <iPhone_Launch1125>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png</iPhone_Launch1125> - <iPhone_Launch2436>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png</iPhone_Launch2436> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_iOSDevice64)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;FMX_FlexCel_Core;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;FMX_FlexCel_Components;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage> - <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera;CFBundleShortVersionString=1.0.0</VerInfo_Keys> - <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily> - <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> - <BT_BuildType>Debug</BT_BuildType> - <VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId> - <iPhone_AppIcon57>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png</iPhone_AppIcon57> - <iPhone_AppIcon60>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png</iPhone_AppIcon60> - <iPhone_AppIcon87>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png</iPhone_AppIcon87> - <iPhone_AppIcon114>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png</iPhone_AppIcon114> - <iPhone_AppIcon120>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png</iPhone_AppIcon120> - <iPhone_AppIcon180>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png</iPhone_AppIcon180> - <iPhone_Launch320>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png</iPhone_Launch320> - <iPhone_Launch640>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png</iPhone_Launch640> - <iPhone_Launch640x1136>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png</iPhone_Launch640x1136> - <iPhone_Launch750>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png</iPhone_Launch750> - <iPhone_Launch1242>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png</iPhone_Launch1242> - <iPhone_Launch2208>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png</iPhone_Launch2208> - <iPhone_Spotlight29>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png</iPhone_Spotlight29> - <iPhone_Spotlight40>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png</iPhone_Spotlight40> - <iPhone_Spotlight58>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png</iPhone_Spotlight58> - <iPhone_Spotlight80>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png</iPhone_Spotlight80> - <iPad_AppIcon72>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png</iPad_AppIcon72> - <iPad_AppIcon76>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png</iPad_AppIcon76> - <iPad_AppIcon144>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png</iPad_AppIcon144> - <iPad_AppIcon152>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png</iPad_AppIcon152> - <iPad_Launch768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png</iPad_Launch768> - <iPad_Launch768x1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png</iPad_Launch768x1024> - <iPad_Launch1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png</iPad_Launch1024> - <iPad_Launch1024x768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png</iPad_Launch1024x768> - <iPad_Launch1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png</iPad_Launch1536> - <iPad_Launch1536x2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png</iPad_Launch1536x2048> - <iPad_Launch2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png</iPad_Launch2048> - <iPad_Launch2048x1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png</iPad_Launch2048x1536> - <iPad_SpotLight40>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png</iPad_SpotLight40> - <iPad_SpotLight50>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png</iPad_SpotLight50> - <iPad_SpotLight80>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png</iPad_SpotLight80> - <iPad_SpotLight100>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png</iPad_SpotLight100> - <iPad_Setting29>$(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png</iPad_Setting29> - <iPad_Setting58>$(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png</iPad_Setting58> - <iPhone_Launch1125>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png</iPhone_Launch1125> - <iPhone_Launch2436>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png</iPhone_Launch2436> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_iOSSimulator)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;FMX_FlexCel_Core;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;TeeBI;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;FMX_FlexCel_Components;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage> - <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera;CFBundleShortVersionString=1.0.0</VerInfo_Keys> - <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily> - <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> - <iPhone_AppIcon57>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png</iPhone_AppIcon57> - <iPhone_AppIcon60>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png</iPhone_AppIcon60> - <iPhone_AppIcon87>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png</iPhone_AppIcon87> - <iPhone_AppIcon114>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png</iPhone_AppIcon114> - <iPhone_AppIcon120>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png</iPhone_AppIcon120> - <iPhone_AppIcon180>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png</iPhone_AppIcon180> - <iPhone_Launch320>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png</iPhone_Launch320> - <iPhone_Launch640>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png</iPhone_Launch640> - <iPhone_Launch640x1136>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png</iPhone_Launch640x1136> - <iPhone_Launch750>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png</iPhone_Launch750> - <iPhone_Launch1242>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png</iPhone_Launch1242> - <iPhone_Launch2208>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png</iPhone_Launch2208> - <iPhone_Spotlight29>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png</iPhone_Spotlight29> - <iPhone_Spotlight40>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png</iPhone_Spotlight40> - <iPhone_Spotlight58>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png</iPhone_Spotlight58> - <iPhone_Spotlight80>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png</iPhone_Spotlight80> - <iPad_AppIcon72>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png</iPad_AppIcon72> - <iPad_AppIcon76>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png</iPad_AppIcon76> - <iPad_AppIcon144>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png</iPad_AppIcon144> - <iPad_AppIcon152>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png</iPad_AppIcon152> - <iPad_Launch768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png</iPad_Launch768> - <iPad_Launch768x1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png</iPad_Launch768x1024> - <iPad_Launch1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png</iPad_Launch1024> - <iPad_Launch1024x768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png</iPad_Launch1024x768> - <iPad_Launch1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png</iPad_Launch1536> - <iPad_Launch1536x2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png</iPad_Launch1536x2048> - <iPad_Launch2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png</iPad_Launch2048> - <iPad_Launch2048x1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png</iPad_Launch2048x1536> - <iPad_SpotLight40>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png</iPad_SpotLight40> - <iPad_SpotLight50>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png</iPad_SpotLight50> - <iPad_SpotLight80>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png</iPad_SpotLight80> - <iPad_SpotLight100>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png</iPad_SpotLight100> - <iPad_Setting29>$(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png</iPad_Setting29> - <iPad_Setting58>$(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png</iPad_Setting58> - <iPhone_Launch1125>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png</iPhone_Launch1125> - <iPhone_Launch2436>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png</iPhone_Launch2436> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_OSX32)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DataSnapServerMidas;DBXInterBaseDriver;FMX_FlexCel_Core;DataSnapFireDAC;tethering;FireDACMSSQLDriver;bindcompfmx;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;TeeBI;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;DataSnapServer;xmlrtl;DataSnapNativeClient;ibxbindings;fmxobj;FireDACDSDriver;rtl;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;bindcomp;DBXInformixDriver;IndyIPClient;FMX_FlexCel_Components;dbxcds;FireDACODBCDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;inetdbxpress;fmxase;$(DCC_UsePackage)</DCC_UsePackage> - <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;CFBundleShortVersionString=1.0.0</VerInfo_Keys> - <BT_BuildType>Debug</BT_BuildType> - <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_Win32)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;TVidGrab;vclactnband;FMX_FlexCel_Core;vclFireDAC;vcl.gtxControlsD102;DataSnapFireDAC;tethering;svnui;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;FMX.dclgtxControlsD102;vcltouch;VCLChartTeeBI;vcldb;bindcompfmx;Intraweb;svn;DBXOracleDriver;SKIA_FlexCel_Core;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;VCL_FlexCel_Components;Marvin.Comps.MDL.General;vclib;FireDACDBXDriver;dbexpress;IndyCore;vcl.gtxDBControlsD102;vclx;dsnap;DataSnapCommon;TeeBI;FMXTeeBI;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;RazorPackageR102;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;FireDACInfxDriver;fmxFireDAC;vclimg;ZrcCrossD102;TeeDB;Vcl.gtxStdCtrlsD102;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;FmxPkgD102;DBXOdbcDriver;FireDACTDataDriver;FMXTee;FMXChartTeeBI;VCLTeeBI;DbxCommonDriver;fmx.gtxControlsD102;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;ibxbindings;fmxobj;FireDACDSDriver;rtl;vclwinx;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;DCEF_D102;FMX_FlexCel_Components;dbxcds;VclSmp;VCL_FlexCel_Core;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;inetdbxpress;vcl.gtxReportExportD102;paxcomp_x10_2;fmxase;$(DCC_UsePackage)</DCC_UsePackage> - <DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace> - <BT_BuildType>Debug</BT_BuildType> - <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> - <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys> - <VerInfo_Locale>1033</VerInfo_Locale> - <Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File> - <UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44> - <UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150> - </PropertyGroup> - <PropertyGroup Condition="'$(Base_Win64)'!=''"> - <DCC_UsePackage>DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;TVidGrab;vclactnband;FMX_FlexCel_Core;vclFireDAC;DataSnapFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;VCLChartTeeBI;vcldb;bindcompfmx;Intraweb;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;VCL_FlexCel_Components;Marvin.Comps.MDL.General;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;TeeBI;FMXTeeBI;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;FireDACInfxDriver;fmxFireDAC;vclimg;TeeDB;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;VCLTeeBI;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;ibxbindings;fmxobj;FireDACDSDriver;rtl;vclwinx;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;FMX_FlexCel_Components;dbxcds;VclSmp;VCL_FlexCel_Core;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;inetdbxpress;fmxase;$(DCC_UsePackage)</DCC_UsePackage> - <DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace> - <BT_BuildType>Debug</BT_BuildType> - <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> - <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys> - <VerInfo_Locale>1033</VerInfo_Locale> - <Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File> - <UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44> - <UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_1)'!=''"> - <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define> - <DCC_DebugDCUs>true</DCC_DebugDCUs> - <DCC_Optimize>false</DCC_Optimize> - <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames> - <DCC_DebugInfoInExe>true</DCC_DebugInfoInExe> - <DCC_RemoteDebug>true</DCC_RemoteDebug> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_1_Win32)'!=''"> - <DCC_RemoteDebug>false</DCC_RemoteDebug> - <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> - <AppEnableHighDPI>true</AppEnableHighDPI> - <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> - <VerInfo_Locale>1033</VerInfo_Locale> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_1_Win64)'!=''"> - <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> - <AppEnableHighDPI>true</AppEnableHighDPI> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_2)'!=''"> - <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols> - <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define> - <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo> - <DCC_DebugInformation>0</DCC_DebugInformation> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''"> - <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> - <AppEnableHighDPI>true</AppEnableHighDPI> - </PropertyGroup> - <PropertyGroup Condition="'$(Cfg_2_Win64)'!=''"> - <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> - <AppEnableHighDPI>true</AppEnableHighDPI> - </PropertyGroup> - <ItemGroup> - <DelphiCompile Include="$(MainSource)"> - <MainSource>MainSource</MainSource> - </DelphiCompile> - <DCCReference Include="uCrossWebSocketServerDemo.pas"> - <Form>fmCrossWebSocketServerDemo</Form> - <FormType>fmx</FormType> - </DCCReference> - <BuildConfiguration Include="Release"> - <Key>Cfg_2</Key> - <CfgParent>Base</CfgParent> - </BuildConfiguration> - <BuildConfiguration Include="Base"> - <Key>Base</Key> - </BuildConfiguration> - <BuildConfiguration Include="Debug"> - <Key>Cfg_1</Key> - <CfgParent>Base</CfgParent> - </BuildConfiguration> - </ItemGroup> - <ProjectExtensions> - <Borland.Personality>Delphi.Personality.12</Borland.Personality> - <Borland.ProjectType>Application</Borland.ProjectType> - <BorlandProject> - <Delphi.Personality> - <Source> - <Source Name="MainSource">CrossWebSocketServer.dpr</Source> - </Source> - <Excluded_Packages> - <Excluded_Packages Name="$(BDSBIN)\bcboffice2k250.bpl">Embarcadero C++Builder Office 2000 Servers Package</Excluded_Packages> - <Excluded_Packages Name="$(BDSBIN)\bcbofficexp250.bpl">Embarcadero C++Builder Office XP Servers Package</Excluded_Packages> - <Excluded_Packages Name="$(BDSBIN)\dcloffice2k250.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages> - <Excluded_Packages Name="$(BDSBIN)\dclofficexp250.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages> - </Excluded_Packages> - </Delphi.Personality> - <Deployment Version="3"> - <DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule"> - <Platform Name="OSX32"> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule"> - <Platform Name="iOSSimulator"> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="$(BDS)\Redist\iossimulator\libPCRE.dylib" Class="DependencyModule"> - <Platform Name="iOSSimulator"> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="$(BDS)\Redist\osx32\libcgsqlite3.dylib" Class="DependencyModule"> - <Platform Name="OSX32"> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="Win32\Debug\CrossWebSocketServer.exe" Configuration="Debug" Class="ProjectOutput"> - <Platform Name="Win32"> - <RemoteName>CrossWebSocketServer.exe</RemoteName> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployClass Name="AdditionalDebugSymbols"> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - <Platform Name="OSX32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="Win32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>0</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidClassesDexFile"> - <Platform Name="Android"> - <RemoteDir>classes</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidGDBServer"> - <Platform Name="Android"> - <RemoteDir>library\lib\armeabi-v7a</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidLibnativeArmeabiFile"> - <Platform Name="Android"> - <RemoteDir>library\lib\armeabi</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidLibnativeMipsFile"> - <Platform Name="Android"> - <RemoteDir>library\lib\mips</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidServiceOutput"> - <Platform Name="Android"> - <RemoteDir>library\lib\armeabi-v7a</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidSplashImageDef"> - <Platform Name="Android"> - <RemoteDir>res\drawable</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="AndroidSplashStyles"> - <Platform Name="Android"> - <RemoteDir>res\values</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_DefaultAppIcon"> - <Platform Name="Android"> - <RemoteDir>res\drawable</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_LauncherIcon144"> - <Platform Name="Android"> - <RemoteDir>res\drawable-xxhdpi</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_LauncherIcon36"> - <Platform Name="Android"> - <RemoteDir>res\drawable-ldpi</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_LauncherIcon48"> - <Platform Name="Android"> - <RemoteDir>res\drawable-mdpi</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_LauncherIcon72"> - <Platform Name="Android"> - <RemoteDir>res\drawable-hdpi</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_LauncherIcon96"> - <Platform Name="Android"> - <RemoteDir>res\drawable-xhdpi</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_SplashImage426"> - <Platform Name="Android"> - <RemoteDir>res\drawable-small</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_SplashImage470"> - <Platform Name="Android"> - <RemoteDir>res\drawable-normal</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_SplashImage640"> - <Platform Name="Android"> - <RemoteDir>res\drawable-large</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="Android_SplashImage960"> - <Platform Name="Android"> - <RemoteDir>res\drawable-xlarge</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="DebugSymbols"> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - <Platform Name="OSX32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="Win32"> - <Operation>0</Operation> - </Platform> - </DeployClass> - <DeployClass Name="DependencyFramework"> - <Platform Name="OSX32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>1</Operation> - <Extensions>.framework</Extensions> - </Platform> - <Platform Name="Win32"> - <Operation>0</Operation> - </Platform> - </DeployClass> - <DeployClass Name="DependencyModule"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="OSX32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="Win32"> - <Operation>0</Operation> - <Extensions>.dll;.bpl</Extensions> - </Platform> - </DeployClass> - <DeployClass Required="true" Name="DependencyPackage"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="OSX32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>1</Operation> - <Extensions>.dylib</Extensions> - </Platform> - <Platform Name="Win32"> - <Operation>0</Operation> - <Extensions>.bpl</Extensions> - </Platform> - </DeployClass> - <DeployClass Name="File"> - <Platform Name="Android"> - <Operation>0</Operation> - </Platform> - <Platform Name="iOSDevice32"> - <Operation>0</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>0</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>0</Operation> - </Platform> - <Platform Name="OSX32"> - <RemoteDir>Contents\Resources\StartUp\</RemoteDir> - <Operation>0</Operation> - </Platform> - <Platform Name="Win32"> - <Operation>0</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPad_Launch1024"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPad_Launch1536"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPad_Launch2048"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPad_Launch768"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPhone_Launch320"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPhone_Launch640"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="iPhone_Launch640x1136"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectAndroidManifest"> - <Platform Name="Android"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectiOSDeviceDebug"> - <Platform Name="iOSDevice32"> - <RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectiOSDeviceResourceRules"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectiOSEntitlements"> - <Platform Name="iOSDevice32"> - <RemoteDir>..\</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <RemoteDir>..\</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectiOSInfoPList"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectiOSResource"> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectOSXEntitlements"> - <Platform Name="OSX32"> - <RemoteDir>..\</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectOSXInfoPList"> - <Platform Name="OSX32"> - <RemoteDir>Contents</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectOSXResource"> - <Platform Name="OSX32"> - <RemoteDir>Contents\Resources</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Required="true" Name="ProjectOutput"> - <Platform Name="Android"> - <RemoteDir>library\lib\armeabi-v7a</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice32"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSDevice64"> - <Operation>1</Operation> - </Platform> - <Platform Name="iOSSimulator"> - <Operation>1</Operation> - </Platform> - <Platform Name="Linux64"> - <Operation>1</Operation> - </Platform> - <Platform Name="OSX32"> - <RemoteDir>Contents\MacOS</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="Win32"> - <Operation>0</Operation> - </Platform> - </DeployClass> - <DeployClass Name="ProjectUWPManifest"> - <Platform Name="Win32"> - <Operation>1</Operation> - </Platform> - <Platform Name="Win64"> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="UWP_DelphiLogo150"> - <Platform Name="Win32"> - <RemoteDir>Assets</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="Win64"> - <RemoteDir>Assets</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <DeployClass Name="UWP_DelphiLogo44"> - <Platform Name="Win32"> - <RemoteDir>Assets</RemoteDir> - <Operation>1</Operation> - </Platform> - <Platform Name="Win64"> - <RemoteDir>Assets</RemoteDir> - <Operation>1</Operation> - </Platform> - </DeployClass> - <ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/> - <ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/> - <ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/> - <ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/> - <ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/> - <ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/> - <ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/> - <ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/> - </Deployment> - <Platforms> - <Platform value="Android">True</Platform> - <Platform value="iOSDevice32">True</Platform> - <Platform value="iOSDevice64">True</Platform> - <Platform value="iOSSimulator">True</Platform> - <Platform value="OSX32">True</Platform> - <Platform value="Win32">True</Platform> - <Platform value="Win64">True</Platform> - </Platforms> - </BorlandProject> - <ProjectFileVersion>12</ProjectFileVersion> - </ProjectExtensions> - <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/> - <Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/> - <Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/> - <ProjectExtensions/> -</Project> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <ProjectGuid>{00BB3B9E-B439-4377-A203-3C4F0C15B1F9}</ProjectGuid> + <ProjectVersion>18.4</ProjectVersion> + <FrameworkType>FMX</FrameworkType> + <MainSource>CrossWebSocketServer.dpr</MainSource> + <Base>True</Base> + <Config Condition="'$(Config)'==''">Debug</Config> + <Platform Condition="'$(Platform)'==''">Win32</Platform> + <TargetedPlatforms>1119</TargetedPlatforms> + <AppType>Application</AppType> + </PropertyGroup> + <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''"> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''"> + <Base_Android>true</Base_Android> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='iOSDevice32' and '$(Base)'=='true') or '$(Base_iOSDevice32)'!=''"> + <Base_iOSDevice32>true</Base_iOSDevice32> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''"> + <Base_iOSDevice64>true</Base_iOSDevice64> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='iOSSimulator' and '$(Base)'=='true') or '$(Base_iOSSimulator)'!=''"> + <Base_iOSSimulator>true</Base_iOSSimulator> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Base)'=='true') or '$(Base_OSX32)'!=''"> + <Base_OSX32>true</Base_OSX32> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''"> + <Base_Win32>true</Base_Win32> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''"> + <Base_Win64>true</Base_Win64> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''"> + <Cfg_1>true</Cfg_1> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''"> + <Cfg_1_Win32>true</Cfg_1_Win32> + <CfgParent>Cfg_1</CfgParent> + <Cfg_1>true</Cfg_1> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''"> + <Cfg_1_Win64>true</Cfg_1_Win64> + <CfgParent>Cfg_1</CfgParent> + <Cfg_1>true</Cfg_1> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''"> + <Cfg_2>true</Cfg_2> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''"> + <Cfg_2_Win32>true</Cfg_2_Win32> + <CfgParent>Cfg_2</CfgParent> + <Cfg_2>true</Cfg_2> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''"> + <Cfg_2_Win64>true</Cfg_2_Win64> + <CfgParent>Cfg_2</CfgParent> + <Cfg_2>true</Cfg_2> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="'$(Base)'!=''"> + <DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput> + <DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput> + <DCC_E>false</DCC_E> + <DCC_N>false</DCC_N> + <DCC_S>false</DCC_S> + <DCC_F>false</DCC_F> + <DCC_K>false</DCC_K> + <DCC_UsePackage>RESTComponents;FlexCel_Pdf;emsclientfiredac;FlexCel_Report;FireDACIBDriver;emsclient;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;FireDAC;FlexCel_XlsAdapter;FireDACSqliteDriver;soaprtl;FlexCel_Core;soapmidas;FlexCel_Render;$(DCC_UsePackage)</DCC_UsePackage> + <DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace> + <AUP_ACCESS_COARSE_LOCATION>true</AUP_ACCESS_COARSE_LOCATION> + <AUP_ACCESS_FINE_LOCATION>true</AUP_ACCESS_FINE_LOCATION> + <AUP_CALL_PHONE>true</AUP_CALL_PHONE> + <AUP_CAMERA>true</AUP_CAMERA> + <AUP_INTERNET>true</AUP_INTERNET> + <AUP_READ_CALENDAR>true</AUP_READ_CALENDAR> + <AUP_READ_EXTERNAL_STORAGE>true</AUP_READ_EXTERNAL_STORAGE> + <AUP_WRITE_CALENDAR>true</AUP_WRITE_CALENDAR> + <AUP_WRITE_EXTERNAL_STORAGE>true</AUP_WRITE_EXTERNAL_STORAGE> + <AUP_READ_PHONE_STATE>true</AUP_READ_PHONE_STATE> + <Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon> + <Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns> + <SanitizedProjectName>CrossWebSocketServer</SanitizedProjectName> + <DCC_Define>__CROSS_SSL__x;__MBED_TLS__x;$(DCC_Define)</DCC_Define> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_Android)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;FMX_FlexCel_Core;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;Marvin.Comps.MDL.General;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;TeeBI;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;FMX_FlexCel_Components;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;$(DCC_UsePackage)</DCC_UsePackage> + <VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys> + <BT_BuildType>Debug</BT_BuildType> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + <Android_LauncherIcon36>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png</Android_LauncherIcon36> + <Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48> + <Android_LauncherIcon72>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png</Android_LauncherIcon72> + <Android_LauncherIcon96>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png</Android_LauncherIcon96> + <Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144> + <Android_SplashImage426>$(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png</Android_SplashImage426> + <Android_SplashImage470>$(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png</Android_SplashImage470> + <Android_SplashImage640>$(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png</Android_SplashImage640> + <Android_SplashImage960>$(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png</Android_SplashImage960> + <EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar</EnabledSysJars> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_iOSDevice32)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;FMX_FlexCel_Core;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;FMX_FlexCel_Components;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage> + <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera;CFBundleShortVersionString=1.0.0</VerInfo_Keys> + <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + <BT_BuildType>Debug</BT_BuildType> + <VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId> + <iPhone_AppIcon57>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png</iPhone_AppIcon57> + <iPhone_AppIcon60>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png</iPhone_AppIcon60> + <iPhone_AppIcon87>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png</iPhone_AppIcon87> + <iPhone_AppIcon114>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png</iPhone_AppIcon114> + <iPhone_AppIcon120>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png</iPhone_AppIcon120> + <iPhone_AppIcon180>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png</iPhone_AppIcon180> + <iPhone_Launch320>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png</iPhone_Launch320> + <iPhone_Launch640>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png</iPhone_Launch640> + <iPhone_Launch640x1136>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png</iPhone_Launch640x1136> + <iPhone_Launch750>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png</iPhone_Launch750> + <iPhone_Launch1242>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png</iPhone_Launch1242> + <iPhone_Launch2208>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png</iPhone_Launch2208> + <iPhone_Spotlight29>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png</iPhone_Spotlight29> + <iPhone_Spotlight40>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png</iPhone_Spotlight40> + <iPhone_Spotlight58>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png</iPhone_Spotlight58> + <iPhone_Spotlight80>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png</iPhone_Spotlight80> + <iPad_AppIcon72>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png</iPad_AppIcon72> + <iPad_AppIcon76>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png</iPad_AppIcon76> + <iPad_AppIcon144>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png</iPad_AppIcon144> + <iPad_AppIcon152>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png</iPad_AppIcon152> + <iPad_Launch768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png</iPad_Launch768> + <iPad_Launch768x1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png</iPad_Launch768x1024> + <iPad_Launch1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png</iPad_Launch1024> + <iPad_Launch1024x768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png</iPad_Launch1024x768> + <iPad_Launch1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png</iPad_Launch1536> + <iPad_Launch1536x2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png</iPad_Launch1536x2048> + <iPad_Launch2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png</iPad_Launch2048> + <iPad_Launch2048x1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png</iPad_Launch2048x1536> + <iPad_SpotLight40>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png</iPad_SpotLight40> + <iPad_SpotLight50>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png</iPad_SpotLight50> + <iPad_SpotLight80>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png</iPad_SpotLight80> + <iPad_SpotLight100>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png</iPad_SpotLight100> + <iPad_Setting29>$(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png</iPad_Setting29> + <iPad_Setting58>$(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png</iPad_Setting58> + <iPhone_Launch1125>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png</iPhone_Launch1125> + <iPhone_Launch2436>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png</iPhone_Launch2436> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_iOSDevice64)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;FMX_FlexCel_Core;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;FMX_FlexCel_Components;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage> + <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera;CFBundleShortVersionString=1.0.0</VerInfo_Keys> + <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + <BT_BuildType>Debug</BT_BuildType> + <VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId> + <iPhone_AppIcon57>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png</iPhone_AppIcon57> + <iPhone_AppIcon60>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png</iPhone_AppIcon60> + <iPhone_AppIcon87>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png</iPhone_AppIcon87> + <iPhone_AppIcon114>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png</iPhone_AppIcon114> + <iPhone_AppIcon120>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png</iPhone_AppIcon120> + <iPhone_AppIcon180>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png</iPhone_AppIcon180> + <iPhone_Launch320>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png</iPhone_Launch320> + <iPhone_Launch640>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png</iPhone_Launch640> + <iPhone_Launch640x1136>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png</iPhone_Launch640x1136> + <iPhone_Launch750>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png</iPhone_Launch750> + <iPhone_Launch1242>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png</iPhone_Launch1242> + <iPhone_Launch2208>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png</iPhone_Launch2208> + <iPhone_Spotlight29>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png</iPhone_Spotlight29> + <iPhone_Spotlight40>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png</iPhone_Spotlight40> + <iPhone_Spotlight58>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png</iPhone_Spotlight58> + <iPhone_Spotlight80>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png</iPhone_Spotlight80> + <iPad_AppIcon72>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png</iPad_AppIcon72> + <iPad_AppIcon76>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png</iPad_AppIcon76> + <iPad_AppIcon144>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png</iPad_AppIcon144> + <iPad_AppIcon152>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png</iPad_AppIcon152> + <iPad_Launch768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png</iPad_Launch768> + <iPad_Launch768x1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png</iPad_Launch768x1024> + <iPad_Launch1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png</iPad_Launch1024> + <iPad_Launch1024x768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png</iPad_Launch1024x768> + <iPad_Launch1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png</iPad_Launch1536> + <iPad_Launch1536x2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png</iPad_Launch1536x2048> + <iPad_Launch2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png</iPad_Launch2048> + <iPad_Launch2048x1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png</iPad_Launch2048x1536> + <iPad_SpotLight40>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png</iPad_SpotLight40> + <iPad_SpotLight50>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png</iPad_SpotLight50> + <iPad_SpotLight80>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png</iPad_SpotLight80> + <iPad_SpotLight100>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png</iPad_SpotLight100> + <iPad_Setting29>$(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png</iPad_Setting29> + <iPad_Setting58>$(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png</iPad_Setting58> + <iPhone_Launch1125>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png</iPhone_Launch1125> + <iPhone_Launch2436>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png</iPhone_Launch2436> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_iOSSimulator)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DBXInterBaseDriver;FMX_FlexCel_Core;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;TeeBI;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;FMX_FlexCel_Components;dbxcds;DataSnapProviderClient;dsnapxml;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage> + <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera;CFBundleShortVersionString=1.0.0</VerInfo_Keys> + <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + <iPhone_AppIcon57>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png</iPhone_AppIcon57> + <iPhone_AppIcon60>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png</iPhone_AppIcon60> + <iPhone_AppIcon87>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png</iPhone_AppIcon87> + <iPhone_AppIcon114>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png</iPhone_AppIcon114> + <iPhone_AppIcon120>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png</iPhone_AppIcon120> + <iPhone_AppIcon180>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png</iPhone_AppIcon180> + <iPhone_Launch320>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png</iPhone_Launch320> + <iPhone_Launch640>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png</iPhone_Launch640> + <iPhone_Launch640x1136>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png</iPhone_Launch640x1136> + <iPhone_Launch750>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png</iPhone_Launch750> + <iPhone_Launch1242>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png</iPhone_Launch1242> + <iPhone_Launch2208>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png</iPhone_Launch2208> + <iPhone_Spotlight29>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png</iPhone_Spotlight29> + <iPhone_Spotlight40>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png</iPhone_Spotlight40> + <iPhone_Spotlight58>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png</iPhone_Spotlight58> + <iPhone_Spotlight80>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png</iPhone_Spotlight80> + <iPad_AppIcon72>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png</iPad_AppIcon72> + <iPad_AppIcon76>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png</iPad_AppIcon76> + <iPad_AppIcon144>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png</iPad_AppIcon144> + <iPad_AppIcon152>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png</iPad_AppIcon152> + <iPad_Launch768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png</iPad_Launch768> + <iPad_Launch768x1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png</iPad_Launch768x1024> + <iPad_Launch1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png</iPad_Launch1024> + <iPad_Launch1024x768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png</iPad_Launch1024x768> + <iPad_Launch1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png</iPad_Launch1536> + <iPad_Launch1536x2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png</iPad_Launch1536x2048> + <iPad_Launch2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png</iPad_Launch2048> + <iPad_Launch2048x1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png</iPad_Launch2048x1536> + <iPad_SpotLight40>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png</iPad_SpotLight40> + <iPad_SpotLight50>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png</iPad_SpotLight50> + <iPad_SpotLight80>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png</iPad_SpotLight80> + <iPad_SpotLight100>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png</iPad_SpotLight100> + <iPad_Setting29>$(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png</iPad_Setting29> + <iPad_Setting58>$(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png</iPad_Setting58> + <iPhone_Launch1125>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png</iPhone_Launch1125> + <iPhone_Launch2436>$(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png</iPhone_Launch2436> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_OSX32)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DataSnapServerMidas;DBXInterBaseDriver;FMX_FlexCel_Core;DataSnapFireDAC;tethering;FireDACMSSQLDriver;bindcompfmx;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;TeeBI;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;DataSnapServer;xmlrtl;DataSnapNativeClient;ibxbindings;fmxobj;FireDACDSDriver;rtl;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;bindcomp;DBXInformixDriver;IndyIPClient;FMX_FlexCel_Components;dbxcds;FireDACODBCDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;inetdbxpress;fmxase;$(DCC_UsePackage)</DCC_UsePackage> + <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;CFBundleShortVersionString=1.0.0</VerInfo_Keys> + <BT_BuildType>Debug</BT_BuildType> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_Win32)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;TVidGrab;vclactnband;FMX_FlexCel_Core;vclFireDAC;vcl.gtxControlsD102;DataSnapFireDAC;tethering;svnui;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;FMX.dclgtxControlsD102;vcltouch;VCLChartTeeBI;vcldb;bindcompfmx;Intraweb;svn;DBXOracleDriver;SKIA_FlexCel_Core;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;VCL_FlexCel_Components;Marvin.Comps.MDL.General;vclib;FireDACDBXDriver;dbexpress;IndyCore;vcl.gtxDBControlsD102;vclx;dsnap;DataSnapCommon;TeeBI;FMXTeeBI;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;RazorPackageR102;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;FireDACInfxDriver;fmxFireDAC;vclimg;ZrcCrossD102;TeeDB;Vcl.gtxStdCtrlsD102;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;FmxPkgD102;DBXOdbcDriver;FireDACTDataDriver;FMXTee;FMXChartTeeBI;VCLTeeBI;DbxCommonDriver;fmx.gtxControlsD102;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;ibxbindings;fmxobj;FireDACDSDriver;rtl;vclwinx;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;DCEF_D102;FMX_FlexCel_Components;dbxcds;VclSmp;VCL_FlexCel_Core;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;inetdbxpress;vcl.gtxReportExportD102;paxcomp_x10_2;fmxase;$(DCC_UsePackage)</DCC_UsePackage> + <DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace> + <BT_BuildType>Debug</BT_BuildType> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys> + <VerInfo_Locale>1033</VerInfo_Locale> + <Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File> + <UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44> + <UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150> + </PropertyGroup> + <PropertyGroup Condition="'$(Base_Win64)'!=''"> + <DCC_UsePackage>DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;TVidGrab;vclactnband;FMX_FlexCel_Core;vclFireDAC;DataSnapFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;VCLChartTeeBI;vcldb;bindcompfmx;Intraweb;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;VCL_FlexCel_Components;Marvin.Comps.MDL.General;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;TeeBI;FMXTeeBI;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;FireDACInfxDriver;fmxFireDAC;vclimg;TeeDB;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;VCLTeeBI;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;ibxbindings;fmxobj;FireDACDSDriver;rtl;vclwinx;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;FMX_FlexCel_Components;dbxcds;VclSmp;VCL_FlexCel_Core;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;inetdbxpress;fmxase;$(DCC_UsePackage)</DCC_UsePackage> + <DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace> + <BT_BuildType>Debug</BT_BuildType> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys> + <VerInfo_Locale>1033</VerInfo_Locale> + <Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File> + <UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44> + <UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_1)'!=''"> + <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define> + <DCC_DebugDCUs>true</DCC_DebugDCUs> + <DCC_Optimize>false</DCC_Optimize> + <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames> + <DCC_DebugInfoInExe>true</DCC_DebugInfoInExe> + <DCC_RemoteDebug>true</DCC_RemoteDebug> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_1_Win32)'!=''"> + <DCC_RemoteDebug>false</DCC_RemoteDebug> + <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> + <AppEnableHighDPI>true</AppEnableHighDPI> + <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> + <VerInfo_Locale>1033</VerInfo_Locale> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_1_Win64)'!=''"> + <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> + <AppEnableHighDPI>true</AppEnableHighDPI> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_2)'!=''"> + <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols> + <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define> + <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo> + <DCC_DebugInformation>0</DCC_DebugInformation> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''"> + <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> + <AppEnableHighDPI>true</AppEnableHighDPI> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_2_Win64)'!=''"> + <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> + <AppEnableHighDPI>true</AppEnableHighDPI> + </PropertyGroup> + <ItemGroup> + <DelphiCompile Include="$(MainSource)"> + <MainSource>MainSource</MainSource> + </DelphiCompile> + <DCCReference Include="uCrossWebSocketServerDemo.pas"> + <Form>fmCrossWebSocketServerDemo</Form> + <FormType>fmx</FormType> + </DCCReference> + <BuildConfiguration Include="Release"> + <Key>Cfg_2</Key> + <CfgParent>Base</CfgParent> + </BuildConfiguration> + <BuildConfiguration Include="Base"> + <Key>Base</Key> + </BuildConfiguration> + <BuildConfiguration Include="Debug"> + <Key>Cfg_1</Key> + <CfgParent>Base</CfgParent> + </BuildConfiguration> + </ItemGroup> + <ProjectExtensions> + <Borland.Personality>Delphi.Personality.12</Borland.Personality> + <Borland.ProjectType>Application</Borland.ProjectType> + <BorlandProject> + <Delphi.Personality> + <Source> + <Source Name="MainSource">CrossWebSocketServer.dpr</Source> + </Source> + <Excluded_Packages> + <Excluded_Packages Name="$(BDSBIN)\bcboffice2k250.bpl">Embarcadero C++Builder Office 2000 Servers Package</Excluded_Packages> + <Excluded_Packages Name="$(BDSBIN)\bcbofficexp250.bpl">Embarcadero C++Builder Office XP Servers Package</Excluded_Packages> + <Excluded_Packages Name="$(BDSBIN)\dcloffice2k250.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages> + <Excluded_Packages Name="$(BDSBIN)\dclofficexp250.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages> + </Excluded_Packages> + </Delphi.Personality> + <Deployment Version="3"> + <DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule"> + <Platform Name="OSX32"> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule"> + <Platform Name="iOSSimulator"> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="$(BDS)\Redist\iossimulator\libPCRE.dylib" Class="DependencyModule"> + <Platform Name="iOSSimulator"> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="$(BDS)\Redist\osx32\libcgsqlite3.dylib" Class="DependencyModule"> + <Platform Name="OSX32"> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployFile LocalName="Win32\Debug\CrossWebSocketServer.exe" Configuration="Debug" Class="ProjectOutput"> + <Platform Name="Win32"> + <RemoteName>CrossWebSocketServer.exe</RemoteName> + <Overwrite>true</Overwrite> + </Platform> + </DeployFile> + <DeployClass Name="AdditionalDebugSymbols"> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + <Platform Name="OSX32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="Win32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>0</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidClassesDexFile"> + <Platform Name="Android"> + <RemoteDir>classes</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidGDBServer"> + <Platform Name="Android"> + <RemoteDir>library\lib\armeabi-v7a</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidLibnativeArmeabiFile"> + <Platform Name="Android"> + <RemoteDir>library\lib\armeabi</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidLibnativeMipsFile"> + <Platform Name="Android"> + <RemoteDir>library\lib\mips</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidServiceOutput"> + <Platform Name="Android"> + <RemoteDir>library\lib\armeabi-v7a</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidSplashImageDef"> + <Platform Name="Android"> + <RemoteDir>res\drawable</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="AndroidSplashStyles"> + <Platform Name="Android"> + <RemoteDir>res\values</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_DefaultAppIcon"> + <Platform Name="Android"> + <RemoteDir>res\drawable</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_LauncherIcon144"> + <Platform Name="Android"> + <RemoteDir>res\drawable-xxhdpi</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_LauncherIcon36"> + <Platform Name="Android"> + <RemoteDir>res\drawable-ldpi</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_LauncherIcon48"> + <Platform Name="Android"> + <RemoteDir>res\drawable-mdpi</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_LauncherIcon72"> + <Platform Name="Android"> + <RemoteDir>res\drawable-hdpi</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_LauncherIcon96"> + <Platform Name="Android"> + <RemoteDir>res\drawable-xhdpi</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_SplashImage426"> + <Platform Name="Android"> + <RemoteDir>res\drawable-small</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_SplashImage470"> + <Platform Name="Android"> + <RemoteDir>res\drawable-normal</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_SplashImage640"> + <Platform Name="Android"> + <RemoteDir>res\drawable-large</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="Android_SplashImage960"> + <Platform Name="Android"> + <RemoteDir>res\drawable-xlarge</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="DebugSymbols"> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + <Platform Name="OSX32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="Win32"> + <Operation>0</Operation> + </Platform> + </DeployClass> + <DeployClass Name="DependencyFramework"> + <Platform Name="OSX32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>1</Operation> + <Extensions>.framework</Extensions> + </Platform> + <Platform Name="Win32"> + <Operation>0</Operation> + </Platform> + </DeployClass> + <DeployClass Name="DependencyModule"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="OSX32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="Win32"> + <Operation>0</Operation> + <Extensions>.dll;.bpl</Extensions> + </Platform> + </DeployClass> + <DeployClass Required="true" Name="DependencyPackage"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="OSX32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>1</Operation> + <Extensions>.dylib</Extensions> + </Platform> + <Platform Name="Win32"> + <Operation>0</Operation> + <Extensions>.bpl</Extensions> + </Platform> + </DeployClass> + <DeployClass Name="File"> + <Platform Name="Android"> + <Operation>0</Operation> + </Platform> + <Platform Name="iOSDevice32"> + <Operation>0</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>0</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>0</Operation> + </Platform> + <Platform Name="OSX32"> + <RemoteDir>Contents\Resources\StartUp\</RemoteDir> + <Operation>0</Operation> + </Platform> + <Platform Name="Win32"> + <Operation>0</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPad_Launch1024"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPad_Launch1536"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPad_Launch2048"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPad_Launch768"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPhone_Launch320"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPhone_Launch640"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="iPhone_Launch640x1136"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectAndroidManifest"> + <Platform Name="Android"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectiOSDeviceDebug"> + <Platform Name="iOSDevice32"> + <RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectiOSDeviceResourceRules"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectiOSEntitlements"> + <Platform Name="iOSDevice32"> + <RemoteDir>..\</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <RemoteDir>..\</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectiOSInfoPList"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectiOSResource"> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectOSXEntitlements"> + <Platform Name="OSX32"> + <RemoteDir>..\</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectOSXInfoPList"> + <Platform Name="OSX32"> + <RemoteDir>Contents</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectOSXResource"> + <Platform Name="OSX32"> + <RemoteDir>Contents\Resources</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Required="true" Name="ProjectOutput"> + <Platform Name="Android"> + <RemoteDir>library\lib\armeabi-v7a</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice32"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSDevice64"> + <Operation>1</Operation> + </Platform> + <Platform Name="iOSSimulator"> + <Operation>1</Operation> + </Platform> + <Platform Name="Linux64"> + <Operation>1</Operation> + </Platform> + <Platform Name="OSX32"> + <RemoteDir>Contents\MacOS</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="Win32"> + <Operation>0</Operation> + </Platform> + </DeployClass> + <DeployClass Name="ProjectUWPManifest"> + <Platform Name="Win32"> + <Operation>1</Operation> + </Platform> + <Platform Name="Win64"> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="UWP_DelphiLogo150"> + <Platform Name="Win32"> + <RemoteDir>Assets</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="Win64"> + <RemoteDir>Assets</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <DeployClass Name="UWP_DelphiLogo44"> + <Platform Name="Win32"> + <RemoteDir>Assets</RemoteDir> + <Operation>1</Operation> + </Platform> + <Platform Name="Win64"> + <RemoteDir>Assets</RemoteDir> + <Operation>1</Operation> + </Platform> + </DeployClass> + <ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/> + <ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/> + <ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/> + <ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/> + <ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/> + <ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/> + <ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/> + <ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/> + </Deployment> + <Platforms> + <Platform value="Android">True</Platform> + <Platform value="iOSDevice32">True</Platform> + <Platform value="iOSDevice64">True</Platform> + <Platform value="iOSSimulator">True</Platform> + <Platform value="OSX32">True</Platform> + <Platform value="Win32">True</Platform> + <Platform value="Win64">True</Platform> + </Platforms> + </BorlandProject> + <ProjectFileVersion>12</ProjectFileVersion> + </ProjectExtensions> + <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/> + <Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/> + <Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/> + <ProjectExtensions/> +</Project> diff --git a/Net/Demos/Old/CrossWebSocket/uCrossWebSocketServerDemo.fmx b/Net/Demos/Old/CrossWebSocket/uCrossWebSocketServerDemo.fmx index 100fe1d..c2f7012 100644 --- a/Net/Demos/Old/CrossWebSocket/uCrossWebSocketServerDemo.fmx +++ b/Net/Demos/Old/CrossWebSocket/uCrossWebSocketServerDemo.fmx @@ -1,49 +1,49 @@ -object fmCrossWebSocketServerDemo: TfmCrossWebSocketServerDemo - Left = 0 - Top = 0 - Caption = 'CrossWebSocketServer' - ClientHeight = 480 - ClientWidth = 640 - FormFactor.Width = 320 - FormFactor.Height = 480 - FormFactor.Devices = [Desktop] - OnCreate = FormCreate - OnDestroy = FormDestroy - DesignerMasterStyle = 0 - object btnStart: TButton - Position.X = 24.000000000000000000 - Position.Y = 24.000000000000000000 - TabOrder = 0 - Text = 'Start' - OnClick = btnStartClick - end - object btnClose: TButton - Position.X = 240.000000000000000000 - Position.Y = 24.000000000000000000 - TabOrder = 2 - Text = 'Close' - OnClick = btnCloseClick - end - object btnBroadcast: TButton - Position.X = 132.000000000000000000 - Position.Y = 24.000000000000000000 - TabOrder = 3 - Text = 'Broadcast' - OnClick = btnBroadcastClick - end - object Memo1: TMemo - Touch.InteractiveGestures = [Pan, LongTap, DoubleTap] - DataDetectorTypes = [] - StyledSettings = [Size, Style, FontColor] - TextSettings.Font.Family = 'Tahoma' - Anchors = [akLeft, akTop, akRight, akBottom] - Position.X = 16.000000000000000000 - Position.Y = 72.000000000000000000 - Size.Width = 609.000000000000000000 - Size.Height = 393.000000000000000000 - Size.PlatformDefault = False - TabOrder = 4 - Viewport.Width = 605.000000000000000000 - Viewport.Height = 389.000000000000000000 - end -end +object fmCrossWebSocketServerDemo: TfmCrossWebSocketServerDemo + Left = 0 + Top = 0 + Caption = 'CrossWebSocketServer' + ClientHeight = 480 + ClientWidth = 640 + FormFactor.Width = 320 + FormFactor.Height = 480 + FormFactor.Devices = [Desktop] + OnCreate = FormCreate + OnDestroy = FormDestroy + DesignerMasterStyle = 0 + object btnStart: TButton + Position.X = 24.000000000000000000 + Position.Y = 24.000000000000000000 + TabOrder = 0 + Text = 'Start' + OnClick = btnStartClick + end + object btnClose: TButton + Position.X = 240.000000000000000000 + Position.Y = 24.000000000000000000 + TabOrder = 2 + Text = 'Close' + OnClick = btnCloseClick + end + object btnBroadcast: TButton + Position.X = 132.000000000000000000 + Position.Y = 24.000000000000000000 + TabOrder = 3 + Text = 'Broadcast' + OnClick = btnBroadcastClick + end + object Memo1: TMemo + Touch.InteractiveGestures = [Pan, LongTap, DoubleTap] + DataDetectorTypes = [] + StyledSettings = [Size, Style, FontColor] + TextSettings.Font.Family = 'Tahoma' + Anchors = [akLeft, akTop, akRight, akBottom] + Position.X = 16.000000000000000000 + Position.Y = 72.000000000000000000 + Size.Width = 609.000000000000000000 + Size.Height = 393.000000000000000000 + Size.PlatformDefault = False + TabOrder = 4 + Viewport.Width = 605.000000000000000000 + Viewport.Height = 389.000000000000000000 + end +end diff --git a/Net/Demos/Old/CrossWebSocket/uCrossWebSocketServerDemo.pas b/Net/Demos/Old/CrossWebSocket/uCrossWebSocketServerDemo.pas index 6cf1b02..cd8263f 100644 --- a/Net/Demos/Old/CrossWebSocket/uCrossWebSocketServerDemo.pas +++ b/Net/Demos/Old/CrossWebSocket/uCrossWebSocketServerDemo.pas @@ -1,197 +1,197 @@ -unit uCrossWebSocketServerDemo; - -interface - -uses - System.SysUtils, - System.Types, - System.UITypes, - System.Classes, - System.Variants, - System.IOUtils, - FMX.Types, - FMX.Controls, - FMX.Forms, - FMX.Graphics, - FMX.Dialogs, - FMX.Controls.Presentation, - FMX.StdCtrls, - FMX.ScrollBox, - FMX.Memo, - Net.CrossSocket.Base, - Net.CrossHttpServer, - Net.CrossWebSocketServer; - -type - TfmCrossWebSocketServerDemo = class(TForm) - btnStart: TButton; - btnClose: TButton; - btnBroadcast: TButton; - Memo1: TMemo; - procedure FormCreate(Sender: TObject); - procedure btnStartClick(Sender: TObject); - procedure btnCloseClick(Sender: TObject); - procedure FormDestroy(Sender: TObject); - procedure btnBroadcastClick(Sender: TObject); - private - FServer: ICrossWebSocketServer; - - procedure _ForEach(AProc: TProc<ICrossWebSocketConnection>); - procedure _ProcChatMessage(AConnection: ICrossWebSocketConnection; - const AChatMessage: string); - public - procedure AddLog(const S: string); overload; - procedure AddLog(const Fmt: string; const Args: array of const); overload; - end; - -var - fmCrossWebSocketServerDemo: TfmCrossWebSocketServerDemo; - -implementation - -uses - Utils.Utils; - -{$R *.fmx} - -procedure TfmCrossWebSocketServerDemo.AddLog(const Fmt: string; const Args: array of const); -begin - AddLog(Format(Fmt, Args)); -end; - -procedure TfmCrossWebSocketServerDemo.AddLog(const S: string); -begin - TThread.Synchronize(nil, - procedure - begin - Memo1.Lines.Add(FormatDateTime('HH:NN:SS:ZZZ', Now) + ' ' + S); - Memo1.GoToTextEnd; - end); -end; - -procedure TfmCrossWebSocketServerDemo.btnStartClick(Sender: TObject); -begin - if (btnStart.Tag = 0) then - begin - FServer.Addr := '0.0.0.0'; - FServer.Port := 12345; - FServer.Start(); - - btnStart.Tag := 1; - btnStart.Text := 'Stop'; - end else - begin - FServer.Stop(); - - btnStart.Tag := 0; - btnStart.Text := 'Start'; - end; -end; - -procedure TfmCrossWebSocketServerDemo.btnBroadcastClick(Sender: TObject); -begin - _ForEach( - procedure(AConnection: ICrossWebSocketConnection) - begin - AConnection.WsSend('Hello, I''m CrossWebSocketServer!'); - end); -end; - -procedure TfmCrossWebSocketServerDemo.btnCloseClick(Sender: TObject); -begin - _ForEach( - procedure(AConnection: ICrossWebSocketConnection) - begin - AConnection.WsClose; - end); -end; - -procedure TfmCrossWebSocketServerDemo.FormCreate(Sender: TObject); -begin - FServer := TNetCrossWebSocketServer.Create(0, False); - if FServer.Ssl then - begin - FServer.SetCertificateFile('server.crt'); - FServer.SetPrivateKeyFile('server.key'); - end; - - // 绑定WebSocket事件 - FServer - .OnOpen( - procedure(const AConnection: ICrossWebSocketConnection) - begin - AddLog('OnOpen [%s:%d]%s', - [AConnection.PeerAddr, AConnection.PeerPort, - AConnection.Request.Path]); - end) - .OnMessage( - procedure(const AConnection: ICrossWebSocketConnection; - const ARequestType: TWsRequestType; const ARequestData: TBytes) - var - LMessage: string; - begin - LMessage := TEncoding.UTF8.GetString(ARequestData); - - _ProcChatMessage(AConnection, Format('[%s:%d]%s', - [AConnection.PeerAddr, AConnection.PeerPort, LMessage])); - - AddLog('OnMessage [%s:%d]%s : %s', - [AConnection.PeerAddr, AConnection.PeerPort, - AConnection.Request.Path, - LMessage]); - end) - .OnClose( - procedure(const AConnection: ICrossWebSocketConnection) - begin - AddLog('OnClose [%s:%d]%s', - [AConnection.PeerAddr, AConnection.PeerPort, - AConnection.Request.Path]); - end) - ; - - // 同时可以处理普通的HTTP请求 - // 在浏览器中访问 http://localhost:12345/index.html 进行测试 - FServer - .Dir('/', TPath.Combine(TUtils.AppPath, '../../web')) - ; - FServer.Get('/hello', - procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) - begin - AResponse.Send('OK'); - AHandled := True; - end); - -end; - -procedure TfmCrossWebSocketServerDemo.FormDestroy(Sender: TObject); -begin - FServer.Stop; - FServer := nil; -end; - -procedure TfmCrossWebSocketServerDemo._ForEach(AProc: TProc<ICrossWebSocketConnection>); -var - LConnections: TArray<ICrossConnection>; - LConnection: ICrossConnection; -begin - LConnections := FServer.LockConnections.Values.ToArray; - FServer.UnlockConnections; - - for LConnection in LConnections do - begin - if Assigned(AProc) then - AProc(LConnection as ICrossWebSocketConnection); - end; -end; - -procedure TfmCrossWebSocketServerDemo._ProcChatMessage(AConnection: ICrossWebSocketConnection; - const AChatMessage: string); -begin - _ForEach( - procedure(AConnection: ICrossWebSocketConnection) - begin - AConnection.WsSend(AChatMessage); - end); -end; - -end. +unit uCrossWebSocketServerDemo; + +interface + +uses + System.SysUtils, + System.Types, + System.UITypes, + System.Classes, + System.Variants, + System.IOUtils, + FMX.Types, + FMX.Controls, + FMX.Forms, + FMX.Graphics, + FMX.Dialogs, + FMX.Controls.Presentation, + FMX.StdCtrls, + FMX.ScrollBox, + FMX.Memo, + Net.CrossSocket.Base, + Net.CrossHttpServer, + Net.CrossWebSocketServer; + +type + TfmCrossWebSocketServerDemo = class(TForm) + btnStart: TButton; + btnClose: TButton; + btnBroadcast: TButton; + Memo1: TMemo; + procedure FormCreate(Sender: TObject); + procedure btnStartClick(Sender: TObject); + procedure btnCloseClick(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure btnBroadcastClick(Sender: TObject); + private + FServer: ICrossWebSocketServer; + + procedure _ForEach(AProc: TProc<ICrossWebSocketConnection>); + procedure _ProcChatMessage(AConnection: ICrossWebSocketConnection; + const AChatMessage: string); + public + procedure AddLog(const S: string); overload; + procedure AddLog(const Fmt: string; const Args: array of const); overload; + end; + +var + fmCrossWebSocketServerDemo: TfmCrossWebSocketServerDemo; + +implementation + +uses + Utils.Utils; + +{$R *.fmx} + +procedure TfmCrossWebSocketServerDemo.AddLog(const Fmt: string; const Args: array of const); +begin + AddLog(Format(Fmt, Args)); +end; + +procedure TfmCrossWebSocketServerDemo.AddLog(const S: string); +begin + TThread.Synchronize(nil, + procedure + begin + Memo1.Lines.Add(FormatDateTime('HH:NN:SS:ZZZ', Now) + ' ' + S); + Memo1.GoToTextEnd; + end); +end; + +procedure TfmCrossWebSocketServerDemo.btnStartClick(Sender: TObject); +begin + if (btnStart.Tag = 0) then + begin + FServer.Addr := '0.0.0.0'; + FServer.Port := 12345; + FServer.Start(); + + btnStart.Tag := 1; + btnStart.Text := 'Stop'; + end else + begin + FServer.Stop(); + + btnStart.Tag := 0; + btnStart.Text := 'Start'; + end; +end; + +procedure TfmCrossWebSocketServerDemo.btnBroadcastClick(Sender: TObject); +begin + _ForEach( + procedure(AConnection: ICrossWebSocketConnection) + begin + AConnection.WsSend('Hello, I''m CrossWebSocketServer!'); + end); +end; + +procedure TfmCrossWebSocketServerDemo.btnCloseClick(Sender: TObject); +begin + _ForEach( + procedure(AConnection: ICrossWebSocketConnection) + begin + AConnection.WsClose; + end); +end; + +procedure TfmCrossWebSocketServerDemo.FormCreate(Sender: TObject); +begin + FServer := TNetCrossWebSocketServer.Create(0, False); + if FServer.Ssl then + begin + FServer.SetCertificateFile('server.crt'); + FServer.SetPrivateKeyFile('server.key'); + end; + + // 绑定WebSocket事件 + FServer + .OnOpen( + procedure(const AConnection: ICrossWebSocketConnection) + begin + AddLog('OnOpen [%s:%d]%s', + [AConnection.PeerAddr, AConnection.PeerPort, + AConnection.Request.Path]); + end) + .OnMessage( + procedure(const AConnection: ICrossWebSocketConnection; + const ARequestType: TWsRequestType; const ARequestData: TBytes) + var + LMessage: string; + begin + LMessage := TEncoding.UTF8.GetString(ARequestData); + + _ProcChatMessage(AConnection, Format('[%s:%d]%s', + [AConnection.PeerAddr, AConnection.PeerPort, LMessage])); + + AddLog('OnMessage [%s:%d]%s : %s', + [AConnection.PeerAddr, AConnection.PeerPort, + AConnection.Request.Path, + LMessage]); + end) + .OnClose( + procedure(const AConnection: ICrossWebSocketConnection) + begin + AddLog('OnClose [%s:%d]%s', + [AConnection.PeerAddr, AConnection.PeerPort, + AConnection.Request.Path]); + end) + ; + + // 同时可以处理普通的HTTP请求 + // 在浏览器中访问 http://localhost:12345/index.html 进行测试 + FServer + .Dir('/', TPath.Combine(TUtils.AppPath, '../../web')) + ; + FServer.Get('/hello', + procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse; var AHandled: Boolean) + begin + AResponse.Send('OK'); + AHandled := True; + end); + +end; + +procedure TfmCrossWebSocketServerDemo.FormDestroy(Sender: TObject); +begin + FServer.Stop; + FServer := nil; +end; + +procedure TfmCrossWebSocketServerDemo._ForEach(AProc: TProc<ICrossWebSocketConnection>); +var + LConnections: TArray<ICrossConnection>; + LConnection: ICrossConnection; +begin + LConnections := FServer.LockConnections.Values.ToArray; + FServer.UnlockConnections; + + for LConnection in LConnections do + begin + if Assigned(AProc) then + AProc(LConnection as ICrossWebSocketConnection); + end; +end; + +procedure TfmCrossWebSocketServerDemo._ProcChatMessage(AConnection: ICrossWebSocketConnection; + const AChatMessage: string); +begin + _ForEach( + procedure(AConnection: ICrossWebSocketConnection) + begin + AConnection.WsSend(AChatMessage); + end); +end; + +end. diff --git a/Net/Demos/Old/CrossWebSocket/web/index.html b/Net/Demos/Old/CrossWebSocket/web/index.html index 78f64e1..20ee8cf 100644 --- a/Net/Demos/Old/CrossWebSocket/web/index.html +++ b/Net/Demos/Old/CrossWebSocket/web/index.html @@ -1,108 +1,108 @@ -<!doctype html> -<html lang="zh"> -<head> - <meta charset="UTF-8"> - <title>CrossWebSocket DEMO - - - -
    -
  • -
    -
      -
      - -
    • -
    - - - - - - + + + + + CrossWebSocket DEMO + + + +
      +
    • +
      +
        +
        + +
      • +
      + + + + + + diff --git a/Net/Demos/Old/CrossWebSocket/web/jquery-2.2.3.min.js b/Net/Demos/Old/CrossWebSocket/web/jquery-2.2.3.min.js index b8c4187..1677970 100644 --- a/Net/Demos/Old/CrossWebSocket/web/jquery-2.2.3.min.js +++ b/Net/Demos/Old/CrossWebSocket/web/jquery-2.2.3.min.js @@ -1,4 +1,4 @@ -/*! jQuery v2.2.3 | (c) jQuery Foundation | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.3",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){var b;if("object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype||{},"isPrototypeOf"))return!1;for(b in a);return void 0===b||k.call(a,b)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="
      ",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c; -}catch(e){}O.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return O.hasData(a)||N.hasData(a)},data:function(a,b,c){return O.access(a,b,c)},removeData:function(a,b){O.remove(a,b)},_data:function(a,b,c){return N.access(a,b,c)},_removeData:function(a,b){N.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=O.get(f),1===f.nodeType&&!N.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),R(f,d,e[d])));N.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){O.set(this,a)}):K(this,function(b){var c,d;if(f&&void 0===b){if(c=O.get(f,a)||O.get(f,a.replace(Q,"-$&").toLowerCase()),void 0!==c)return c;if(d=n.camelCase(a),c=O.get(f,d),void 0!==c)return c;if(c=R(f,d,void 0),void 0!==c)return c}else d=n.camelCase(a),this.each(function(){var c=O.get(this,d);O.set(this,d,b),a.indexOf("-")>-1&&void 0!==c&&O.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){O.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=N.get(a,b),c&&(!d||n.isArray(c)?d=N.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return N.get(a,c)||N.access(a,c,{empty:n.Callbacks("once memory").add(function(){N.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length",""],thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};$.optgroup=$.option,$.tbody=$.tfoot=$.colgroup=$.caption=$.thead,$.th=$.td;function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",!b||N.get(b[c],"globalEval"))}var ba=/<|&#?\w+;/;function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],o=0,p=a.length;p>o;o++)if(f=a[o],f||0===f)if("object"===n.type(f))n.merge(m,f.nodeType?[f]:f);else if(ba.test(f)){g=g||l.appendChild(b.createElement("div")),h=(Y.exec(f)||["",""])[1].toLowerCase(),i=$[h]||$._default,g.innerHTML=i[1]+n.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;n.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",o=0;while(f=m[o++])if(d&&n.inArray(f,d)>-1)e&&e.push(f);else if(j=n.contains(f.ownerDocument,f),g=_(l.appendChild(f),"script"),j&&aa(g),c){k=0;while(f=g[k++])Z.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var da=/^key/,ea=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,fa=/^([^.]*)(?:\.(.+)|)/;function ga(){return!0}function ha(){return!1}function ia(){try{return d.activeElement}catch(a){}}function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ja(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ha;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return"undefined"!=typeof n&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(G)||[""],j=b.length;while(j--)h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.hasData(a)&&N.get(a);if(r&&(i=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&N.remove(a,"handle events")}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(N.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,la=/\s*$/g;function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&&(f=N.access(a),g=N.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}O.hasData(a)&&(h=O.access(a),i=n.extend({},h),O.set(b,i))}}function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&ma.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),ua(f,b,c,d)});if(o&&(e=ca(b,a[0].ownerDocument,!1,a,d),g=e.firstChild,1===e.childNodes.length&&(e=g),g||d)){for(h=n.map(_(e,"script"),qa),i=h.length;o>m;m++)j=e,m!==p&&(j=n.clone(j,!0,!0),i&&n.merge(h,_(j,"script"))),c.call(a[m],j,m);if(i)for(k=h[h.length-1].ownerDocument,n.map(h,ra),m=0;i>m;m++)j=h[m],Z.test(j.type||"")&&!N.access(j,"globalEval")&&n.contains(k,j)&&(j.src?n._evalUrl&&n._evalUrl(j.src):n.globalEval(j.textContent.replace(oa,"")))}return a}function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(_(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&aa(_(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(ka,"<$1>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=_(h),f=_(a),d=0,e=f.length;e>d;d++)ta(f[d],g[d]);if(b)if(c)for(f=f||_(a),g=g||_(h),d=0,e=f.length;e>d;d++)sa(f[d],g[d]);else sa(a,h);return g=_(h,"script"),g.length>0&&aa(g,!i&&_(a,"script")),h},cleanData:function(a){for(var b,c,d,e=n.event.special,f=0;void 0!==(c=a[f]);f++)if(L(c)){if(b=c[N.expando]){if(b.events)for(d in b.events)e[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);c[N.expando]=void 0}c[O.expando]&&(c[O.expando]=void 0)}}}),n.fn.extend({domManip:ua,detach:function(a){return va(this,a,!0)},remove:function(a){return va(this,a)},text:function(a){return K(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.appendChild(a)}})},prepend:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(_(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return K(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!la.test(a)&&!$[(Y.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(_(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return ua(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(_(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),f=e.length-1,h=0;f>=h;h++)c=h===f?this:this.clone(!0),n(e[h])[b](c),g.apply(d,c.get());return this.pushStack(d)}});var wa,xa={HTML:"block",BODY:"block"};function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(wa||n("

      GjU1lO-!A@MOz*mL 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 WtWPF_AP}eC1XBtgT&1reuKxu#%R$fp diff --git a/CnPack/Crypto/CnNative.dcu b/CnPack/Crypto/CnNative.dcu deleted file mode 100644 index 6b75b118ea19893f0e12fe282c3f47c9989c3dbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48972 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 diff --git a/CnPack/Crypto/CnPemUtils.dcu b/CnPack/Crypto/CnPemUtils.dcu deleted file mode 100644 index b14a181ea709064b3476fff66071bca6173099f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16968 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 HV0HfoxNO-h diff --git a/CnPack/Crypto/CnRandom.dcu b/CnPack/Crypto/CnRandom.dcu deleted file mode 100644 index c89e954877a4cd1e8e54c20ff7c9e1f2ca04318b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5673 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 diff --git a/CnPack/Crypto/CnSHA1.dcu b/CnPack/Crypto/CnSHA1.dcu deleted file mode 100644 index a3f75043eb9f12c9d50a84dbf880dc9592c6e5f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10859 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 QlTU=35CcrI#ct;Ke<$eb%>V!Z diff --git a/CnPack/Crypto/CnSHA2.dcu b/CnPack/Crypto/CnSHA2.dcu deleted file mode 100644 index b080c2a50656f8ebf30bc3076405071038294457..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30907 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