- 论坛徽章:
- 2
|
回复 67# mirnshi
自然必须有办法,还不止一种,实现。
C/C++都有不少coroutine的库。 在Windows上,有一套fiber的函数; 在posix上貌似有ucontext还是什么的。
但无论它们的代价再怎么低(fiber切换只有10来个指令), 还是不适合在循环里这么搞。
如果用纯C/C++, 可以这么搞:
- typedef struct
- {
- unsigned i, j;
- unsigned char s[256];
- } rc4_t;
- void rc4(rc4_t* self, char const* key, size_t len)
- {
- unsigned char* S = self->s;
- for (unsigned i=0; i<256; ++i)
- S[i] = i;
- for (unsigned i=0, j=0; i<256; ++i)
- {
- j = (j+key[i%len]+S[i]) % 256;
- std::swap(S[i], S[j]);
- }
- self->i = self->j = 0;
- }
- unsigned rc4_next(rc4_t* self)
- {
- unsigned* i = self->i;
- unsigned* j = self->j;
- unsigned char* S = self->s;
- unsigend k;
- *i = (*i+1) % 256;
- *j = (*j+S[*i]) % 256;
- k = S[*i]; S[*i] = S[*j]; S[*j] = k;
- return S[ (S[*i]+S[*j]) % 256 ];
- }
复制代码 客户代码就可以:
rc4_t g;
rc4(&g, key, len);
for ( ... ) {
// 这里由用户决定要加密什么
// 当需要一个加密流字节时
unsigned byte = rc4_next(&g);
}
但这其实就是在人肉实现coroutine, 然后再表达rc4算法。
就像是用亲戚关系的具体定义(父亲的亲兄弟的儿子), 而非直接用一个词(堂兄)表达。
人肉实现时需要保存哪些局部状态、 哪些是挂起点(这个例子中挂起点很简单,因为最后是一个无限循环) —— 这种分析很容易出错。
以前与starwing83讨论过是否可以将这种人肉翻译自动化一些, 不过他貌似没什么兴趣, 我也很懒…… 就此作罢了…… |
|