delphi 相关问题

Delphi是一种通过使用Object Pascal快速开发本机Windows,macOS,Linux,iOS和Android应用程序的语言。该名称是指Delphi语言及其库,编译器和IDE,用于帮助编辑和调试Delphi项目。

Delphi - 如何获取目录中所有文件的列表

我正在使用delphi,当我执行openpicturedialog时,我想要一个目录中所有文件的列表。 即,当执行打开对话框时并且 我从中选择一个文件,我想要 列表...

回答 6 投票 0

是否可以打开一个blob而不将其保存到文件

我的IDE是Delphi 10.3。 我有一个 Firebird 2.5 表,附件字段类型是 Binary Blob。我可以打开此存储的文件(图像、word、excel、pdf、txt...)而不保存到磁盘吗? 如果这不是

回答 1 投票 0

Delphi (FMX):Windows 中的 DCPCrypt2 在 Android/IOS 中产生不同的结果

我正在尝试编写一个函数,该函数在 Delphi (RAD Studio 10.2) 中返回与 PHP 中的以下代码相同的结果: 我正在尝试编写一个在 Delphi (RAD Studio 10.2) 中返回与 PHP 中的以下代码相同的结果的函数: <?php $method = 'AES-256-CTR'; $data = 'Hello, world!'; $key = 'bRuD5WYw5wd0rdHR9yLlM6wt2vteuini'; $vector = 'bf49ea9d61104d8c'; $crypt = openssl_encrypt($data, $method, $key, 0, $vector); echo $crypt; ?> 我在 Pascal 中提出了这个函数(使用 David Barton 编写的 DCPcrypt v2.1 库): procedure TMainForm.Encrypt1ButtonClick(Sender: TObject); var Cipher: TDCP_rijndael; Key, Vector: RawByteString; Data, Crypt: RawByteString; begin Data := 'Hello, world!'; SetLength(Crypt, Length(Data)); Key := 'bRuD5WYw5wd0rdHR9yLlM6wt2vteuini'; Vector := 'bf49ea9d61104d8c'; Cipher := TDCP_rijndael.Create(nil); try Cipher.Init(Key[1], 256, @Vector[1]); Cipher.EncryptCTR(Data[1], Crypt[1], Length(Data)); finally Cipher.Free; end; EncryptEdit.Text := DCPBase64.Base64EncodeStr(Crypt); end; 这确实有效(在 Windows 中)。 PHP 和 Pascal 都返回:pEP16OOxov9QDfraIg== 但是,如果我为 Android 编译相同的代码并在平板电脑上运行它,我会得到非常不同的结果。这是为什么? 我确实阅读了有关转换 fmx 代码的文档,特别是处理字符串处理的内容,但我仍然不明白为什么。即使 RawByteString 是基于 0 而不是基于 1,我仍然会得到差异(尝试使用 [0] 而不是 [1])。 RawByteString 没有附加代码页,对吧?所以这个问题不可能是由某些字符串转换引起的(我认为)。那么这是怎么回事? 经过3天的努力,我终于成功了。关键是完全消除字符串的使用,并且仅使用 DCPCrypt 中基于 TByte 的例程。 下面的代码是一个测试程序,用于测试 DCPCrypt 支持的所有不同链接模式。我还添加了一个函数来实现我在这里找到的四种填充模式(与 CBC 和 ECB 一起使用): https://en.wikipedia.org/wiki/Padding_(密码学) 以及零填充和随机填充。 我选择不使用 DCPCrypt 自己的 Base64 函数,因为它们与 FMX 不兼容。相反,我使用 System.NetEncoding 单元中的对应项。 拜托,我认为自己只是一个普通的程序员,所以我希望你们当中真正的 Delphi 奇才能够找到很多可以批评的地方。但没关系。如果给出良好的反馈,我将调整代码。 现在,代码可以运行并生成与 PHP 的 openssl 函数兼容的结果(使用 CTR 模式进行测试)。我只是在这里发布此内容,希望它对寻找与我相同的解决方案的人有用。 unit MainUnit; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, System.NetEncoding, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Layouts, FMX.ScrollBox, FMX.Memo, FMX.Edit, FMX.Controls.Presentation, DCPcrypt2, DCPsha256, DCPblockciphers, DCPrijndael; type TChainingMode = (cmCBC, cmCFB8bit, cmCFBblock, cmOFB, cmCTR, cmECB); TPaddingMode = (pmZeroPadding, pmANSIX923, pmISO10126, pmISO7816, pmPKCS7, pmRandomPadding); type TMainForm = class(TForm) ScrollBox: TScrollBox; KeySizeLabel: TLabel; ChainingLabel: TLabel; EncodingLabel: TLabel; PaddingLabel: TLabel; KeyLabel: TLabel; InitVectorLabel: TLabel; DataLabel: TLabel; DecryptedLabel: TLabel; CipherLabel: TLabel; EncryptedLabel: TLabel; rbRijndael: TRadioButton; rb128bit: TRadioButton; rb256bit: TRadioButton; rbANSI: TRadioButton; rbUTF8: TRadioButton; rbUnicode: TRadioButton; rbCBC: TRadioButton; rbOFB: TRadioButton; rbCTR: TRadioButton; rbECB: TRadioButton; rbCFB8bit: TRadioButton; rbCFBblock: TRadioButton; rbZeroPadding: TRadioButton; rbANSIX923: TRadioButton; rbISO10126: TRadioButton; rbISO7816: TRadioButton; rbPKCS7: TRadioButton; rbRandomPadding: TRadioButton; KeyEdit: TEdit; InitVectorEdit: TEdit; DataMemo: TMemo; EncryptedMemo: TMemo; DecryptedMemo: TMemo; EncryptButton: TButton; DecryptButton: TButton; procedure FormCreate(Sender: TObject); procedure EncryptButtonClick(Sender: TObject); procedure DecryptButtonClick(Sender: TObject); public procedure GetOptions(var Key: TBytes; var KeySize: integer; var InitVector: TBytes; var Encoding: TEncoding; var ChainingMode: TChainingMode; var PaddingMode: TPaddingMode); end; var MainForm: TMainForm; implementation {$R *.fmx} {$R *.LgXhdpiPh.fmx ANDROID} function BytesToHex(B: TBytes): string; var I: integer; begin Result := ''; for I := Low(B) to High(B) do Result := Result + IntToHex(B[I]) + ' '; end; procedure BytePadding(var Data: TBytes; BlockSize: integer; PaddingMode: TPaddingMode); // Supports: ANSI X.923, ISO 10126, ISO 7816, PKCS7, zero padding and random padding var I, DataBlocks, DataLength, PaddingStart, PaddingCount: integer; begin BlockSize := BlockSize div 8; // convert bits to bytes // Zero and Random padding do not use end-markers, so if Length(Data) is a multiple of BlockSize, no padding is needed if PaddingMode in [pmZeroPadding, pmRandomPadding] then if Length(Data) mod BlockSize = 0 then Exit; DataBlocks := (Length(Data) div BlockSize) + 1; DataLength := DataBlocks * BlockSize; PaddingCount := DataLength - Length(Data); // ANSIX923, ISO10126 and PKCS7 store the padding length in a 1 byte end-marker, so any padding length > $FF is not supported if PaddingMode in [pmANSIX923, pmISO10126, pmPKCS7] then if PaddingCount > $FF then Exit; PaddingStart := Length(Data); SetLength(Data, DataLength); case PaddingMode of pmZeroPadding, pmANSIX923, pmISO7816: // fill with $00 bytes FillChar(Data[PaddingStart], PaddingCount, 0); pmPKCS7: // fill with PaddingCount bytes FillChar(Data[PaddingStart], PaddingCount, PaddingCount); pmRandomPadding, pmISO10126: // fill with random bytes for I := PaddingStart to DataLength-1 do Data[I] := Random($FF); end; case PaddingMode of pmANSIX923, pmISO10126: Data[DataLength-1] := PaddingCount; // set end-marker with number of bytes added pmISO7816: Data[PaddingStart] := $80; // set fixed end-markder $80 end; end; procedure EncryptAES(const Data: TBytes; var Crypt: TBytes; const Key: TBytes; KeySize: integer; const InitVector: TBytes; ChainingMode: TChainingMode; PaddingMode: TPaddingMode); overload; var Cipher: TDCP_rijndael; begin Cipher := TDCP_rijndael.Create(nil); try Cipher.Init(Key[0], KeySize, @InitVector[0]); // Copy Data => Crypt Crypt := Copy(Data, 0, Length(Data)); // Padd Crypt to required length (for Block based algorithms) if ChainingMode in [cmCBC, cmECB] then BytePadding(Crypt, Cipher.BlockSize, PaddingMode); // Encrypt Crypt using the algorithm specified in ChainingMode case ChainingMode of cmCBC: Cipher.EncryptCBC(Crypt[0], Crypt[0], Length(Crypt)); cmCFB8bit: Cipher.EncryptCFB8bit(Crypt[0], Crypt[0], Length(Crypt)); cmCFBblock: Cipher.EncryptCFBblock(Crypt[0], Crypt[0], Length(Crypt)); cmOFB: Cipher.EncryptOFB(Crypt[0], Crypt[0], Length(Crypt)); cmCTR: Cipher.EncryptCTR(Crypt[0], Crypt[0], Length(Crypt)); cmECB: Cipher.EncryptECB(Crypt[0], Crypt[0]); end; finally Cipher.Free; end; end; procedure DecryptAES(const Crypt: TBytes; var Data: TBytes; const Key: TBytes; KeySize: integer; const InitVector: TBytes; ChainingMode: TChainingMode; PaddingMode: TPaddingMode); overload; var Cipher: TDCP_rijndael; I: integer; begin Cipher := TDCP_rijndael.Create(nil); try Cipher.Init(Key[0], KeySize, @InitVector[0]); // Copy Crypt => Data Data := Copy(Crypt, 0, Length(Crypt)); // Decrypt Data using the algorithm specified in ChainingMode case ChainingMode of cmCBC: Cipher.DecryptCBC(Data[0], Data[0], Length(Data)); cmCFB8bit: Cipher.DecryptCFB8bit(Data[0], Data[0], Length(Data)); cmCFBblock: Cipher.DecryptCFBblock(Data[0], Data[0], Length(Data)); cmOFB: Cipher.DecryptOFB(Data[0], Data[0], Length(Data)); cmCTR: Cipher.DecryptCTR(Data[0], Data[0], Length(Data)); cmECB: Cipher.DecryptECB(Data[0], Data[0]); end; // Correct the length of Data, based on the used PaddingMode (only for Block based algorithms) if ChainingMode in [cmCBC, cmECB] then case PaddingMode of pmANSIX923, pmISO10126, pmPKCS7: // these modes store the original Padding count in the last byte SetLength(Data, Length(Data) - Data[Length(Data)-1]); pmISO7816: // this mode uses a fixed end-marker. Find it and correct length accordingly. for I := Length(Data)-1 downto 0 do if Data[I] = $80 then begin SetLength(Data, I); Break; end; end; finally Cipher.Free; end; end; procedure TMainForm.FormCreate(Sender: TObject); begin EncryptedMemo.Lines.Clear; DecryptedMemo.Lines.Clear; end; procedure TMainForm.GetOptions(var Key: TBytes; var KeySize: integer; var InitVector: TBytes; var Encoding: TEncoding; var ChainingMode: TChainingMode; var PaddingMode: TPaddingMode); begin KeySize := 256; Encoding := TEncoding.ANSI; ChainingMode := cmCBC; PaddingMode := pmPKCS7; if rb128bit.IsChecked then KeySize := 128; if rb256bit.IsChecked then KeySize := 256; if rbCBC.IsChecked then ChainingMode := cmCBC; if rbCFB8bit.IsChecked then ChainingMode := cmCFB8bit; if rbCFBblock.IsChecked then ChainingMode := cmCFBblock; if rbOFB.IsChecked then ChainingMode := cmOFB; if rbCTR.IsChecked then ChainingMode := cmCTR; if rbECB.IsChecked then ChainingMode := cmECB; if rbZeroPadding.IsChecked then PaddingMode := pmZeroPadding; if rbANSIX923.IsChecked then PaddingMode := pmANSIX923; if rbISO10126.IsChecked then PaddingMode := pmISO10126; if rbISO7816.IsChecked then PaddingMode := pmISO7816; if rbPKCS7.IsChecked then PaddingMode := pmPKCS7; if rbRandomPadding.IsChecked then PaddingMode := pmRandomPadding; if rbANSI.IsChecked then Encoding := TEncoding.ANSI; if rbUTF8.IsChecked then Encoding := TEncoding.UTF8; if rbUnicode.IsChecked then Encoding := TEncoding.Unicode; Key := Encoding.GetBytes(KeyEdit.Text); InitVector := Encoding.GetBytes(InitVectorEdit.Text); end; procedure TMainForm.EncryptButtonClick(Sender: TObject); var Keysize: integer; Encoding: TEncoding; ChainingMode: TChainingMode; PaddingMode: TPaddingMode; Key, InitVector, Data, Crypt: TBytes; begin GetOptions(Key, KeySize, InitVector, Encoding, ChainingMode, PaddingMode); Data := Encoding.GetBytes(DataMemo.Text); EncryptAES(Data, Crypt, Key, KeySize, InitVector, ChainingMode, PaddingMode); EncryptedMemo.Text := TNetEncoding.Base64.EncodeBytesToString(Crypt); end; procedure TMainForm.DecryptButtonClick(Sender: TObject); var Keysize: integer; Encoding: TEncoding; ChainingMode: TChainingMode; PaddingMode: TPaddingMode; Key, InitVector, Data, Crypt: TBytes; begin GetOptions(Key, KeySize, InitVector, Encoding, ChainingMode, PaddingMode); Crypt := TNetEncoding.Base64.DecodeStringToBytes(EncryptedMemo.Text); DecryptAES(Crypt, Data, Key, KeySize, InitVector, ChainingMode, PaddingMode); DecryptedMemo.Text := Encoding.GetString(Data); end; end. Android 字符串从位置 0 开始。您可以使用 low(Data) 返回字符串的第一个字符,库内部也使用从位置 1 开始的字符串,这不会在 android 或 ios 中运行。对于多平台,我们不应该使用 for i:=1 to length(string) 而应该使用 for l in string 我认为LockBox3应该可以解决你的问题。 我在这里面临着同样的问题,并且想运行您测试应用程序。能提供一下fmx表格的源码吗? 非常感谢!

回答 3 投票 0

如何使用 Delphi 将各种文档类型添加到 Firebird BLOB 字段

背景:我们的产品包括一个文档管理系统,允许用户保存和检索各种文档类型(.PDF、.DOC、.JPG、.PNG、.TIF 等)。目前

回答 1 投票 0

使用 mongo-delphi-driver 获取具有特定 _id 的文档

我必须在mongodb上执行查询,我想仅选择具有特定_id(类型ObjectId)的文档。 我使用“严格模式”语法,特别是运算符 $oid 将 _id 与

回答 4 投票 0

德尔福和Doxygen

我想使用 doxygen + pas2dox 记录我的源代码。当我设置好所有内容(包括过滤器和提取选项(提取所有内容))时,doxygen 运行良好。但是生成的文档...

回答 1 投票 0

如何使用 Delphi 10(西雅图)在 Excel 中合并 2 个单元格

互联网上曾经有很多Delphi参考资料。我尝试用谷歌搜索,我从黛博拉·佩特 (Deborah Pate) 那里获得的 com 编程的首选现在给了我一个 404 页面未找到!不好了! 无论如何,我正在使用...

回答 1 投票 0

如何在 Delphi 中将带有图像的 RichText (RTF) 文档转换为 HTML?

我一直在尝试找到一个免费的(最好是开源的)组件或库,它可以将嵌入图像的 RTF 文件转换为 HTML 文件和图像文件或更好的 HTML 和图像

回答 2 投票 0

当最大化表单时(即使在 IDE 设计器中),Delphi 表单会出现不正确的行为,为什么?

这是完整 Delphi 应用程序的精简版本。 即使在Delphi7 IDE设计器中,当双击窗体的标题时,窗体也会错误地最大化,这意味着左上角

回答 1 投票 0

Google Oauth2 出现 invalid_grant 错误问题

大家加油, 我们一直在深入阅读关于从 google 交换 access_token 的 google 文档,以便我们的(delphi)桌面应用程序从服务器端与 google 进行 SSO。这是 p...

回答 2 投票 0

修改 SAM 密码策略时出错

我用 pascal 编写了一个程序,使用 sam api 启用/禁用“密码必须满足复杂性要求”。每个函数都会返回 STATUS_SUCCESS,除了 SamSetInformationD...

回答 1 投票 0

编写一段代码,将一个数字分为几个不同的区间,并对每个区间进行特殊计算

我想编写一段代码,将一个数字分为几个不同的区间,并对每个区间进行特殊计算,如下所示。 最后,显示所有获得的数字的总和。我...

回答 1 投票 0

如何使用 TIdMessage 处理将内联图像分隔到不同边界的 MIME 格式?

我的 MIME 格式如下: 内容类型:多部分/替代;边界=“qawqKLHOZYgscUPhZKw5hacv=_UlERjiEj” MIME 版本:1.0 日期:2024 年 3 月 25 日星期一 10:17:34 +0800 这是一个多...

回答 1 投票 0

在Delphi中删除字符串中的多个空格的最简单方法是什么?

假设我的字符串是: “狐狸跳过了圆木。” 那么它应该变成: “狐狸跳过了圆木。” 实现这一目标最简单的(1-3行)是什么,

回答 1 投票 0

Delphi 到 C# 转换

我需要将用 Delphi 编程语言编写的程序转换为 C#,但我遇到了问题。 我无法找出正确的转换。任何帮助都会很棒。 我有注意...

回答 2 投票 0

将 C 转换为 Delphi - 指南

我正在将低级 C 库转换为 Delphi 编程语言。 我发现很多演员。我觉得这在C世界很正常。我认为我可以安全地将它们扔掉。仅此处整数为 32 位。

回答 3 投票 0

如何在Java项目中使用Delphi代码? [已关闭]

我有一个用 Delphi 编程语言编写的古老但非常复杂的算法,我想将其用作 Java 项目的服务。 我的计划是建立一个可以为算法提供服务的网站

回答 2 投票 0

Delphi 在 Visual Studio IDE 上可用吗?

我已经决定(无论是好还是坏),开始学习 Delphi 编程语言。但是,它在 Visual Studio 中可用吗?或者有适合它的IDE吗?我用谷歌搜索了 Delphi,但是 cam...

回答 7 投票 0

Delphi 中的游戏开发

我想尝试制作一些用于个人/学习目的的简单游戏。我所说的简单游戏是指平台游戏、迷宫游戏、街机游戏等游戏。我也想有一天创建一个

回答 4 投票 0

如何更改 TWebScrollBox 组件上滚动条的颜色?

我有一个 TWebScrollBox,里面有很多元素,但我不喜欢其中默认滚动条的颜色。 这是我在 TWebScrollBox 上的滚动条: 你可以看到滚动条由两个

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.