How do you get the name of a constant given its value ?
More specifically (and to get a more readable understanding), I\'m working with the crypto/tls
packa
I am afraid that is not possible.
The constants are resolved at compile time and there is nothing in the reflect
package that allows you to retrieve the name.
What I suggest is creating a map with the names:
var constLookup = map[uint16]string{
tls.TLS_RSA_WITH_RC4_128_SHA: `TLS_RSA_WITH_RC4_128_SHA`,
tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA: `TLS_RSA_WITH_3DES_EDE_CBC_SHA`,
...
}
Note: As of Go 1.4, the String()
code below can be auto-generated using Go's new generate
feature, combined with the stringer
command. See here for more info.
Apart from ANisus' answer, you can do the following.
package main
import "fmt"
import "crypto/tls"
type Ciphersuite uint16
const (
TLS_RSA_WITH_RC4_128_SHA = Ciphersuite(tls.TLS_RSA_WITH_RC4_128_SHA)
TLS_RSA_WITH_3DES_EDE_CBC_SHA = Ciphersuite(tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA)
TLS_RSA_WITH_AES_128_CBC_SHA = Ciphersuite(tls.TLS_RSA_WITH_AES_128_CBC_SHA)
TLS_RSA_WITH_AES_256_CBC_SHA = Ciphersuite(tls.TLS_RSA_WITH_AES_256_CBC_SHA)
TLS_ECDHE_RSA_WITH_RC4_128_SHA = Ciphersuite(tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA)
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = Ciphersuite(tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = Ciphersuite(tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = Ciphersuite(tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
)
func (cs Ciphersuite) String() string {
switch cs {
case TLS_RSA_WITH_RC4_128_SHA:
return "TLS_RSA_WITH_RC4_128_SHA"
case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
case TLS_RSA_WITH_AES_128_CBC_SHA:
return "TLS_RSA_WITH_AES_128_CBC_SHA"
case TLS_RSA_WITH_AES_256_CBC_SHA:
return "TLS_RSA_WITH_AES_256_CBC_SHA"
case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
return "TLS_ECDHE_RSA_WITH_RC4_128_SHA"
case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"
case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
}
return "Unknown"
}
func main() {
cs := TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
fmt.Printf("0x%04x = %s\n", uint16(cs), cs)
cs = TLS_RSA_WITH_RC4_128_SHA
fmt.Printf("0x%04x = %s\n", uint16(cs), cs)
cs = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
fmt.Printf("0x%04x = %s\n", uint16(cs), cs)
}
You can test it on the go playground.
You can use go generate to have this generated for you.
Install stringer
using
go get golang.org/x/tools/cmd/stringer
Now define a type
for your const
. You can do it like this
type TLSType uint16
const (
TLS_RSA_WITH_RC4_128_SHA TLSType = 0x0005
TLS_RSA_WITH_3DES_EDE_CBC_SHA TLSType = 0x000a
TLS_RSA_WITH_AES_128_CBC_SHA TLSType = 0x002f
TLS_RSA_WITH_AES_256_CBC_SHA TLSType = 0x0035
TLS_ECDHE_RSA_WITH_RC4_128_SHA TLSType = 0xc011
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA TLSType = 0xc012
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA TLSType = 0xc013
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA TLSType = 0xc014
)
Then add this line to your file (spacing is important)
//go:generate stringer -type=TLSType
Now go to the terminal in the folder where your program is and run
go generate
This will create a file called tlstype_string.go
in your code directory, which is the generated code that implements the fmt.Stringer
interface for your TLSType
. Open it if you want to see the implementation but you don't need to. It will just work.
Now when you run go build
or go run *.go
on this directory, your source files will use the generated code.
The full program would look something like this
package main
import (
"fmt"
)
//go:generate stringer -type=TLSType
type TLSType uint16
const (
TLS_RSA_WITH_RC4_128_SHA TLSType = 0x0005
TLS_RSA_WITH_3DES_EDE_CBC_SHA TLSType = 0x000a
TLS_RSA_WITH_AES_128_CBC_SHA TLSType = 0x002f
TLS_RSA_WITH_AES_256_CBC_SHA TLSType = 0x0035
TLS_ECDHE_RSA_WITH_RC4_128_SHA TLSType = 0xc011
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA TLSType = 0xc012
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA TLSType = 0xc013
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA TLSType = 0xc014
)
func main() {
fmt.Println("This const will be printed with its name instead of its number:")
fmt.Println(TLS_RSA_WITH_RC4_128_SHA)
fmt.Println()
fmt.Println("So will this one:")
fmt.Println(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
fmt.Println()
fmt.Println("Or maybe we want to give it a value and convert:")
fmt.Println(TLSType(0xc011))
fmt.Println()
fmt.Println("No problem:")
fmt.Println(TLSType(0xc013))
}
Which outputs
This const will be printed with its name instead of its number:
TLS_RSA_WITH_RC4_128_SHA
So will this one:
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Or maybe we want to give it a value and convert:
TLS_ECDHE_RSA_WITH_RC4_128_SHA
No problem:
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
If you add new const
values, just run go generate
again to update the generated code.