小编典典

与私有接口比较

go

我有两个对象。key1是类型*rsa.PublicKeykey2类型*ssh.PublicKey是隐藏*ssh.rsaPublicKey对象的接口。ssh.rsaPublicKey定义为:

type ssh.rsaPublicKey rsa.PublicKey

它还有一些额外的方法。但是,ssh.rsaPublicKey由于该类“未导出”,所以我无法将任何一个键都转换key2为一个,rsa.PublicKey因为那没有实现ssh.PublicKey,所以我也无法转换为一个,并且我无法访问the
Nefrom,key2因为我不应该知道我有一个rsaPublicKey对象。

我应该怎么比较,key1并且key2是相同的密钥?


阅读 272

收藏
2020-07-02

共1个答案

小编典典

如前所述,您不能使用类型断言,因为您不能引用未导出的type
ssh.rsaPublicKey

使用reflect软件包可以实现您想要的一切。

由于rsa.PublicKey是的基础类型ssh.rsaPublicKey,因此可以将封装的 指针
key2转换为rsa.PublicKey。一旦你获得reflect.Value你的key2,“导航”到

利用价值Value.Elem()。该值可转换为type的值rsa.PublicKey。您可以使用Value.Convert()“动态”将,在运行时将其转换为rsa.PublicKey。拥有后,您可以reflect.DeepEquals()用来进行比较,也可以手动进行比较。

它看起来像这样:

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需要使用该Int.Cmp()方法,因为比较指针是比较内存地址,而不是指针值。如果两个值相等,则Int.Cmp()返回0

2020-07-02