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.
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)
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.
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!?!"
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://stackoverflow.com/questions/14109915/what-is-gos-equivalent-to-pythons-crypt-crypt