【问题标题】:String to unique int algorithm字符串到唯一 int 算法
【发布时间】:2011-09-28 03:38:03
【问题描述】:

我们正在尝试实施以下案例。我们有一个发票表,并且有一列包含电子邮件地址。我们希望以某种方式从该电子邮件地址生成一个唯一的 int 值并将其存储在单独的列中。这将用作 FK 并被索引。所以我正在寻找的是一种从字符串生成整数的算法(请注意,电子邮件字符串应始终输出相同的整数,因此每个电子邮件地址都作为唯一的整数表示)。我们也可以使用 bigint

【问题讨论】:

  • 这已经被问过很多次了,简短的回答是不可能取一个无限(或相对无限)域(字符串/varchar)并将其与有限域(int , 大整数)。您需要在唯一性或输出数据类型上做出妥协。我的建议是您只需索引电子邮件地址本身。
  • 我不明白为什么会这样,@MarkPeters。他们得到的任何字符串都将被编码为有限的字节数。只需将相同的字节解释为 bigint,瞧,你就有了一个数字。
  • @Tom:我不确定 bigint 的确切语义。在 Java 中,BigInteger 具有可变位长,因此可以正常工作(我已经按照这些行删除了答案)。我的印象是 SQL 上下文中的 bigint 仍然是有界的(64 位),因此它代表一个有限域。
  • 我认为@MarkPeters 的意思是可能的电子邮件地址的数量总是> 给定长度的整数的数量。例如,如果使用 64 位整数,则有 2^64 个可能的值。有无限多个可能的电子邮件地址,> 2^64。
  • @TomZych 如果你有一个定义精度的整数类型(例如 32 位),生成 2**32 + 1 个不同的电子邮件地址是微不足道的,你的唯一性就在那里。跨度>

标签: algorithm


【解决方案1】:

最简单的解决方案是将电子邮件地址与身份/自动增量类型列一起放入自己的表中。然后,您可以简单地携带该标识字段(标准 int),并且不会遇到任何潜在哈希冲突的问题,并且没有哈希开销。

【讨论】:

  • +1 最佳答案,我想。当 OP 没有做出限制时,为什么要把事情复杂化?
【解决方案2】:

似乎一个简单的哈希码(MD5、SHA1、...)应该满足您的需求;根据您的 RDBMS,您可能能够使用内置包(例如 Oracle 的 dbms_crypto)或必须在外部计算它们。

注意事项:

  • 在计算哈希码之前将所有内容转换为小写/大写(因此 USER@DOMAIN.COM 获得与 user@domain.com 相同的哈希码)

  • 显然,您有一个非规范化模式。拥有一个包含电子邮件地址的单独客户表会更有意义;发票应该只包含外键 customer_fk

【讨论】:

  • @Raze2dust 是的,当然。但这种可能性非常非常小(尤其是如果使用 SHA1)。
  • @FrankSchmitt 有些人关心非常非常小的概率和不可能之间的区别……而有些人则不关心。
  • @Frank Schmitt:既然问题提到了发票,那么关心的人是客户、会计师、律师等。潜在的冲突应该足以取消任何哈希方案的资格。
  • @Blastfurnace:对于 HTTPS 证书,MD5 和 SHA1 冲突是公认的折衷方案,其中一个公司使用的大多数客户电子邮件地址都远不止这些。通常除非有人攻击系统并瞄准碰撞,否则这不会发生。另请注意,这种可能性受电子邮件地址语法的影响,因为大多数冲突将出现在语法之外或非常长的字符串(因此地址不可用)上。
【解决方案3】:

MD5 - 给你一个 128 位整数。 (诚​​然,这比大多数语言中的 int 数据类型大,但仅使用 32 位就无法保证唯一性。)

【讨论】:

  • OP 说他想要一个唯一的整数; MD5 不保证唯一性。
  • 您不能保证唯一的整数(除非使用任意长度的整数),因为可能的电子邮件地址数量是无限的。
  • @FrankSchmitt 实际使用的电子邮件地址数量有限,因此我们可以在看到它们时对它们进行索引。
  • @Michael:daiscog 没有声明 MD5 保证唯一性。它声明它让您接近保证独特性。
  • 取决于输入与输出,没有“保证”唯一性。
【解决方案4】:

我不知道您是否可以使用 64 位 int:电子邮件地址的最大长度为 254 个字符,在这种情况下您需要保留每个字符的唯一性,散列不会这样做.

因此,您似乎不得不克服这个 254 个字符的障碍。我的方法(对我来说总是蛮力方法)是采用电子邮件地址中允许字符的字母表,将它们映射到 6 位值,然后使用映射将它们打包成一系列单词。

看看rfc3696,它以一种实际上可以理解的方式处理电子邮件地址。

很抱歉帮不上忙。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多