C# 将int转换为BCD字节数组
我想使用BCD将int转换为字节[2]数组 所讨论的int来自表示年份的DateTime,必须转换为两个字节 是否有任何预先制作的函数可以做到这一点,或者你能给我一个简单的方法来做到这一点 示例:C# 将int转换为BCD字节数组,c#,.net,encryption,bcd,C#,.net,Encryption,Bcd,我想使用BCD将int转换为字节[2]数组 所讨论的int来自表示年份的DateTime,必须转换为两个字节 是否有任何预先制作的函数可以做到这一点,或者你能给我一个简单的方法来做到这一点 示例: int year = 2010 将输出: byte[2]{0x20, 0x10}; 这是一个可怕的暴力版本。我相信有比这更好的方法,但无论如何它都应该奏效 int digitOne = year / 1000; int digitTwo = (year - digitOne * 1000) / 1
int year = 2010
将输出:
byte[2]{0x20, 0x10};
这是一个可怕的暴力版本。我相信有比这更好的方法,但无论如何它都应该奏效
int digitOne = year / 1000;
int digitTwo = (year - digitOne * 1000) / 100;
int digitThree = (year - digitOne * 1000 - digitTwo * 100) / 10;
int digitFour = year - digitOne * 1000 - digitTwo * 100 - digitThree * 10;
byte[] bcdYear = new byte[] { digitOne << 4 | digitTwo, digitThree << 4 | digitFour };
int-digitOne=year/1000;
int digitTwo=(年份-洋地黄酮*1000)/100;
int digittree=(年份-digitOne*1000-digitTwo*100)/10;
int digitFour=年份-洋地黄酮*1000-洋地黄酮*100-洋地黄酮*10;
byte[]bcdYear=新的byte[]{digitOne这是一个稍微干净一点的版本
静态字节[]IntToBCD(int输入)
{
如果(输入>9999 | |输入<0)
抛出新ArgumentOutOfRangeException(“输入”);
整数千=输入/1000;
int数百=(输入-=千*1000)/100;
整数十位数=(输入-=百位数*100)/10;
整数位数=(输入-=十位数*10);
字节[]bcd=新字节[]{
(字节)(千<代码>静态字节[]年2BCD(整数年){
如果(年份<0 | |年份>9999)抛出新的ArgumentException();
int bcd=0;
用于(整数位数=0;位数<4;++位数){
int nibble=年份%10;
bcd |=半字节>8)和0xff,(字节)(bcd和0xff)};
}
请注意,您要求的是大端结果,这有点不寻常。可能是包含此循环的简单解析函数
static byte[] IntToBCD(int input) {
byte[] bcd = new byte[] {
(byte)(input>> 8),
(byte)(input& 0x00FF)
};
return bcd;
}
i=0;
while (id>0)
{
twodigits=id%100; //need 2 digits per byte
arr[i]=twodigits%10 + twodigits/10*16; //first digit on first 4 bits second digit shifted with 4 bits
id/=100;
i++;
}
使用这种方法
public static byte[] ToBcd(int value){
if(value<0 || value>99999999)
throw new ArgumentOutOfRangeException("value");
byte[] ret=new byte[4];
for(int i=0;i<4;i++){
ret[i]=(byte)(value%10);
value/=10;
ret[i]|=(byte)((value%10)<<4);
value/=10;
}
return ret;
}
公共静态字节[]ToBcd(int值){
如果(值9999999)
抛出新ArgumentOutOfRangeException(“值”);
字节[]ret=新字节[4];
对于(int i=0;i更常见的解决方案
private IEnumerable<Byte> GetBytes(Decimal value)
{
Byte currentByte = 0;
Boolean odd = true;
while (value > 0)
{
if (odd)
currentByte = 0;
Decimal rest = value % 10;
value = (value-rest)/10;
currentByte |= (Byte)(odd ? (Byte)rest : (Byte)((Byte)rest << 4));
if(!odd)
yield return currentByte;
odd = !odd;
}
if(!odd)
yield return currentByte;
}
private IEnumerable GetBytes(十进制值)
{
字节currentByte=0;
布尔奇数=真;
而(值>0)
{
if(奇数)
currentByte=0;
十进制剩余=值%10;
值=(剩余值)/10;
currentByte |=(Byte)(奇数)(Byte)rest:(Byte)(Byte)rest我在上发布了一个通用例程,您可以使用它,比如:
var yearInBytes=ConvertBigIntToBcd(2010,2);与Peter O.的版本相同,但在VB.NET中
Public Shared Function ToBcd(ByVal pValue As Integer) As Byte()
If pValue < 0 OrElse pValue > 99999999 Then Throw New ArgumentOutOfRangeException("value")
Dim ret As Byte() = New Byte(3) {} 'All bytes are init with 0's
For i As Integer = 0 To 3
ret(i) = CByte(pValue Mod 10)
pValue = Math.Floor(pValue / 10.0)
ret(i) = ret(i) Or CByte((pValue Mod 10) << 4)
pValue = Math.Floor(pValue / 10.0)
If pValue = 0 Then Exit For
Next
Return ret
End Function
公共共享函数ToBcd(ByVal pValue为整数)为Byte()
如果pValue<0或lse pValue>9999999,则抛出新的ArgumentOutOfRangeException(“值”)
Dim ret As Byte()=新字节(3){}所有字节都是带0的init
对于i,作为整数=0到3
ret(i)=CByte(pValue Mod 10)
pValue=数学楼层(pValue/10.0)
ret(i)=ret(i)或CByte((pValue Mod 10)你可能会想出一些使用布尔逻辑和移位的疯狂方法…但这会更好地维护。Big-endian如果使用嵌入式硬件,可能不会很不寻常。非常有用,谢谢!在这种情况下,我认为endian不重要,我很小心,但在这种情况下它可以。这不是。你只是在转换对于两字节数组,如果只能计算整数,则不应使用十进制作为输入参数。如果内部计算需要十进制,则应将其保留在内部,或者如何计算GetBytes(3.55549322);
?你能一步一步地告诉我这里发生了什么吗?谢谢。@Anonymous:我已经添加了一个解释。很棒的函数-我已经使用了很长时间-通过将数组增加到5字节,我将我的函数更改为覆盖所有int值。还为其他数据类型制作了一个,并将它们制作成扩展方法。谢谢你让我开始。
private IEnumerable<Byte> GetBytes(Decimal value)
{
Byte currentByte = 0;
Boolean odd = true;
while (value > 0)
{
if (odd)
currentByte = 0;
Decimal rest = value % 10;
value = (value-rest)/10;
currentByte |= (Byte)(odd ? (Byte)rest : (Byte)((Byte)rest << 4));
if(!odd)
yield return currentByte;
odd = !odd;
}
if(!odd)
yield return currentByte;
}
Public Shared Function ToBcd(ByVal pValue As Integer) As Byte()
If pValue < 0 OrElse pValue > 99999999 Then Throw New ArgumentOutOfRangeException("value")
Dim ret As Byte() = New Byte(3) {} 'All bytes are init with 0's
For i As Integer = 0 To 3
ret(i) = CByte(pValue Mod 10)
pValue = Math.Floor(pValue / 10.0)
ret(i) = ret(i) Or CByte((pValue Mod 10) << 4)
pValue = Math.Floor(pValue / 10.0)
If pValue = 0 Then Exit For
Next
Return ret
End Function