我有两个对象。 key1
的类型为*rsa.PublicKey
。 key2
的类型为*ssh.PublicKey
,它是隐藏*ssh.rsaPublicKey
对象的接口。 ssh.rsaPublicKey
定义为:
type ssh.rsaPublicKey rsa.PublicKey
它有一些额外的方法。但是,我无法将关键字投放到ssh.rsaPublicKey
,因为该类是"未导出",我无法将key2
投射到rsa.PublicKey
因为那并没有实现ssh.PublicKey
,我无法从N
访问e
或key2
,因为我不应该知道我有rsaPublicKey
一个key1
对象。
我应该如何比较key2
和eigen
是否相同?
答案 0 :(得分:2)
正如您所提到的,您无法使用type assertion,因为您无法引用未导出的类型ssh.rsaPublicKey
。
使用reflect
包可以实现您的目标。
由于rsa.PublicKey
是ssh.rsaPublicKey
的基础类型,key2
中包含的指向值可以转换为rsa.PublicKey
。获得key2
的{{3}}后,使用reflect.Value
“导航”到指向的值。此值可转换为类型rsa.PublicKey
的值。您可以使用Value.Elem()
“动态”,在运行时将其转换为rsa.PublicKey
。获得后,您可以使用Value.Convert()
进行比较,或手动比较。
这就是它的样子:
key1 := &rsa.PublicKey{N: big.NewInt(123), E: 10}
key2, _ := ssh.NewPublicKey(&rsa.PublicKey{N: big.NewInt(123), E: 10})
key2conv := reflect.ValueOf(key2).Elem().
Convert(reflect.TypeOf(rsa.PublicKey{})).Interface()
// key2conf is an interface{}, wrapping an rsa.PublicKey
// Comparision with DeepEqual
fmt.Println(reflect.DeepEqual(*key1, key2conv))
// Comparing manually:
key22 := key2conv.(rsa.PublicKey)
fmt.Println(key1.N.Cmp(key22.N)) // Int.Cmp() returns 0 if equal
fmt.Println(key1.E == key22.E)
请注意,在手动比较时,比较PublicKey.N
字段 - 类型为*big.Int
- 您需要使用reflect.DeepEquals()
方法,因为比较指针会比较内存地址,而不是指向内存地址值。如果2个值相等,则Int.Cmp()
会返回0
。