DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: tkzcol
今日帖子: 3
在线用户: 1
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/6 13:14:43
标题:
Cnpack使用sm2加密UTF8 浏览:2016
加入我的收藏
楼主: 我使用Cnpack里面的sm2签名后,在第三方网站验签不通过,怀疑是utf8编码的问题,下面是我的代码,用过的大佬帮我看一下
  MSG2: String = 'biz_con_tent={"out_trade_no":"123456789","seller_name":"银盛支付服务股份有限公司行业发展部",'+
  '"total_amount":"2.99","subject":"公众号","is_minipg":"1","appid":"wxf71930fbcc125f64","timeout_express":"96h",'+
  '"currency":"CNY","business_code":"01000010","seller_id":"826584848160007","sub_openid":'+
  '"oc0KJ5Kcr5lhbKgmkqXPENrGzsdw"}&charset=utf-8&method=ysepay.online.weixin.pay¬ify_url=http://127.0.0.1&partner_id=826584848160007&sign_type=SM×tamp=2023-11-05 05:11&version=3.0';

USER_A: String = 'BCSoftLib@1672';

procedure TestFp256SignExample;
var
  SM2: TCnSM2;
  PrivateKey: TCnSM2PrivateKey;
  PublicKey: TCnSM2PublicKey;
  Sig: TCnSM2Signature;
  sU:UTF8String;
begin
  SM2 := TCnSM2.Create(); // 注意这里不是标准 SM2 曲线参数,内部不能用预计算的加速算法
  PrivateKey := TCnSM2PrivateKey.Create;
  PublicKey := TCnSM2PublicKey.Create;
  Sig := TCnSM2Signature.Create;
//  PublicKey.X.SetHex('0AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A');
//  PublicKey.Y.SetHex('7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857');
//  PrivateKey.SetHex('128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263');
  PublicKey.X.SetHex('87b15fc6c3f8d4401323fd98a97cfce2871dfa203fcd8da1b7227c4f73c85947');
  PublicKey.Y.SetHex('d0c3f23325e78cc4f81414351cf1914c4c4852f9e74b51a7b86d0482d179f280');
  PrivateKey.SetHex('3ce4497107cba3a6a5db4adf4b3d6a2ab74fe862100cdfc3cdd303fa2fb368e0');
  FormSM2.edtSM2PrivateKey.Text:=PrivateKey.ToHex();
  FormSM2.edtSM2PublicKey.Text := PublicKey.ToString;
  // 里头的随机数 K 要 6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F
   var cText:=TEncoding.UTF8.GetBytes(MSG2);
  if CnSM2SignData(USER_A, @cText[0], Length(cText), Sig, PrivateKey, PublicKey, SM2) then
  begin

    FormSM2.mmoSignResult.Lines.Add(Sig.R.ToHex);
    FormSM2.mmoSignResult.Lines.Add(Sig.S.ToHex);

    ShowMessage('Sig OK: ' + Sig.R.ToHex + ', ' + Sig.S.ToHex);
    if CnSM2VerifyData(USER_A, @cText[0], Length(cText), Sig, PublicKey, SM2) then
      ShowMessage('Verify OK.');
  end;

  Sig.Free;
  PrivateKey.Free;
  PublicKey.Free;
  SM2.Free;
end;
用的就是Cnpack里面的例子,改的这个函数TestFp256SignExample,原函数用的是Ansistring,
第三方验签的网站用的是这个网址https://const.net.cn/tool/sm2/verify/
----------------------------------------------
-
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/6 16:02:18
1楼: 那个验签网站的UserID填的貌似是十六进制格式,你传的USER_A是string,先纠正这个差异?
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/6 18:11:26
2楼: 不可以,然后我试着将签名的string换成hexstring也是不可以的
----------------------------------------------
-
作者:
男 denkun (dk) ★☆☆☆☆ -
普通会员
2023/11/7 8:07:05
3楼:
----------------------------------------------
-
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/7 10:30:50
4楼: 第三方验签网站你去验签时具体贴的啥内容?
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/7 18:03:43
5楼: 第三方验签网站我贴的也是转成了16进制的内容
----------------------------------------------
-
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/7 18:21:04
6楼: function strtohex(s:string):string;
var
 I:integer;
begin
 var c:=TEncoding.Default.GetBytes(s);
 result:='';
 for I:=0  to Length(c)-1 do
  begin
     Result:=result+inttohex(Ord(c[I]));
  end;

end;
procedure TFormSM2.Button1Click(Sender: TObject);
var
  SM2: TCnSM2;
  PrivateKey: TCnSM2PrivateKey;
  PublicKey: TCnSM2PublicKey;
  Sig: TCnSM2Signature;
  lvUser:string;
begin
  lvUser:=strtohex(USER_A);
  self.Memo1.Lines.Add('userid='+lvUser);

  SM2 := TCnSM2.Create(ctSM2); // 注意这里不是标准 SM2 曲线参数,内部不能用预计算的加速算法
  PrivateKey := TCnSM2PrivateKey.Create;
  PublicKey := TCnSM2PublicKey.Create;
  Sig := TCnSM2Signature.Create;
  PrivateKey.SetHex('F4A115840CE610EAEBE6682230D072E88AE891CA803EBB75769A9300E8062742');
  PublicKey.Assign(SM2.Generator);
  SM2.MultiplePoint(PrivateKey, PublicKey);
  Self.Memo1.Lines.Add('PrivateKey='+PrivateKey.ToHex());
  Self.Memo1.Lines.Add('PublicKey='+PublicKey.ToHex());


  var s:=TEncoding.UTF8.GetBytes('你好,大D');
 // s:=TEncoding.Default.GetBytes('你好,大D');
  var ctext:='';
  for var I :=0 to Length(s)-1 do
   begin
     cText:=cText+inttohex(Ord(s[I]));
   end;
  Self.Memo1.Lines.Add('Data='+cText);

  // 里头的随机数 K 要 6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F
  if CnSM2SignData(lvUser, @cText[1], Length(cText), Sig, PrivateKey, PublicKey, SM2) then
  begin
    ShowMessage('Sig OK: ' + Sig.R.ToHex + ', ' + Sig.S.ToHex);
    Self.Memo1.Lines.Add('----------');
    self.Memo1.Lines.Add('R='+sig.R.ToHex());
    self.Memo1.Lines.Add('S='+sig.S.ToHex());

    if CnSM2VerifyData(USER_A, @s[0], Length(s)-1, Sig, PublicKey, SM2) then
      ShowMessage('Verify OK.');
  end;

  Sig.Free;
  PrivateKey.Free;
  PublicKey.Free;
  SM2.Free;
end;
----------------------------------------------
-
作者:
男 yanggs18 (yanggs18) ▲▲▲▲▲ -
普通会员
2023/11/8 16:17:53
7楼: USER_A: AnsiString = '1234567812345678';  //java bouncycastle 默认
----------------------------------------------
-
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/20 0:22:37
8楼: public static final String SM3_SM2 = "sm3WithSM2Encryption";
这里java里面使用的算法,对应的CNPack里面的sm2应该用哪一个呢
  TCnEccCurveType = (ctCustomized, ctSM2, ctSM2Example192, ctSM2Example256,
    ctRfc4754ECDSAExample256, ctSecp224r1, ctSecp224k1, ctSecp256k1, ctPrime256v1,
    ctWapiPrime192v1, ctSM9Bn256v1);这是CNVCL里的
----------------------------------------------
-
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/20 6:34:08
9楼: 楼上,直接使用CnSM2.pas里的封装好了的CnSM2EncryptData函数可以实现标准SM2加密,不需要自己指定特定的椭圆曲线。

function CnSM2EncryptData(PlainData: Pointer; DataLen: Integer; OutStream:
  TStream; PublicKey: TCnSM2PublicKey; SM2: TCnSM2 = nil;
  SequenceType: TCnSM2CryptSequenceType = cstC1C3C2;
  IncludePrefixByte: Boolean = True; const RandHex: string = ''): Boolean; overload;
{* 用公钥对数据块进行加密,参考 GM/T0003.4-2012《SM2椭圆曲线公钥密码算法
   第4部分:公钥加密算法》中的运算规则,不同于普通 ECC 与 RSA 的对齐规则
   SequenceType 用来指明内部拼接采用默认国标的 C1C3C2 还是想当然的 C1C2C3
   IncludePrefixByte 用来声明是否包括 C1 前导的 $04 一字节,默认包括
   返回加密是否成功,加密结果写入 OutStream 中}
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/20 12:09:34
10楼: 哦,我说错了,其实我说的还是签名,不管我怎么签名,就是和其他的验签不过
----------------------------------------------
-
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/21 17:06:50
11楼: 目前签名的话,用Cnapck验签是可以通过的,但是我对接的接口,SDK用的是Java的,然后我用里面的验签就不通过了。接口所提供的SDK用的是cfca-sadk包
下面是他签名的代码
public byte[] p1SignMessage(String signAlg, byte[] sourceData, PrivateKey privateKey, Session session) throws PKIException {
        if (LoggerManager.debugLogger.isDebugEnabled()) {
          StringBuffer buffer = new StringBuffer();
          buffer.append("p1SignMessage>>>>>>Running");
          buffer.append("\n signAlg: ");
          buffer.append(SADKDebugger.dump(signAlg));
          buffer.append("\n sourceData: ");
          buffer.append(SADKDebugger.dump(sourceData));
          buffer.append("\n PrivateKey: ");
          buffer.append(SADKDebugger.dump(privateKey));
          buffer.append("\n session: ");
          buffer.append(SADKDebugger.dump(session));
          LoggerManager.debugLogger.debug(buffer.toString());
        }

        boolean isFailed = false;

        byte[] var9;
        try {
          byte[] signData = session.sign(new Mechanism(signAlg), privateKey, sourceData);
          byte[] binarySignValue = this.SM2RStoASN1(signData, signAlg);
          byte[] base64SignValue = this.outputSignResult(binarySignValue);
          if (LoggerManager.debugLogger.isDebugEnabled()) {
          LoggerManager.debugLogger.debug("p1SignMessage<<<<<<Finished");
          }

          var9 = base64SignValue;
        } catch (PKIException var16) {
          isFailed = true;
          LoggerManager.exceptionLogger.error("p1SignMessage<<<<<<Failure", var16);
          throw var16;
        } catch (Throwable var17) {
          isFailed = true;
          LoggerManager.exceptionLogger.error("p1SignMessage<<<<<<Failure", var17);
          throw new PKIException("p1SignMessage Failure", var17);
        } finally {
          if (isFailed && LoggerManager.exceptionLogger.isErrorEnabled()) {
          StringBuffer buffer = new StringBuffer();
          buffer.append("p1SignMessage>>>>>>Running");
          buffer.append("\n signAlg: ");
          buffer.append(SADKDebugger.dump(signAlg));
          buffer.append("\n sourceData: ");
          buffer.append(SADKDebugger.dump(sourceData));
          buffer.append("\n PrivateKey: ");
          buffer.append(SADKDebugger.dump(privateKey));
          buffer.append("\n session: ");
          buffer.append(SADKDebugger.dump(session));
          LoggerManager.exceptionLogger.error(buffer.toString());
          }

        }

        return var9;
    }
----------------------------------------------
-
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/21 17:15:18
12楼: 另外,他调用这个签名之前 ,指定了算法
String signAlg = Mechanism.SM3_SM2;//SM3WithSM2
      // 签名,必须指定签名算法,返回BASE64签名结果
signed = util.p1SignMessage(signAlg, sourceData, priKey, session);
----------------------------------------------
-
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/21 18:34:23
13楼: 注意这一句Java代码:this.SM2RStoASN1(signData, signAlg);

从字面上看它把签名结果里的R和S俩值转换成了ASN1格式,而你的代码中是拼接的R的Hex和S的Hex,这俩应该是对不上号的。
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/21 20:13:27
14楼: 是的,他最终生成的会比我用Cnapck生成的长一点点
----------------------------------------------
-
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/21 20:54:19
15楼: 可以用CnVcl中签名结果类TCnEccSignature的ToASN1Hex方法将签名结果转换成ASN1格式的十六进制。
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/22 0:22:22
16楼: 目前来看,最络转换是楼上所说的方法,必须把R和S合并后再转成ASNI,再base64格式化
但是他这个签名从头到尾没有看到传入userid这个参数,我从他的私钥里看到有Dint值
并且跟踪后在Sign有一段函数
    public void sign(byte[] hash, BigInteger userD, SM2Result sm2Ret) {
        if (sm2Ret == null) {
          throw new SecurityException("null not allowed for sm2Ret");
        } else {
          try {
          BigInteger[] signature = generateSignature(hash, userD);
          sm2Ret.r = signature[0];
          sm2Ret.s = signature[1];
          } catch (PKIException var5) {
          throw new SecurityException(var5.getMessage());
          }
        }
    }
这里面的userD就是私钥里看到有Dint的值,所以怀疑这个Dint就是userid这个参数,
但目前有个问题,我们的参数userid是一个AnString,而java里同的是一个BigInteger
他的值是
27542118920543702403654067052892950960095467836988035615188147333450236651744
我不管是直接
  userid:='27542118920543702403654067052892950960095467836988035615188147333450236651744'
然后传入,还是用其他方法,最终都验签不过
----------------------------------------------
-
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/22 6:24:22
17楼: 正常写代码的话,这个大整数应该就是私钥本身。
椭圆曲线的私钥是一个大随机整数,公钥是根据这个整数算出来的椭圆曲线点坐标。

userid应该都没传,使用默认的ASCII码1234567812345678
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/23 2:15:12
18楼: @Cnpack,java的这个加库里面,私钥有两种格式的文件,一种是sm2格式,一种是pfx格式。他打开sm2用的是        
  PKCS12_SM2 P12 = new PKCS12_SM2(sm2FileData);
CNVCL里是否没有对这种文件的封装
我按照Java里的代码,自己读取,但是最终乱码了
  var Stream := TFileStream.Create('D:\data\test_sm2.sm2', fmOpenRead or fmShareDenyWrite);
  Stream.Position:=0;
  Buf:=StreamToBytes(Stream);
  var  ANSBuf:TBytes;
  Base64Decode(BytesToAnsi(BUF),ANSBuf);
  var s:AnsiString;
  s:=BytesToAnsi(ANSBuf);
此帖子包含附件:wuxi15_2023112321512.rar 大小:952B
----------------------------------------------
-
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/23 9:03:54
19楼: 不确定扩展名是sm2的是啥格式,没听说过。
PFX格式cnvcl目前不支持。
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/26 22:38:43
20楼: 我说的sm2应该是java库自己封装的,我在解释的过程过,发现有一中叫ASN1的东西。然后Delphi对于ASN1的资料很少,不知道CNPACK里面有没有对asn1转换的库,例如直接转换成string.
----------------------------------------------
-
作者:
男 powerpcer (大强) ★☆☆☆☆ -
禁用账号
2023/11/26 23:07:34
21楼: ……
被禁用帐号,帖子内容自动屏蔽!
……

----------------------------------------------
呆湾傻冒
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/27 10:55:52
22楼: ASN.1是一种对多个类型数据的树形包装格式,cnvcl\Source\Crypto\CnBerUtils.pas提供了对其解析和组装的接口。
相关例子见cnvcl\Example\VCL\BerParse
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/27 12:39:41
23楼: 你这个是ber吧,好像有个der的东西,cnpack没有吧
----------------------------------------------
-
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/27 15:38:44
24楼: 官方文档:DER is a subset of BER providing for exactly one way to encode an ASN.1 value.
DER是BER的子集。
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/28 21:53:46
24楼: 还得请教一个问题,SM4DecryptCbcBytes解密之后,得到的数据,如果后面几位是空的,他会填充16进去,我要如何计算从哪个位置开始他是空的呢。如果我用土方法进行循环,得到从哪个位置写的是16,然后判断从这里开始他就是无效的,会不会有问题,例如,有一些有效的数据,他中间有一位就是16呢
----------------------------------------------
-
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/29 9:25:32
25楼: CBC这种分块加密模式规定会补齐缺的块,而Padding(对齐)就是为了应对这种问题而发明的,典型的对齐类型有PKCS7等。

CnPemUtils.pas里有这俩函数可以用来处理,加密前先加Padding、解密后去除Padding:

procedure BytesAddPKCS7Padding(var Data: TBytes; BlockSize: Integer);
{* 给字节数组末尾加上 PKCS7 规定的填充“几个几”的填充数据}

procedure BytesRemovePKCS7Padding(var Data: TBytes);
{* 去除 PKCS7 规定的字节数组末尾填充“几个几”的填充数据}

SM4的BlockSize是16。
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/30 0:17:10
26楼: 我看到CNPack里需读取私钥的文件头是
-----BEGIN EC PARAMETERS-----
而我用其他库读取的pfx,他的文件头是
-----BEGIN PRIVATE KEY-----
我将这个私钥保存Pem用CNPack读取,是不可以读取的。
这两者是不是压根就不是同一种东西,也就说只有-----BEGIN EC PARAMETERS-----才是国密sm2的,而如果用的是Pfx,也就是-----BEGIN PRIVATE KEY-----,根本就不是国密sm2
----------------------------------------------
-
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/30 2:52:07
27楼: 我好像明白了,pfx文件只有文件头是
-----BEGIN EC PARAMETERS-----的才是sm2的证书,如果是-----BEGIN PRIVATE KEY-----的,就是标准的RSA证书。而RSA证书Cnpack也是支持的。只需要用ICS打开pfx,然后保存成Pem就可以了。
另外这几天折腾了sm2的签名,发现节果的base64和Java的base64不同,只是输出不同而己,但是浪费了我很多时间才查清楚。我这里增加了两个函数,群主可以考虑是否加上,以后有使用者和其他语言方便对比,节省精力。
两个函数,一个是输入base64,别一个是反过来,根据base64设置Key
 TCnSM2Signaturehelper= class helper for TCnEccSignature
  public
   function ToAnsiBase64(FixedLen: Integer=0): string;
   function SetAsn1Base64(const Buf: AnsiString):boolean;
 end;

function TCnSM2Signaturehelper.SetAsn1Base64(const Buf: AnsiString): boolean;
begin
   var B: TBytes;
   Result:=false;
   Base64Decode(string(Buf), B);
   Result:=SetAsn1Hex(BytesToHex(B));
end;

function TCnSM2Signaturehelper.ToAnsiBase64(FixedLen: Integer): string;
begin
  var   Writer := TCnBerWriter.Create;
  var   Root := Writer.AddContainerNode(CN_BER_TAG_SEQUENCE);
  var      Stream :=TMemoryStream.Create;
  Result:='';
   try
     AddBigNumberToWriter(Writer,Self.R, Root);
     AddBigNumberToWriter(Writer,Self.S, Root);
     Writer.SaveToStream(Stream);
     Stream.Position:=0;
     Base64Encode(Stream.Memory,Stream.Size,Result);
   finally
     Writer.Free;
     Stream.Free;
   end;
end;
----------------------------------------------
-
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/30 9:13:05
28楼: 好,我看看能否集成。
不过如果集成的话,我们就不用helper了,直接在原类上增加方法了。
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/30 10:18:59
29楼: 已更新CnECC.pas,增加这俩方法。

注意是ASN1,不是Ansi。
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2023/11/30 15:16:39
30楼: 更新的函数应该是有错误的
function TCnEccSignature.SetAsn1Base64(const Buf: AnsiString): Boolean;
var
  B: TBytes;
  Reader: TCnBerReader;
  NR, NS: TCnBerReadNode;
begin
  Result := False;
//  B := HexToBytes(string(Buf)); 参数是一个base64,不是Hex
  Base64Decode(Buf,B);
  if Length(B) <= 1 then
    Exit;

  Reader := nil;
  try
 //   if Base64Decode(string(Buf), B) = ECN_BASE64_OK then
    begin
      Reader := TCnBerReader.Create(PByte(@B[0]), Length(B));
      Reader.ParseToTree;

      if Reader.TotalCount = 3 then
      begin
        NR := Reader.Items[1];
        NS := Reader.Items[2];

        PutIndexedBigIntegerToBigNumber(NR, FR);
        PutIndexedBigIntegerToBigNumber(NS, FS);
        Result := True;
      end;
    end;
  finally
    Reader.Free;
  end;
end;
----------------------------------------------
-
作者:
男 cnpack (CnPack) ★☆☆☆☆ -
普通会员
2023/11/30 15:23:16
31楼: 手滑,感谢指出,已修正。
----------------------------------------------
欢迎使用CnPack IDE Wizards
http://www.cnpack.org/
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行6020.02毫秒 RSS