작성일 : 2005년 11월 어느날
작성자 : 김대영(아크마)
목적 : This program encrypts and decrypts a message string, using modular arithmetic (한글로 하려니 참 말이 어색해서)
; MP2 - Encryption and Decryption
;
; 김대영
; 11월 어느날
;
; This program encrypts and decrypts a message string, using
; modular arithmetic
BITS 16
;====== SECTION 1: Define constants =======================================
CR EQU 0Dh
LF EQU 0Ah
BS EQU 08h
ESC EQU 1Bh ; ESC key
SPACE EQU 20h
MAXLen EQU 60 ; MAXimum length of input string
; You may define additional constants here
;====== SECTION 2: Declare external procedures ============================
EXTERN kbdin, dspout, dspmsg, mp2xit, ascbin
EXTERN libGetStr, libKeys, libEncryp, libDecryp
GLOBAL k1, k2, mik1, prompt, invmsg, inpstr, modulo, CRLFString
GLOBAL GetStr, Keys, Encryp, Decryp
;====== SECTION 3: Define stack segment ===================================
SEGMENT stkseg STACK ; *** STACK SEGMENT ***
RESB 64*8
stacktop:
RESB 0 ; NASM bug workaround
;====== SECTION 4: Define code segment ====================================
SEGMENT code ; *** CODE SEGMENT ***
;====== SECTION 5: Declare variables for main procedure ===================
prompt DB CR,LF,LF,'?','$'
invmsg DB CR,LF,'Invalid command','$'
inpstr RESB MAXLen ; Input string
crlfmsg DB CR,LF, '$'
k1 DW 1 ; Encryption/decryption keys
k2 DW 0
mik1 DW 1 ; Multiplicative inverse of k1 mod 37
;You may declare additional variables here
modulo DW 37 ;t
invkeymsg DB CR,LF,'Invalid Keys','$'
s DW 0
b DW 0
;====== SECTION 6: Program initialization =================================
..start:
MOV AX, CS ; Initialize Default Segment register
MOV DS, AX
MOV AX, stkseg ; Initialize Stack Segment register
MOV SS, AX
MOV SP, stacktop ; Initialize Stack Pointer register
;====== SECTION 7: Main procedure =========================================
main:
.mainloop:
MOV BX, inpstr
CALL GetStr
CMP BYTE [BX], 'K' ; K for Keys function
JE .doKeys
CMP BYTE [BX], 'E' ; E for Encryption function
JE .doEncryp
CMP BYTE [BX], 'D' ; D for Decryption function
JE .doDecryp
CMP BYTE [BX], 'Q' ; Q for Quit function
JE .done
MOV DX, invmsg ; Otherwise invalid command
CALL dspmsg
JMP .mainloop
.doKeys:
INC BX ; Go past command character
CALL Keys
JMP .mainloop
.doEncryp:
INC BX ; Go past command character
CALL Encryp
JMP .mainloop
.doDecryp:
INC BX ; Go past command character
CALL Decryp
JMP .mainloop
.done:
CALL mp2xit
GetStr:
;CALL libGetStr
pusha
mov dx, prompt
call dspmsg
mov ax,0
mov cx, bx; //첫번째 위치값을 저장함
.GetStrBegin
call kbdin ; Wait for a key to be pressed
cmp al, 13 ; if return
je .GetStrDone
cmp al, 8 ; if bakspace
jne .NoBackspace
cmp cx, bx ; 백스페이스로 지울때 ? 여기 이전까지만 지우도록
je .GetStrBegin
dec bx ; 백스페이스 누르면 입력스트링의 가르키는 오프셋을 감소
mov dx, 8
call dspout
mov dx, ''
call dspout
mov dx, 8
call dspout
jmp .GetStrBegin
.NoBackspace
mov byte[bx], al ; patter[i] = al
mov dx, ax
call dspout
inc bx
jmp .GetStrBegin
.GetStrDone
mov byte[bx], '$'
mov dx, crlfmsg
call dspmsg
popa
RET
Keys:
PUSHA
CALL ascbin
CMP DL, 0 ; ascbin 호출 이후에 DL 값으로 변환성공여부
jne .invalidKeys
CMP AX, 1
JL .invalidKeys
CMP AX, 36
JG .invalidKeys
MOV word[s], AX
CALL ascbin
CMP DL, 0
jne .invalidKeys
CMP AX, 1
JL .invalidKeys
CMP AX, 36
JG .invalidKeys
MOV word[b], AX
MOV CX, 1
.multInvLoop:
; if(((s * i) % t) == 1)
;
MOV AX, WORD [s]
MOV BX, WORD [modulo]
MUL CX
CALL XmodY
CMP AX, 1 ; hasInv = true;
JZ .hasInv
;
CMP CX, WORD [modulo]
JZ .invalidKeys ; i = t
INC CX
JMP .multInvLoop
; }
.hasInv:
MOV WORD [mik1], CX
MOV AX, word[s]
MOV WORD[k1], AX
MOV AX, word[b]
MOV WORD[k2], AX
JMP .endKeys
.invalidKeys:
MOV DX, invkeymsg
CALL dspmsg
.endKeys:
POPA
RET
; inputs: AX = X
; BX = Y
; Outputs: AX = remainder
XmodY:
DIV BX
MOV AX, DX
RET
Encryp:
;CALL libEncryp
;RET
PUSHA
; print 2 spaces
MOV DL, 20h
CALL dspout
CALL dspout
;foreach(inputString as char c)
;{
.forEachChar:
CMP BYTE [BX], '$'
JE .endEnc
CMP BYTE [BX], 13
JE .endEnc
; if(c > 0x5A || c < 0x41) {
; printf("%c", c)
; 0 <= c <=9 , A <= c <= Z not a, z
CMP BYTE [BX], '0' ; 30h
JL .rawPrintChar
CMP BYTE [BX], '9'
JL .encDigit
CMP BYTE [BX], '@' ;40h
JL .rawPrintChar
CMP BYTE [BX], 'Z'
JG .rawPrintChar
JMP .encChar
; } else {
; char z = 0xFF, d;
.encDigit
MOVZX AX, BYTE [BX]
SUB AX, 15h
JMP .encDo
.encChar
MOVZX AX, BYTE [BX]
SUB AX, 40h
; while(z > 26)
;
.encDo:
; e := g( (f(c) * k1 + k2) mod 37 )
MUL WORD[k1]
ADD AX, WORD[k2]
PUSH BX ; save BX
MOV BX, WORD [modulo]
CALL XmodY ; AX now contains (m * z) % K2
POP BX ; get BX
;CMP AX, 36
;JA .encWhile
; }
.printChar:
; z += 0x40;
CMP AX, 27
JL .convChar
; 숫자라면 15h만 더해줌
ADD AX, 15h
MOV DX, AX
JMP .realPrintChar
.convChar
ADD AX, 40h
MOV DX, AX
JMP .realPrintChar
.rawPrintChar:
MOVZX DX, BYTE [BX]
.realPrintChar:
CALL dspout
INC BX
JMP .forEachChar
.endEnc:
POPA
ret
Decryp:
;CALL libDecryp
;RET
PUSHA
; print 2 spaces
MOV DL, 20h
CALL dspout
CALL dspout
.whileEachDecChar:
CMP BYTE [BX], '$'
JE .endDec
CMP BYTE [BX], 13
JE .endDec
; 0 <= c <=9 , A <= c <= Z not a, z
CMP BYTE [BX], '0' ; 30h
JL .rawDecPrint
CMP BYTE [BX], '9'
JL .decDigit
CMP BYTE [BX], '@' ;40h
JL .rawDecPrint
CMP BYTE [BX], 'Z'
JG .rawDecPrint
JMP .decChar
.decDigit
MOVZX AX, BYTE [BX]
SUB AX, 15h
JMP .decDo
.decChar
MOVZX AX, BYTE [BX]
SUB AX, 40h
.decDo:
; d := g( (mik1 * (f(c) + 37 - k2)) mod 37 )
ADD AX, WORD[modulo]
SUB AX, WORD[k2]
MUL WORD[mik1]
PUSH BX ; save BX
MOV BX, WORD [modulo]
CALL XmodY ; AX now contains (m * z) % K2
POP BX ; get BX
.printDecChar:
CMP AX, 27
JL .convDecChar
; 숫자라면 15h만 더해줌
ADD AX, 15h
MOV DX, AX
JMP .realDecPrintChar
.convDecChar
ADD AX, 40h
MOV DX, AX
JMP .realDecPrintChar
.rawDecPrint:
MOVZX DX, BYTE [BX]
.realDecPrintChar:
CALL dspout
INC BX
JMP .whileEachDecChar
.endDec:
POPA
ret
좋은 자료네요!
하지만 제게는 너무 멉니다 ^^
감사합니다 공부해야겠네요 ㅜㅜ