在代码中从长数中提取三个数字

时间:2012-11-09 09:39:10

标签: c# asp.net algorithm math

我正在使用ASP.NET C#和MySQL构建自己的分片解决方案。对于每行的Id,我使用以下内容:

  • Shard Id - Int(1-65535)
  • 表类型Id - 小Int(1-65535)
  • 增量编号(1 - 4294967295)

例如,ID应该在URL中,如下所示:

http://mywebsite.com/folders/65535655354294967297

我想知道的是如何将数字组合成一个大数字,以便我可以在以后提取数据。因此,例如,我不会使用1作为分片ID,我可能需要你00001,因为稍后通过对整数进行除法将更容易提取该数字。

那么我该怎么做呢,用三个单独的数值构建一个长数字然后能够用代码提取它们的最佳方法是什么?

我在C#

中寻找最强大的高效方式

感谢。

4 个答案:

答案 0 :(得分:2)

你几乎已经在你的问题中描述了答案。为每个数字定义固定宽度。

int iShardId = 12; // Fixed width of 5
int iTableTypeId = 840; // Fixed width of 5
long lIncremental = 967295; // Fixed width of 10

string sMyId = String.Concat(iShardId.ToString("00000"), iTableTypeId.ToString("00000"), lIncremental.ToString("0000000000"));

然后您可以使用RegEx解析字符串(通过iHttpModule或其他):

RegEx rMyText = new RegEx(@"/(?<shard>[0-9]{5})(?<table>[0-9]{5})(?<inc>[0-9]{10})/?$");
Match mMyValues = rMyText.Match(Request.Url.AbsolutePath);

if (mMyValues.Success) {
    int iShardId = Convert.ToInt32(mMyValues["shard"].Value);
    int iTableTypeId = Convert.ToInt32(mMyValues["table"].Value);
    long lIncremental = Convert.ToInt64(mMyValues["inc"].Value);
}
else {
    //The input didn't match
}

RegEx旨在作为解析数字的示例,但显然取决于您计划实施的方式,您应该调整它以确保输入限制为您期望的值,使用开始/终止斜线或字符串结尾($)。

答案 1 :(得分:1)

解决方案可以是使用二进制数并将它们附加在一起形成一个数字。

  
      
  • Shard Id - Int(1-65535)
  •   
  • 表类型Id - 小Int(1-65535)
  •   
  • 增量编号(1 - 4294967295)
  •   

Shard Id和Table Id都需要16位,增量数需要16位。这意味着您可以用64位表示数据。

示例:

Shard Id

Dec:7

Bin:0000 0000 0000 0111

表格类型ID

12月:2435

宾:0000 1001 1000 0011

增量号

Dec:23456457

Bin:0001 0110 0101 1110 1010 1100 1001

最终号码

Concat二进制值,如

分片ID +表格类型ID +增量号码

Bin:0000 0000 0000 0111 0000 1001 1000 0011 0000 0001 0110 0101 1110 1010 1100 1001

Dec:1980783105796809

答案 2 :(得分:1)

您可以使用数字的十六进制表示

ushort ShardId=1;
ushort TableTypeId = 100;
uint IncrementalNumber = 1000;

string url = ShardId.ToString("X4") + TableTypeId.ToString("X4")
                                    + IncrementalNumber.ToString("X8");

var i1 = Convert.ToUInt16(url.Substring(0, 4), 16);
var i2 = Convert.ToUInt16(url.Substring(4, 4), 16);
var i3 = Convert.ToUInt32(url.Substring(8, 8), 16);

string url = (((ulong)ShardId << 48) | ((ulong)TableTypeId << 32) | IncrementalNumber)
             .ToString("X16");

var u  = Convert.ToUInt64(url,16);
var i1 = (ushort)(u >> 48);
var i2 = (ushort)((u >> 32) & 0xffff);
var i3 = (uint)(u & 0xffffffff);

答案 3 :(得分:0)

几个选项,大致从最长(最可读?)到最短(最不可读)

  • 用零填充每个数字(00001000010000000001
  • 用连字符,甚至是斜杠(1-1-11/1/1
  • 分隔数字
  • 将您的两个ushortuint合并到ulong并将 放入网址
  • 将八个字节合并到一个数组中,Base64对其进行编码并将 放入URL中

我会选择第二个 - 它可能在大多数情况下都是最短的,而且最具人性化。