go equivalents of c types

huangapple go评论96阅读模式
英文:

go equivalents of c types

问题

在Go语言中,unsigned char可以用byte类型表示,unsigned char*可以用[]byte表示。你的重写代码中已经使用了[256]byte来表示m_aucState0m_aucState,这是正确的。但是,你需要对其他变量进行一些修改。

首先,m_ucIm_ucJ应该是byte类型而不是切片类型。所以你可以将它们声明为byte类型:

m_ucI, m_ucJ byte

接下来,m_pucState1m_pucState2应该是指向byte类型的指针,而不是切片类型。所以你可以将它们声明为*byte类型:

m_pucState1, m_pucState2 *byte

最后,m_ucTemp应该是byte类型而不是切片类型。所以你可以将它声明为byte类型:

m_ucTemp byte

关于你提到的循环和memcpy函数,你可以使用copy函数来实现相同的功能。你可以将循环代码修改为以下形式:

for i := 0; i < 256; i++ {
    m_pucState1 = &m_aucState0[i]
    m_ucJ += *m_pucState1 + pucKeyData[m_ucI]
    m_pucState2 = &m_aucState0[m_ucJ]
    // 交换值
    m_ucTemp = *m_pucState1
    *m_pucState1 = *m_pucState2
    *m_pucState2 = m_ucTemp
    m_ucI = (m_ucI + 1) % byte(iKeyLen)
}
copy(m_aucState[:], m_aucState0[:])

希望这可以帮助你将C++代码重写为Go代码。如果你还有其他问题,请随时问我。

英文:

What are the right equivalent of unsigned char or unsigned char* in go? Or am I even doing this right?


I have this C++ class:

class ArcfourPRNG
{
public:
	ArcfourPRNG();
	void SetKey(unsigned char *pucKeyData, int iKeyLen);
	void Reset();
	unsigned char Rand();
    
private:
	bool m_bInit;
	unsigned char m_aucState0[256];
	unsigned char m_aucState[256];
	unsigned char m_ucI;
	unsigned char m_ucJ;
	unsigned char* m_pucState1;
	unsigned char* m_pucState2;
	unsigned char m_ucTemp;
};

I am trying to rewrite it to go:

type ArcfourPRNG struct {
    m_bInit bool
    m_aucState0 [256]byte
    m_aucState [256]byte
    m_ucI, m_ucJ []byte
    *m_pucState1 []byte
    *m_pucState2 []byte
    m_ucTemp []byte
}

func (arc4 *ArcfourPRNG) SetKey(pucKeyData []byte, iKeyLen int) {
func (arc4 *ArcfourPRNG) Reset() {
func (arc4 *ArcfourPRNG) Rand() uint {

Well, I just started with go a few hours ago. So this is still confusing me.


A function

for(i=0; i&lt;256; i++)
{
    m_pucState1 = m_aucState0 + i;
    m_ucJ += *m_pucState1 + *(pucKeyData+m_ucI);
    m_pucState2 = m_aucState0 + m_ucJ;
    //Swaping
    m_ucTemp = *m_pucState1;
    *m_pucState1 = *m_pucState2;
    *m_pucState2 = m_ucTemp;
    m_ucI = (m_ucI + 1) % iKeyLen;
}
memcpy(m_aucState, m_aucState0, 256); // copy(aucState[:], aucState0) ?

答案1

得分: 2

希望这能为你解决一些问题。

  • 用于存储原始字节序列的是切片[]byte。如果你确切地知道序列的长度,你可以指定它,例如[256]byte,但是后续不能改变大小。
  • 虽然Go有指针,但它没有指针算术。因此,你需要使用整数来索引字节切片。
  • 对于存储单个字节,byte就足够了;你不需要一个字节切片。在C++代码中,指针用于指向数组中的特定位置,而在Go中,你只需要一个整数索引值来选择切片的一个元素。
  • Go字符串不仅仅是字节序列,它们是以UTF-8字符的形式存储的字符序列,这些字符可能具有不同的长度。因此,不要尝试在此算法中使用字符串。

要重新实现所示的算法,你根本不需要指针或指针算术。与在C++中保留指向字节数组的指针不同,你将使用切片的int索引。

由于这几乎全部都是指针算术,所以有点难以理解。在转换时,我建议你手头有算法的描述(由于这可能是一个众所周知的算法,应该不难找到)。我不会为你完成整个转换,但我会用一个更简单的示例来演示。这个示例将字符串的每个字符打印在单独的一行。

C++:

unsigned char *data = "Hello World";
unsigned char *ptr = 0;

for (int i = 0; i < std::strlen(data); i++) {
    ptr = i + data;
    std::cout << *ptr << std::endl;
}

Go:

data := []byte("Hello World")

for i := 0; i < len(data); i++ {
    // 指针已经是多余的了
    fmt.Println(data[i:i+1])
}

因此,了解Go切片,当你重新实现这个算法时,你可能会发现代码相对简单一些,或者至少更容易理解,比起C++的对应代码。

英文:

Hopefully this can clear a few things up for you.

  • For storing raw sequences of bytes, use a slice []byte. If you know exactly how long the sequence will be, you can specify that, e.g. [256]byte but you cannot resize it later.
  • While Go has pointers, it does not have pointer arithmetic. So you will need to use integers to index into your slices of bytes.
  • For storing single bytes, byte is sufficient; you don't want a slice of bytes. Where there are pointers in the C++ code used to point to specific locations in the array, you'll simply have an integer index value that selects one element of a slice.
  • Go strings are not simply sequences of bytes, they are sequences of UTF-8 characters stored internally as runes, which may have different lengths. So don't try to use strings for this algorithm.

To reimplement the algorithm shown, you do not need either pointers or pointer arithmetic at all. Instead of keeping pointers into the byte arrays as you would in C++, you'll use int indexes into the slices.

This is kind of hard to follow since it's virtually all pointer arithmetic. I would want to have a description of the algorithm handy while converting this (and since this is probably a well-known algorithm, that should not be hard to find). I'm not going to do the entire conversion for you, but I'll demonstrate with hopefully a simpler example. This prints each character of a string on a separate line.

C++:

unsigned char *data = &quot;Hello World&quot;;
unsigned char *ptr = 0;

for (int i = 0; i &lt; std::strlen(data); i++) {
    ptr = i + data;
    std::cout &lt;&lt; *ptr &lt;&lt; std::endl;
}

Go:

data := []byte(&quot;Hello World&quot;)

for i := 0; i &lt; len(data); i++ {
    // The pointer is redundant already
    fmt.Println(data[i:i+1])
}

So, learn about Go slices, and when you do reimplement this algorithm you will likely find the code to be somewhat simpler, or at least easier to understand, than its C++ counterpart.

huangapple
  • 本文由 发表于 2015年2月17日 03:31:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/28548970.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定