C# 从三个整数生成唯一的2字节整数

C# 从三个整数生成唯一的2字节整数,c#,unique,unique-key,C#,Unique,Unique Key,我有三个整数: 第一个数字范围为1-600 第二个数字的范围为0-4 第三个数字的范围为0-14 我需要从上述整数生成一个2字节的唯一整数,以便: 再次使用相同的号码将导致相同的号码 能够从唯一号码中取回所有三个号码 唯一编号应大于0&

我有三个整数:

  • 第一个数字范围为1-600
  • 第二个数字的范围为0-4
  • 第三个数字的范围为0-14
我需要从上述整数生成一个2字节的唯一整数,以便:

  • 再次使用相同的号码将导致相同的号码
  • 能够从唯一号码中取回所有三个号码
  • 唯一编号应大于0&<32768(2字节)

我已经搜索了解决方案,但大多数解决方案都会将字节数从2个字节增加到4个字节,这在我的情况下不是一个选项。

将它们转换为带零填充的字符串。用零填充后将它们连接起来。然后将它们转换回整数

所以20-1-8会变成“020108”,然后当你把它变成一个整数时会变成20108


要返回数字,请重新转换为字符串,并根据位数从右到左进行解析

将它们转换为零填充的字符串。用零填充后将它们连接起来。然后将它们转换回整数

所以20-1-8会变成“020108”,然后当你把它变成一个整数时会变成20108


要返回数字,请重新转换为字符串,并根据位数从右到左进行解析

首先,让我们将第一个范围转换为0-599,标记为下面的
First-1
。然后,您只需将这些数字相乘,使用范围最大值作为乘数:

range_of_first = 599 + 1 = 600
range_of_second = 4 + 1 = 5
range_of_third = 14 + 1 = 15

(first-1) + range_of_first * second + range_of_first * range_of_second * third
= (first-1) + 600*second + 600*5*third
= result
您可以获得的最大值为599+600*4+600*5*14=44999

这不适合有符号2字节整数(-32768..32767)。它适合于2字节无符号整数(0..65535)

如果必须将其拟合到有符号整数中,那么最简单的方法是在32位中进行计算,然后从结果中减去(44999-32768),这样它将适合2字节有符号整数的范围。然后在解码之前做相反的操作

相反,你需要划分和提醒:

first = result % range_of_first + 1 // +1 to get values 1..600
second = result / range_of_first % range_of_second
third = result / range_of_first / range_of_second // % range_of_third redundant

首先,假设所有的数字都是非负的,并且通常的整数除法舍入是假定的,这只是切掉任何小数。

首先,让我们将第一个范围转换为0-599,标记为下面的
First-1
。然后,您只需将这些数字相乘,使用范围最大值作为乘数:

range_of_first = 599 + 1 = 600
range_of_second = 4 + 1 = 5
range_of_third = 14 + 1 = 15

(first-1) + range_of_first * second + range_of_first * range_of_second * third
= (first-1) + 600*second + 600*5*third
= result
您可以获得的最大值为599+600*4+600*5*14=44999

这不适合有符号2字节整数(-32768..32767)。它适合于2字节无符号整数(0..65535)

如果必须将其拟合到有符号整数中,那么最简单的方法是在32位中进行计算,然后从结果中减去(44999-32768),这样它将适合2字节有符号整数的范围。然后在解码之前做相反的操作

相反,你需要划分和提醒:

first = result % range_of_first + 1 // +1 to get values 1..600
second = result / range_of_first % range_of_second
third = result / range_of_first / range_of_second // % range_of_third redundant
最重要的是,所有的数字都假定为非负的,通常的整数除法四舍五入是假定的,这只是切掉任何小数。

我认为海德的意思是(第一-1)+第一*第二的范围+第一*第二*第三的范围 =(第一-1)+600*第二+600*5*第三 =(第一-1)+600*第二+3000*第三

您需要存储45000个不同的值,所以您不能将它们放入2个有符号字节,但它们将放入2个无符号字节。

我认为hyde的意思是(第一-1)+第一*第二的范围+第一*第二*第三的范围 =(第一-1)+600*第二+600*5*第三 =(第一-1)+600*第二+3000*第三


您需要存储45000个不同的值,因此您无法将它们放入2个有符号字节,但它们将放入2个无符号字节。

假设数字为500-1-14。那将是050001014。将其转换为整数。它将是50001014,不再是2字节整数。假设数字为500-1-14。那将是050001014。将其转换为整数。。它将是50001014,不再是2字节整数。我实现的一切都与您描述的完全一样,但对于超过32768的数字,当我减去它们时,我得到了重复的数字。@ykh请注意,我在一小时前更新了答案,乘法中有一个错误。不管怎样,你能举一个例子,两组3个数字,其中你得到的是重复的吗?@ykh这个想法不是从太大的值中减去,而是从所有的值中减去,因此在某些情况下给你负值。如果你真的坚持你想要正15位值(0..32768),那么你的任务是不可能不放弃唯一性的。我认为这现在是有意义的。我试图解决这个问题,但如果没有负数,这是非常困难的。给我重复的数字是233,0,0,这只是一组。当我减法时,有很多重复项。无论如何,我会用负片numbers@ykh因此,对于这些数字,未调整的结果是
((233-1)+0*600+0*600*5)=232
。然后将其调整为2字节有符号整数,
232-(44999-32767)=-12000
,您可以将其存储起来。然后,要解码,您首先反转调整:
-12000-(44999-32767)=232
,解码时应给出
233,0,0
。我实现了与您描述的完全相同的所有操作,但对于超过32768的数字,当我减去它们时,我得到了重复的数字。@ykh注意,我在一小时前更新了答案,乘法中有个错误。不管怎样,你能举一个例子,两组3个数字,其中你得到的是重复的吗?@ykh这个想法不是从太大的值中减去,而是从所有的值中减去,因此在某些情况下给你负值。如果你真的坚持你想要正15位值(0..32768),那么你的任务是不可能不放弃唯一性的。我认为这现在是有意义的。我试图解决这个问题,但如果没有负数,这是非常困难的。给我重复的数字是233,0,0,这只是一组。当我减法时,有很多重复项。无论如何,我会用负片numbers@ykh所以,对于这些数字,未调整的结果是