【问题标题】:Visual FoxPro (VFP) CTOBIN and BINTOC Functions - Equivalent In .NetVisual FoxPro (VFP) CTOBIN 和 BINTOC 函数 - .Net 中的等效函数
【发布时间】:2012-02-16 09:59:07
【问题描述】:

我们正在重写一些以前在 Visual FoxPro 中开发的应用程序,并使用 .Net(使用 C#)重新开发它们

这是我们的场景: 我们的应用程序使用智能卡。我们从具有名称和编号的智能卡中读取数据。名称在可读文本中恢复正常,但数字,在这种情况下,“900”以 2 字节字符表示(131 和 132)的形式返回,看起来像这样 - ƒ„

这 2 个特殊字符可以在扩展的 Ascii 表中看到。现在你可以看到 2 个字节是 131 和 132,并且可以变化,因为没有单一的标准扩展 ascii 表(据我所知,阅读一些这里的帖子)

所以...智能卡之前是使用 VFP 中的 BINTOC 函数写入的,因此 900 被写入卡中作为 ƒ„。在 foxpro 中,这 2 个特殊字符可以使用 CTOBIN 函数转换回整数格式.. FoxPro 中的另一个内置函数..

所以(终于切入正题)- 到目前为止,我们无法将这两个特殊字符转换回 int (900),我们想知道这是否可以在 .NET 中读取整数的字符表示返回一个实际的整数。

或者有没有办法用 C# 重写这两个 VFP 函数的逻辑?

更新: 经过一番摆弄,我们意识到要将 900 转换为 2 字节,我们需要将 900 转换为 16 位二进制值,然后我们需要将 16 位二进制值转换为十进制值。

如上所述,我们收到了 131 和 132 以及它们对应的二进制值,分别为 10000011(十进制值 131)和 10000100(十进制值 132)。 当我们将这两个值连接到“1000001110000100”时,它会给出十进制值 33668,但是如果我们删除前导 1 并将“000001110000100”转换为十进制,它会给出正确的值 900...

不太清楚为什么会这样……

任何帮助将不胜感激。

【问题讨论】:

  • 问题已解决。我们将数字 900 转换为二进制,将 9 - 16 (内含)的值作为我们的第二个字节,并获取剩余的值并使用前导 1 对其进行更新,因为该数字 > 127。这在转换任何数字的两个方向上都有效> 127(并且小于 32,7??无论上限是多少)
  • 示例:二进制中的 900 = 1110000100。取最后 8 位 (10000100) 并转换为十进制 = 132。取前 2 位 (11) 并应用 5 个后续 0,并以二进制值开头一个 1,所以它看起来像这样 - 10000011。将其转换为十进制,它是 131。现在要将 131、132 十进制值重新转换为单个二进制值以转换回十进制,我们将它们单独转换并将它们连接起来给我们1000001110000100。现在,只需将位置 1 中的 1 替换为 0 即可得到原始的 16 位二进制值,如果我们使用 2 x 位块,我们只需要开头的 1
  • 如果您认为您的问题已得到充分回答,请随时将其发布为您问题的答案。这将允许您将此问题标记为已回答。
  • 您可以将整个问题重写为“如何使用 C# 将使用 VFP BINTOC() 函数存储的 16 位有符号整数转换为十进制”,这将使它对其他人更有用读者也不太可能因为过于本地化而被关闭。

标签: c# encoding ascii smartcard visual-foxpro


【解决方案1】:

看起来 VFP 将您的值存储为带符号的 16 位(短)整数。负数对我来说似乎有一个奇怪的转换点,但它将 128 添加到 8 位数字并将 32768 添加到 16 位数字。

因此,从字符串转换您的 16 位数字应该像将其读取为 16 位整数然后从中取出 32768 一样简单。如果您必须手动执行此操作,则必须将第一个数字乘以 256,然后添加第二个数字以获得存储的值。然后从这个数字中取出 32768 得到你的值。

例子:

131 * 256 = 33536
33536 + 132 = 33668
33668 - 32768 = 900

您可以尝试按照 http://msdn.microsoft.com/en-us/library/ms131059.aspxhttp://msdn.microsoft.com/en-us/library/tw38dw27.aspx 使用 C# 转换来为您完成至少一些工作,但如果不是,手动编写上述代码应该不会太难。

【讨论】:

    【解决方案2】:

    这已经晚了几年,但这是一个可行的例子。

    public ulong CharToBin(byte[] s)
    {
      if (s == null || s.Length < 1 || s.Length > 8)
        return 0ul;
    
      var v = s.Select(c => (ulong)c).ToArray();
      var result = 0ul;
      var multiplier = 1ul;
      for (var i = 0; i < v.Length; i++)
      {
        if (i > 0)
          multiplier *= 256ul;
    
        result += v[i] * multiplier;
      }
    
      return result;
    }
    

    这是 CTOBIN 的 VFP 8 和更早版本的等效版本,涵盖了您的场景。您应该能够根据上面的代码编写自己的 BINTOC。 VFP 9 增加了对多个选项的支持,例如非反转二进制数据、货币和双精度数据类型以及有符号值。此示例仅涵盖反向无符号二进制文件,如支持的旧版 VFP。

    一些注意事项:

    • 代码支持 1、2、4 和 8 字节值,涵盖所有 最大为System.UInt64 的无符号数值。
    • 在铸造之前 结果下降到您预期的数字类型,您应该验证 天花板。例如,如果您需要一个 Int32,则检查结果 在执行演员表之前反对Int32.MaxValue
    • 该示例通过接受一个字符来避免字符串编码的复杂性 字节数组。您需要了解使用哪种编码 读取字符串,然后应用相同的编码来获取字节数组 在调用此函数之前。在 VFP 世界中,这经常是 Encoding.ASCII,但这取决于应用程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-29
      • 2017-01-06
      相关资源
      最近更新 更多