英文:
What is Go's equivalent to Python's crypt.crypt?
问题
我目前正在尝试使用《Violent Python》一书中的示例。您可以在这里看到我的实现。
我现在正在尝试使用Go实现相同的脚本以进行性能比较,注意我对Go完全不熟悉。打开文件并迭代行是可以的,但是我无法弄清楚如何使用“crypto”库以与Python的crypt.crypt(str_to_hash, salt)相同的方式对字符串进行哈希。我以为可能是这样的:
import "crypto/des"
des.NewCipher([]byte("abcdefgh"))
然而,没有成功。如果能得到任何帮助,将不胜感激,因为将Go的并行性能与Python的多线程性能进行比较将非常有趣。
英文:
I am currently playing around with an example from the book Violent Python. You can see my implementation here
I am now trying to implement the same script in Go to compare performance, note I am completely new to Go. Opening the file and iterating over the lines is fine, however I cannot figure out how to use the "crypto" library to hash the string in the same way as Python's crypt.crypt(str_to_hash, salt). I thought it maybe something like
import "crypto/des"
des.NewCipher([]byte("abcdefgh"))
However, no cigar. Any help would be much appreciated as it'd be really interesting to compare Go's parallel performance to Python's multithreaded.
答案1
得分: 3
我相信目前没有任何公开可用的Go软件包来实现旧式的Unix“盐”DES基于crypt()
功能。这与在“crypto/des”
软件包中实现的正常对称DES加密/解密不同(正如您所发现的那样)。
您将不得不自己实现它。有很多现有的实现,使用不同的语言(主要是C),例如在FreeBSD源代码或glibc中。如果您在Go中实现它,请发布出来。
对于新项目,最好使用一些更强大的密码哈希算法,例如bcrypt。在go.crypto存储库中有一个很好的实现。文档在这里可用。不幸的是,如果您需要处理现有的传统密码哈希,这并没有帮助。
编辑以添加:我查看了Python的crypt.crypt()
实现,并发现它只是一个对libc实现的包装。为Go实现相同的包装将很简单。然而,您比较Python实现和Go实现的想法已经被破坏:您将不得不自己实现两者才能进行有意义的比较。
英文:
I believe there isn't currently any publicly available package for Go which implements the old-fashioned Unix "salted" DES based crypt()
functionality. This is different from the normal symmetrical DES encryption/decryption which is implemented in the "crypto/des"
package (as you have discovered).
You would have to implement it on your own. There are plenty of existing implementations in different languages (mostly C), for example in FreeBSD sources or in glibc. If you implement it in Go, please publish it.
For new projects it is much better to use some stronger password hashing algorithm, such as bcrypt. A good implementation is available in the go.crypto repository. The documentation is available here. Unfortunately this does not help if you need to work with pre-existing legacy password hashes.
Edited to add: I had a look at Python's crypt.crypt()
implementation and found out that it is just a wrapper around the libc implementation. It would be simple to implement the same wrapper for Go. However your idea of comparing a Python implementation to a Go implementation is already ruined: you would have to implement both of them yourself to make any meaningful comparisons.
答案2
得分: 3
crypt
非常容易使用cgo进行封装,例如
package main
import (
"fmt"
"unsafe"
)
// #cgo LDFLAGS: -lcrypt
// #define _GNU_SOURCE
// #include <crypt.h>
// #include <stdlib.h>
import "C"
// crypt封装了C库crypt_r
func crypt(key, salt string) string {
data := C.struct_crypt_data{}
ckey := C.CString(key)
csalt := C.CString(salt)
out := C.GoString(C.crypt_r(ckey, csalt, &data))
C.free(unsafe.Pointer(ckey))
C.free(unsafe.Pointer(csalt))
return out
}
func main() {
fmt.Println(crypt("abcdefg", "aa"))
}
运行时产生以下结果
aaTcvO819w3js
与Python的crypt.crypt
完全相同
>>> from crypt import crypt
>>> crypt("abcdefg","aa")
'aaTcvO819w3js'
>>>
(更新以释放CStrings - 感谢@james-henstridge)
英文:
crypt
is very easy to wrap with cgo, eg
package main
import (
"fmt"
"unsafe"
)
// #cgo LDFLAGS: -lcrypt
// #define _GNU_SOURCE
// #include <crypt.h>
// #include <stdlib.h>
import "C"
// crypt wraps C library crypt_r
func crypt(key, salt string) string {
data := C.struct_crypt_data{}
ckey := C.CString(key)
csalt := C.CString(salt)
out := C.GoString(C.crypt_r(ckey, csalt, &data))
C.free(unsafe.Pointer(ckey))
C.free(unsafe.Pointer(csalt))
return out
}
func main() {
fmt.Println(crypt("abcdefg", "aa"))
}
Which produces this when run
aaTcvO819w3js
Which is identical to python crypt.crypt
>>> from crypt import crypt
>>> crypt("abcdefg","aa")
'aaTcvO819w3js'
>>>
(Updated to free the CStrings - thanks @james-henstridge)
答案3
得分: 2
package main
import (
"crypto/des"
"fmt"
"log"
)
func main() {
b, err := des.NewCipher([]byte("abcdefgh"))
if err != nil {
log.Fatal(err)
}
msg := []byte("Hello!?!")
fmt.Printf("% 02x: %q\n", msg, msg)
b.Encrypt(msg, msg)
fmt.Printf("% 02x: %q\n", msg, msg)
b.Decrypt(msg, msg)
fmt.Printf("% 02x: %q\n", msg, msg)
}
英文:
E.g.
package main
import (
"crypto/des"
"fmt"
"log"
)
func main() {
b, err := des.NewCipher([]byte("abcdefgh"))
if err != nil {
log.Fatal(err)
}
msg := []byte("Hello!?!")
fmt.Printf("% 02x: %q\n", msg, msg)
b.Encrypt(msg, msg)
fmt.Printf("% 02x: %q\n", msg, msg)
b.Decrypt(msg, msg)
fmt.Printf("% 02x: %q\n", msg, msg)
}
(Also: http://play.golang.org/p/czYDRjtWNR)
Output:
48 65 6c 6c 6f 21 3f 21: "Hello!?!"
3e 41 67 99 2d 9a 72 b9: ">Ag\x99-\x9ar\xb9"
48 65 6c 6c 6f 21 3f 21: "Hello!?!"
答案4
得分: 2
好消息!实际上有一个开源的实现是你正在寻找的。Osutil有一个加密包,它在纯Go中重新实现了crypt
。
https://github.com/kless/osutil/tree/master/user/crypt
1: https://github.com/kless/osutil "Osutil"
英文:
Good news! There's actually an open source implementation of what you're looking for. Osutil has a crypt package that reimplements crypt
in pure Go.
https://github.com/kless/osutil/tree/master/user/crypt
1: https://github.com/kless/osutil "Osutil"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论