我正在尝试翻译一个C#实现的RC4密码,我写到了球拍语言。
然而,它们正在产生不同的密钥流。我已经消除了错误写入密钥调度阶段的可能性;这必须是正确的,因为它们导致相同的数组S。因此,我的重点是寻找密钥流生成阶段的差异。
C#:
public int Dencode (int c)
{
I = (I + 1) % 256;
J = (J + S [I]) % 256;
int tmp = S [I];
S [I] = S [J];
S [J] = tmp;
return S [(S[I] + S[J]) % 256] ^ c;
}球拍:
(define (toret c)
(set! i (unsafe-fxmodulo (add1 i) 256))
(set! j (unsafe-fxmodulo (add1 (Sr i)) 256))
(swap! (box (Sr i)) (box (Sr j)))
(bitwise-xor (Sr (unsafe-fxmodulo (+ (Sr i) (Sr j)) 256)) c))将swap定义为
(define (swap! ba bb)
(define temp (unbox ba))
(set-box! ba (unbox bb))
(set-box! bb temp))Sr定义为(define (Sr x) (unsafe-bytes-ref S x))。
有什么关系?为什么这些功能产生不同的输出?在这两种情况下,i和j都初始化为0,S是一个相同的256个字节数组.
发布于 2013-09-07 17:13:19
有一个非常愚蠢的错误。(set! j (unsafe-fxmodulo (add1 (Sr i)) 256))不等同于J = (J + S [I]) % 256;!在每个语句之后添加调试printf行非常有帮助。
发布于 2013-09-07 17:10:22
线
(swap! (box (Sr i)) (box (Sr j)))不会做你想做的事。它不会神奇地使(Sr i)和(Sr j)成为可变的引用。swap!过程交换框的内容--但是这些框包含(Sr i)和(Sr j)的值,而不是引用。
您需要做的是修改您的swap!过程以使用unsafe-bytes-set!。
这里有一些代码来说明我的观点:
#lang racket
(require racket/unsafe/ops)
(define (box-swap! x y)
(define tmp (unbox x))
(set-box! x (unbox y))
(set-box! y tmp))
(define (wrong-swap! bs x y)
(box-swap! (box (unsafe-bytes-ref bs x))
(box (unsafe-bytes-ref bs y))))
(define (right-swap! bs x y)
(define tmp (unsafe-bytes-ref bs x))
(unsafe-bytes-set! bs x (unsafe-bytes-ref bs y))
(unsafe-bytes-set! bs y tmp))示例:
> (define bs (bytes 1 2 3 4 5 6))
> bs
#"\1\2\3\4\5\6"
> (wrong-swap! bs 0 5)
> bs
#"\1\2\3\4\5\6"
> (right-swap! bs 0 5)
> bs
#"\6\2\3\4\5\1"https://stackoverflow.com/questions/18675705
复制相似问题