在球拍上实现 RC4

Implementing RC4 on Racket

本文关键字:实现 RC4      更新时间:2023-10-16

我正在尝试将我编写的RC4密码的C#实现转换为Racket语言。

但是,它们正在产生不同的密钥流。我已经消除了错误编写密钥调度阶段的可能性;这必须是正确的,因为它们会产生相同的数组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)) .

有什么区别?为什么这些函数产生不同的输出?在这两种情况下,ij 都初始化为 0,并且 S 是相同的 256 字节数组。

(swap! (box (Sr i)) (box (Sr j)))

不会做你所期望的。它不会神奇地(Sr i)(Sr j)可变引用。swap!过程交换框的内容---但框包含按值而不是按引用(Sr j) (Sr i)和。

您需要做的是修改您的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
#"123456"
> (wrong-swap! bs 0 5)
> bs
#"123456"
> (right-swap! bs 0 5)
> bs
#"623451"

有一个非常愚蠢的错误。 (set! j (unsafe-fxmodulo (add1 (Sr i)) 256))不等于J = (J + S [I]) % 256;!在每个语句后添加调试 printf 行有很大帮助。