C# Visual FoxPro(VFP)CTOBIN和BINTOC函数-在.Net中等效

C# Visual FoxPro(VFP)CTOBIN和BINTOC函数-在.Net中等效,c#,encoding,ascii,smartcard,visual-foxpro,C#,Encoding,Ascii,Smartcard,Visual Foxpro,我们正在重写以前在VisualFoxPro中开发的一些应用程序,并使用.Net(使用C#)重新开发它们 下面是我们的场景: 我们的应用程序使用智能卡。我们从一个有名字和号码的智能卡中读取数据。名称在可读文本中返回正常,但数字(在本例中为“900”)返回为2字节字符表示(131和132),如下所示 这两个特殊字符可以在扩展Ascii表中看到。。现在你可以看到,2个字节是131和132,并且可能会有所不同,因为没有单一的标准扩展ascii表(据我所知,阅读这里的一些文章) 所以。。。智能卡之前是使用

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

下面是我们的场景: 我们的应用程序使用智能卡。我们从一个有名字和号码的智能卡中读取数据。名称在可读文本中返回正常,但数字(在本例中为“900”)返回为2字节字符表示(131和132),如下所示

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

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

(终于说到点子上了)-到目前为止,我们还无法将这两个特殊字符转换回int(900),我们想知道在.NET中是否可以将整数的字符表示形式读回实际整数

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

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

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

不太清楚这是为什么


任何帮助都将不胜感激。

看起来VFP正在将您的值存储为有符号16位(短)整数。对于负数,它似乎有一个奇怪的转换点,但它将128位数字与8位数字相加,将32768位数字与16位数字相加

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

示例:

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

您可以尝试根据使用C#转换,并至少为您做一些工作,但如果不这样做,手动编写上述代码应该不会太难。

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

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

示例:

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

您可以尝试按照使用C#转换,并至少为您做一些工作,但如果不是这样,手动编写上述代码应该不会太难。

已经晚了几年,但这里有一个工作示例

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;
}
public-ulong-CharToBin(字节[]s)
{
如果(s==null | | s.长度<1 | | s.长度>8)
返回0ul;
var v=s.Select(c=>(ulong)c.ToArray();
var结果=0ul;
var乘数=1ul;
对于(变量i=0;i0)
乘数*=256ul;
结果+=v[i]*乘数;
}
返回结果;
}
这是一个VFP8和更早版本的CTOBIN等价物,它涵盖了您的场景。您应该能够基于上述代码编写自己的BINTOC。VFP 9增加了对多个选项的支持,如非反转二进制数据、货币和双精度数据类型以及有符号值。此示例仅涵盖与支持的旧VFP类似的反向无符号二进制文件

一些注意事项:

  • 该代码支持1、2、4和8字节的值,这些值涵盖了所有 小于等于
    System.UInt64
    的无符号数值
  • 在铸造前 如果结果是预期的数字类型,则应验证 天花板例如,如果需要Int32,则检查结果 在执行强制转换之前,针对
    Int32.MaxValue
  • 该示例通过接受 字节数组。您需要了解使用的编码是什么 读取字符串,然后应用相同的编码来获取字节数组 在调用此函数之前。在VFP世界中,这是经常发生的
    Encoding.ASCII
    ,但它取决于应用程序

    • 虽然晚了几年,但这里有一个有效的例子

      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;
      }
      
      public-ulong-CharToBin(字节[]s)
      {
      如果(s==null | | s.长度<1 | | s.长度>8)
      返回0ul;
      var v=s.Select(c=>(ulong)c.ToArray();
      var结果=0ul;
      var乘数=1ul;
      对于(变量i=0;i0)
      乘数*=256ul;
      结果+=v[i]*乘数;
      }
      返回结果;
      }
      
      这是一个VFP8和更早版本的CTOBIN等价物,它涵盖了您的场景。您应该能够基于上述代码编写自己的BINTOC。VFP 9增加了对多个选项的支持,如非反转二进制数据、货币和双精度数据类型以及有符号值。此示例仅涵盖与支持的旧VFP类似的反向无符号二进制文件

      一些注意事项:

      • 该代码支持1、2、4和8字节的值,这些值涵盖了所有 小于等于
        System.UInt64
        的无符号数值
      • 在铸造前 如果结果是预期的数字类型,则应验证 塞林