Powershell:将唯一字符串转换为唯一整数

3
有没有一种方法可以在PowerShell中将唯一字符串转换为唯一整数?
我正在使用一个PowerShell函数作为两个API之间的服务总线,第一个API生成唯一代码,例如HG44X10999(varchars) - 但是将作为输入消耗第一个API的第二个API仅接受整数。 我只关心保持它们的唯一性。
我已经查看了$string.gethashcode()但是这会产生负整数,并且在构建之间也会更改。 Get-hash | $string -encoding ASCII显然也输出varchars。
SO上的其他示例是指将数字字符的字符串转换为整数,即$string = 123-但我找不到一种从字母数字字符串快速计算int的方法。

2
第二个进程接受的INT有什么限制?只能是正数吗?16位、32位还是64位?第一个进程生成的字符串有什么约束条件?长度?特定位置允许使用哪些字符?所有字符都保证可打印吗?所有字符都保证是大写字母或数字吗?有实现您所需功能的方法,但您需要了解数据的特性,我们也需要了解才能帮助您。 - Jeff Zeitlin
2
你有两个选择 - 1)设计一个确定性过程,将任意字符串转换为整数,但这会与您对小整数的要求产生冲突;2)跟踪所有标识符分配记录,以确保始终将相同的整数重新分配给相同的输入字符串,这将需要一个数据库或类似的方式来跟踪它们。您是否有存储字符串<->整数分配的设施? - Mathias R. Jessen
1
一个例子是不够的。如果涉及到COBOL,我想要数据的PIC子句;它是AA99A99999,还是XXXXX99999,或者XXXXXXXXXX,或者其他什么?(在COBOL PIC中,A是字母,9是数字,X是任何字符 - 当讨论这类问题时,使用正则表达式或COBOL PIC子句来描述您的数据是一个很好的方法。) - Jeff Zeitlin
@Matt - 我更或多或少地假设字符串和整数之间的对应关系可以由查询者定义,而不是外部强制实施。 - Jeff Zeitlin
3
我不知道有任何一种语言拥有"内置方法",你需要为转换定义自己的函数,这并不难,但是_你需要了解你的数据的特性_。如果您无法想出一种描述您生成的字母数字代码的方式,则在不超过32位限制的情况下处理此问题的唯一方法是使用@MathiasR.Jessen提到的数据库方法。 - Jeff Zeitlin
显示剩余8条评论
1个回答

9
Fowler-Noll-Vo哈希函数 似乎非常适合您的目的,因为它可以生成32位哈希输出。以下是PowerShell中的简单实现(偏移基数和初始质数取自维基百科参考表格,用于32位输出):
function Get-FNVHash {

    param(
        [string]$InputString
    )

    # Initial prime and offset chosen for 32-bit output
    # See https://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function
    [uint32]$FNVPrime = 16777619
    [uint32]$offset = 2166136261

    # Convert string to byte array, may want to change based on input collation
    $bytes = [System.Text.Encoding]::UTF8.GetBytes($InputString)

    # Copy offset as initial hash value
    [uint32]$hash = $offset

    foreach($octet in $bytes)
    {
        # Apply XOR, multiply by prime and mod with max output size
        $hash = $hash -bxor $octet
        $hash = $hash * $FNVPrime % [System.Math]::Pow(2,32)
    }
    return $hash
}

现在,您可以从输入字符串中重复产生不同的整数:
PS C:\> Get-FNVHash HG44X10999
1174154724

如果目标API只接受正的32位有符号整数,您可以将模数更改为[System.Math]::Pow(2,31)(将冲突几率加倍,对于1000个不同的输入,约为1/4300)

要深入了解这种简单方法,请参见FNV页面并查看短字符串哈希探索文章


太好了!Mathias,请更加努力地使用POSIX :-) - Sum1sAdmin
它抛出了这个错误:“无法将值“2166136261”转换为类型“System.Int32”。错误:“值对于 Int32 来说太大或太小。”,用于 Prime 和 offset。 - Sum1sAdmin
1
将它们声明为无符号整数。 - Mathias R. Jessen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接