【问题标题】:Assembly 8086 - Subtracting in x86程序集 8086 - x86 中的减法
【发布时间】:2021-04-24 06:09:57
【问题描述】:

我正在开发一个使用 Vigenère 密码加密/解密数据的程序。除了解密部分,一切都很好。

加密和计算密钥背后的逻辑是:

  • 输入:“qwerty”

  • Key : "asd" = 计算出来的键是 "asdasd"

  • 密码:“catdxn”

  • 我使用以下算法进行加密:

  • 结果[i] = (INPUT[i]+key[i]) % 26

  • 结果[i] += 3dH ;转换为ASCII码

  • 密码[i] += 结果[i] 问题在于解密:

解密算法应该是

  • 结果[i] = (INPUT[i] - KEY[i]) % 26

  • IN CASE INPUT[i] - KEY[i] = NEGATIVE NUMBER = 加 26 所以公式变为

  • 结果[i] = (INPUT[i] - KEY[i] + 26) % 26

  • 结果[i] += 3dH

  • 密码[i] += 结果[i] ;获取结果字符串

预期的结果应该是“qwerty”,但我得到的是“usgtrm”。

所以按照上面描述的算法,我有以下代码:

;inputKey           = KEY,
;inputWORD          = Input,
;cipherText         = Result    
;inputWORDLENGTH    = length of input = CX
XOR DI,DI
vigDECLOOP:
    cmp di,cx
    JNB DONELOOPDEC 
    PUSH CX
    mov si, offset inputWORD
    ADD SI,DI
    XOR DX,DX
    MOV DL, DS:[SI]         ; DL = INPUT[I]
    xor SI,SI
    MOV SI, OFFSET inputKEY
    ADD SI, DI
    XOR CX,CX
    MOV CL, DS:[SI]         ; CL = KEY[I]
    SUB DL, CL
    ; ========
    ; Here in case is negative number I somehow need to add 26 to DL (result of DIV )
    ; IT 2:  61- 73 = EE in DL and should be -18, I know is something about the signed bit 
    ; but I dont know what to read and where about this.
    ; ========
    mov ax, cx              ; Store in AX the result of subtracting
    mov bx, 26              ; add in bx 26 
    div bx                  ; To obtain the reminder from % 26 
    ; ========
    ; ========
    add dl, 3Dh             ; add 3dH to DL(reminder of DIV) to get the asci        
    xor si,si   
    mov si, offset cipherText
    add si,di
    xor dh,dh
    add dl, DS:[si]
    mov DS:[si],dl
    INC DI
    POP CX
    jmp vigDECLOOP
DONELOOPDEC:    
    RET

问题在于减法,我对这个问题完全不熟悉。 让我们说“catdxn”这个词。 63、61、74、64、78、6E 和 'asdasd' 键 61, 73, 64, 61, 73, 64 在第二次迭代中,我们有 61 - 73 (SUB DL, CL) = 结果是 FFFF FFFF FFFF FFEE 或 - 18。 发生这种情况时,我需要将 26 添加到结果中,但我无法理解: SUB DL, CL STORES IN DL = EE 的结果这是十进制的 238,如何添加十进制的 26 或 (1A Hex) 到一个正数......它应该是'61h - 73h = -18d + 26d 或 1Ah = 8'。可能真的错了。

【问题讨论】:

  • 您的算法可能打算使用字母,而不是 ascii 代码。
  • 不知何故,您设法得出结论,18446744073709551598 = 0xFFFFFFFFFFFFFFEE-18 相同。使用相同的思路得出结论 0xEE-18 相同。

标签: assembly encryption x86-16 subtraction emu8086


【解决方案1】:

问题在于解密

没有。连加密都错了!正如 Jester 所说,您正在使用 ASCII 代码,而您应该使用字母表中字母的偏移量 [0,25]。

这是原始的 Vigenère 编码,减/加 97 来转换小写字母:

CIPHER[i] = ((INPUT[i]-97 + KEY[i]-97) % 26) + 97

INPUT  : "qwerty"
KEY    : "asdasd"
CIPHER : "qohrlb"

解密算法应该是

RESULT[i] = (INPUT[i] - KEY[i]) % 26

如何使用 INPUT 进行解密?这就是解密试图找出的!


您当前代码中的一些错误包括:

  • 您在 DL 中有减法的结果,并且您想将其除以 26,但您将 CX 除以 26
  • 您使用了字大小的除法,但忘记将 DX 预先归零

接下来使用字节大小的除法来纠正这几个错误:

  sub dl, cl
  mov ax, dx              ; Store in AX the result of subtracting
  mov bl, 26
  div bl                  ; To obtain the reminder from % 26 
  add ah, 3Dh             ; add 3Dh to AH (remainder of DIV) to get the ascii
  mov si, offset cipherText
  add si, di
  add [si], ah

为什么你认为添加 3Dh(十进制的 61)会产生 ASCII?


您当前的加密是这样做的:

        113 119 101 114 116 121  INPUT[]  : "qwerty"
         97 115 100  97 115 100  KEY[]    : "asdasd"
        --- --- --- --- --- ---     
        210 234 201 211 231 221  INPUT[]+KEY[]
          2   0  19   3  23  13  (INPUT[]+KEY[]) % 26
cipher   63  61  80  64  84  74  (INPUT[]+KEY[]) % 26 + 3Dh

          ?   =   P   @   T   J  CIPHER[] : "catdxn" ???

我看不出你从哪里得到你的 CIPHER。会不会是您将数字 63、61 和 64 解释为十六进制?它们确实代表“c”、“a”和“d”。


关于减法本身的问题。这完全取决于您如何查看编码数字。如果DL 包含位模式 11101110b (EEh),并且您以无符号方式查看它,则它表示 238,但如果您以签名方式查看它,那么它代表-18。
只需将其视为带符号的数字并添加所需的 26。您最终将得到一个范围为 [0,25] 的数字。

  sub dl, cl              ; DH = 0
  jns IsPositive
  add dl, 26
IsPositive:
  mov ax, dx              ; Store in AX the result of subtracting

【讨论】:

  • 解密的输入是密文,输出是明文。 RESULT[i] = (INPUT[i] - KEY[i]) % 26 在我看来可以作为解密的描述。
猜你喜欢
  • 2012-12-22
  • 2013-05-14
  • 2013-07-25
  • 1970-01-01
  • 2016-03-30
  • 2021-12-18
  • 2015-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多