如何断言大量字符串的唯一性?

时间:2017-05-29 13:47:38

标签: c# .net algorithm unique collision

假设我有一个以unsigned 64-bit integer为输入的算法,结果产生string。字符串的字母表限制为[a-z, A-Z, 0-9],其最大长度为16.因此,62^{16}或47,672,401,706,823,533,450,263,330,816可能的结果。

我想断言算法输出的唯一性。阅读:我想验证没有碰撞。

是否有一种简单/快速的方法可以做到这一点,而不必退回(例如)某种数据库?

[编辑] 一些澄清:评论中提出的问题是合法的,但不用担心,我并没有真正计划迭代所有可能的组合,我的生命周期可能不到1世纪;)我也没有编写自己的算法来生成独特的ID的。我刚刚看到this并开始想知道如何为具有无法在内存中处理的非常大的结果集的算法断言唯一性 [/编辑]

1 个答案:

答案 0 :(得分:0)

正如评论中所说,计算每个可能的条目需要很长时间,但只是为了好玩,这是一个尝试:

var workspace = new DirectoryInfo("MyWorkspace");

if (workspace.Exists)
{
    workspace.Delete();
}

workspace.Create();

var limit = 23997907;
var buffer = new HashSet<string>();

ulong i = 0;
int j = 0;

var stopWatch = Stopwatch.StartNew();

while (i <= ulong.MaxValue)
{
    var result = YourSuperAlgorythm(i);

    // Check the result with current results
    if (buffer.Contains(result))
    {
        throw new Exception("Failure !");
    }

    // Check the result with older results
    foreach (var file in workspace.GetFiles())
    {
        var content = new HashSet<string>(File.ReadAllText(file.FullName).Split(';'));

        if (content.Contains(result))
        {
            throw new Exception("Failure !");
        }
    }

    buffer[j] = result;

    i++;
    j++;

    if (j == arrayLimit)
    {
        stopWatch.Stop();

        Console.WriteLine("Resetting. This loop takes " + stopWatch.Elapsed.TotalMilliseconds + "ms");

        j = 0;

        var file = Path.GetRandomFileName();
        File.WriteAllText(Path.Combine(workspace.FullName, file), String.Join(";", buffer));

        buffer = new HashSet<string>();

        stopWatch.Restart();
    }
}

你可能可以对它进行优化,但你不需要一辈子来检查结果。目前,它甚至没有创建存储第一组条目的文件:D。我将在完成一个循环后编辑这篇文章!

您唯一的选择是以数学方式证明您的算法。祝你好运......

EDIT1:对于我的测试,我使用此功能:

private static string YourSuperAlgorythm(ulong i)
{
    return i.ToString("x");
}

EDIT2:一个循环需要1477221.4261ms(~25分钟)。然后String.Join(";", buffer)行失败(OutOfMemory)。所以23997907不是我尝试的最大值。必须减少!