gpt4 book ai didi

javascript - 试图将 JS 脚本移植到 Swift,但计算不正确

转载 作者:行者123 更新时间:2023-11-28 10:11:11 25 4
gpt4 key购买 nike

该脚本用于在 IRC 上为缺口着色。

这是 JavaScript:

<script type="text/javascript">
function clean_nick(nick) {
nick = nick.toLowerCase();
nick = nick.replace(/[^a-z]/g, "")

return nick;
}

function hash(nick) {
var cleaned = clean_nick(nick);
var h = 0;

for(var i = 0; i < cleaned.length; i++) {
var a = cleaned.charCodeAt(i)
var b = (h << 6)
var c = (h << 16)
var d = h

h = a + b + c - d;
}

console.log(h);

return h;
}

function get_color(nick) {
var nickhash = hash(nick);
var deg = nickhash % 360;
var h = deg < 0 ? 360 + deg : deg;
var l = 50;

if(h >= 30 && h <= 210) {
l = 30;
}

var s = 20 + Math.abs(nickhash) % 80;

return "hsl(" + h + "," + s + "%," + l + "%)";
}

console.log(get_color("kIrb-839432-`~#$%^&*()_+{}|:<>?/,'.;[]=-_-"));
</script>

这是一个 Swift Playground :

//: Playground - noun: a place where people can play

import UIKit

extension Character {
func unicodeScalarCodePoint() -> UInt32 {
let characterString = String(self)
let scalars = characterString.unicodeScalars

return scalars[scalars.startIndex].value
}
}

func cleanNick(nick: String) -> String {
let lowerCaseNick = nick.lowercased()
let noNumberNick = lowerCaseNick.components(separatedBy: CharacterSet.decimalDigits).joined()
let noPunctuationNick = noNumberNick.components(separatedBy: CharacterSet.punctuationCharacters).joined()
let noSymbolNick = noPunctuationNick.components(separatedBy: CharacterSet.symbols).joined()
let finishedNick = noSymbolNick.replacingOccurrences(of: " ", with: "")

return finishedNick
}

func hash(nick: String) -> Int {
let cleaned = cleanNick(nick: nick)
var h = 0

for char in cleaned {
let a = char.unicodeScalarCodePoint()
let b = (h << 6)
let c = (h << 16)
let d = h

h = Int(Int(a) + Int(b) + Int(c) - Int(d))
}

print(h)

return h
}

func coloredNick(nick: String) -> String {
let nickHash = hash(nick: nick)
let deg = nickHash % 360
let h = deg < 0 ? 360 + deg : deg
var l = 50

if (h >= 30 && h <= 210) {
l = 30
}

let s = 20 + abs(nickHash) % 80

return "hsl(\(h),\(s),\(l))"
}

print(coloredNick(nick: "kIrb-839432-`~#$%^&*()_+{}|:<>?/,'.;[]=-_-"))

两者都应该输出相同的散列,因此应该输出相同的 hsl(),但是在计算中出了点问题。无法弄清楚哪里出了问题,但哈希计算不正确。

非常感谢任何帮助。

最佳答案

您需要考虑的所有事情都写在 Dávid Pásztor 的评论中。

这是我的hash 函数版本。它产生的结果与我使用 Safari 为您的 JavaScript 代码测试的结果相同:

func hash(_ nick: String) -> Int64 {
let cleaned = cleanNick(nick)
var h: Int64 = 0

for a in cleaned.utf16 {
let b = Int32(truncatingIfNeeded: h) &<< 6
let c = Int32(truncatingIfNeeded: h) &<< 16
let d = h

h = Int64(a) + Int64(b) + Int64(c) - d
}
print(h) //-> -1501579218 (JS:-1501579218)

return h
}

一些注意事项:

  • 在 JavaScript 中,所有数字都是 64 位 float ,在 Swift 中是 Double
  • 在 JavaScript 中,移位操作将所有输入值转换为 32 位有符号整数 (Int32),然后将结果转换为 64 位 float 。

所以,我首先用Double 编写了我的hash,并在确认所有中间值都是整数后,将其变成了Int64。(Int 在 32 位系统中是 32 位长,您的 hash 可能生成 32 位整数不能包含的值。)

您拆分字符的方式可能会从您的 JavaScript 代码中生成不同的结果,如评论中所示,但是您通过将字符限制在“a”...“z”中来过滤输入 .

但是您的过滤代码很难理解,可能会产生与预期不同的结果。

func cleanNick(_ nick: String) -> String {
var result = nick.lowercased()
result = String(result.unicodeScalars.filter{"a" <= $0 && $0 <= "z"})

return result
}

关于javascript - 试图将 JS 脚本移植到 Swift,但计算不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48139752/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com