new project, to encrypt a word using polyalphabetic cipher, that is using a key word, may it be different each time the program is run (entered by user) to encrypt text.. so far i used an example program in the book that encrypt text but not polyalphbetically. I am also instructed that i have to use the XLAT instruction for my encryption, and im not sure what that instruction does.. so far i have this program, it encrypts but not the way it is supposed to because i dont know how to use the 'KEY' the user enters to do the actualy encryption... also where do i get the length of the 'KEY' the user enters? im getting 3778 or something from entereing 3 letters.... well here's the program, any input would be helpful.. thank you.
include \masm615\include\irvine16.inc
key = 239
bufmax = 35
.data
sprompt byte "Enter the plain text: ",0
sencrypt byte "CIPHERTEXT: ",0
skey byte "KEY: ",0
theend byte "END OF DATA",0
lengthbuf byte "LENGTH = ",0
buffer byte bufmax dup(0)
bufsize dword ?
.code
main proc
startup
start:
mov edx,offset skey
call writestring
call crlf
call inputthekey
mov edx,offset lengthbuf
call writestring
mov edx,bufsize
call writedec
call crlf
mov edx,offset sprompt
call writestring
call crlf
call inputthestring
call translatebuffer
mov edx,offset sencrypt
call displaymessage
mov edx,offset theend
call writestring
exit
main endp
mytbl proc ; to be used with xlat later, not sure if correct
i=1
while i LE 26
byte 40h+i
i=i+1
endm
while i LE 26
byte 40h+i
i=i+1
endm
mytbl endp
inputthekey proc
pushad
mov ecx,bufmax
mov edx,offset buffer
call readstring
mov bufsize,eax
call crlf
popad
ret
inputthekey endp
inputthestring proc
pushad
mov ecx,bufmax
mov edx,offset buffer
call readstring
mov bufsize,eax
call crlf
popad
ret
inputthestring endp
displaymessage proc
pushad
call writestring
call crlf
mov edx,offset buffer
call writestring
call crlf
popad
ret
displaymessage endp
translatebuffer proc
pushad
mov ecx,bufsize
mov esi,0
L1:
xor buffer[esi],key
inc esi
loop l1
popad
ret
translatebuffer endp
quit: exit
end main
Do you mean polyalphabetic?
http://en.wikipedia.org/wiki/Substitution_cipher#Polyalphabetic_substitution
yes it seems it is polyalphabetic, guess he mistyped it on the project sheet :clap:
From opcodes.hlp in the MASM32 package, for XLAT/XLATB:
Quote
Replaces the byte in AL with byte from a user table addressed by BX. The original value of AL is the index into the translate table. The best way to describe this is MOV AL,[BX+AL]
MOV AL,[BX+AL] is not a valid instruction, but it does express what the XLAT instruction does. So for an example, in the code below, after the XLAT instruction AL would contain 'C'.
.data
table db 'ABCD'
.code
mov bx, offset table
mov al, 2
xlat
A polyalphabetic cipher is not one that uses a keyword, but one that uses multiple substitution alphabets. Are you supposed to have the user enter multiple substitution alphabets, or are you supposed to somehow generate the alphabets from the entered keyword?
In the mytbl procedure the second while loop will not be entered because the value of i will be 27 after the first while loop. The first while loop will expand to the byte sequence 41h-5Ah, in the
code segment. A macro that would place the table in the data segment would probably be a better choice, because you can access data in the data segment without using a segment override.
The irvine16 library includes a Str_length procedure that returns the length of a null-terminated string.
im spose to use the KEYword to help cypher the text, and he asks for the length of the keyword, so i guess if the word is 3 digits long, then im spose to add 1,2,3 to watever letter the normal text is. ex: KEY: 'ABC', Length: '3', plain text:'AAA', CIPHERED:'BCD' .. something along those lines.. the 'mytbl' that i wrote was something he wrote in class and said 'this will help ur program write out the alphabet two times', yet he didnt explain how to even incorporporate it in anything, or even how to go about workin the program out, im working off a basicbasic example i found in the book..im so lost.. lol, so much for a happy thanksgiving ::)
Quote from: MichaelW on November 25, 2005, 03:01:21 AM
A polyalphabetic cipher is not one that uses a keyword, but one that uses multiple substitution alphabets. Are you supposed to have the user enter multiple substitution alphabets, or are you supposed to somehow generate the alphabets from the entered keyword?
Er, the wikipedia article you cited does not say there is no keyword. In fact, the examples such as Vigenere explicitly mention keywords.
Each letter in the keyword represents a different substitution alphabet. The simplest way is to use shifted alphabets (as in Vigenere) where, for example, the B alphabet table is the A alphabet table shifted one position. But in fact, each table can be an arbitrary one.
The keyword is generally used this way...
Plaintext: R i g h t n o w
Keyword=CAT: C A T C A T C A
Ciphered text: a b c d e f g h
where
a = R translated using table C
b = i translated using table A
c = g translated using table T
d = h translated using table C
and so on and so forth...
The exact ciphered text, which I've randomly written as abcdefgh, depends on the translation tables used.
Quote from: tenkey on November 25, 2005, 08:12:40 AM
Quote from: MichaelW on November 25, 2005, 03:01:21 AM
A polyalphabetic cipher is not one that uses a keyword, but one that uses multiple substitution alphabets. Are you supposed to have the user enter multiple substitution alphabets, or are you supposed to somehow generate the alphabets from the entered keyword?
Er, the wikipedia article you cited does not say there is no keyword. In fact, the examples such as Vigenere explicitly mention keywords.
I did not mean to imply that there is no keyword, just that the presence of a keyword does not make a cipher polyalphabetic. But I see now that I misinterpreted "new project, to encrypt a word using polyalphabetic cipher, that is using a key word," as "new project, to encrypt a word using polyalphabetic cipher, IOW, using a key word,"
thanks guys, i seem to understand what polyalpha. substitution is... now my problem lies in how to actually apply it.. had anyone done examples like this, or have something i can work off of? thanks
well seems like nobody does... well can anybody tell me what the 'mytbl' procedure does? and how i can use it to encrypt my plain text? i know michaelw wrote wat call to use, but where would i insert it in my code? i keep getting the most random numbers, not the number of digits in my 'KEY'..thx
Try reading tenkey's post again, and then this page:
http://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher
If you are going to use a Vigenère cipher, and you are not going to limit the key to a restricted range of characters, then you will need 26 alphabets. As I stated previously, it would be better to place the table in the data segment so you can access it without a segment override. You could code a macro to create the table, but it would probably be easier to create it manually.
As I stated previously, the irvine16 library includes a Str_length procedure that returns the length of a null-terminated string. The ReadString procedure returns a null-terminated string, so you can just pass the key to the Str_length procedure to get the length. I don't know what sort of documentation you may have for the irvine16 library, but if all else fails you can just use the source file for documentation. You should have a copy of the source file, or if not you can get a copy here:
http://www.cs.fit.edu/~mmahoney/cse3101/examples/Lib16/
my KEY has no limit of characters, but my PLAINTEXT has a limit of 35, also when '!' is enterd as a KEY my program should exit, i tried using the -test- and -cmp- calls to try to exit my program when '!' is entered but i've had no luck, i tried using its hexadecimal code and using '!' as a char
I don't know what your code currently looks like, but if you are using ReadChar to get the input, then you should be able to just compare al to '!'. If you are using ReadString, then it will be more difficult. For this and other purposes it would be convenient to have a procedure that could return a single character from a string, something like the BASIC MID$ function, but with the length fixed at 1. You should probably assume that the character indexes start at zero, so, for example, to get the last character of a string you would pass the index (stringLength – 1). As a starting point, take a look at the Str___ procedures in irvine16.asm. And keep in mind that for indirect memory operands with 16-bit registers you are limited to using a base (BP or BX) or index (DI or SI) register, or one of each.
uppercase proc
i=0
repeat 97
byte i
i=i+1
endm
repeat 26
byte i-32
i=i+1
endm
repeat 133
byte i
i=i+1
endm
uppercase endp
------------------------------------------------
mov ebx,offset uppercase
mov al,[ebx]
xlat
mov [ebx],al
the proffesor gave me that code to try to use to translate whatever plaint text entered to be converted to uppercase... but it doesnt seem to be doing its job... he's lost in how to use assembler himself, and couldnt answer me... do you guys know if its right or close at all?
include \masm615\include\irvine16.inc
key = 239
bufmax = 35
.data
sprompt byte "Enter the plain text: ",0
sencrypt byte "CIPHERTEXT: ",0
skey byte "KEY: ",0
sdecrypt byte "Decrypted: ",0
theend byte "END OF DATA",0
lengthbuf byte "LENGTH = ",0
buffer byte bufmax dup(0)
bufsize dword ?
.code
main proc
startup
start:
mov edx,offset skey
call writestring
call crlf
call inputthekey
mov edx,offset lengthbuf
call writestring
mov edx,bufsize
call writedec
call crlf
mov edx,offset sprompt
call writestring
call crlf
call inputthestring
call translatebuffer
mov edx,offset sencrypt
call displaymessage
mov edx,offset theend
call writestring
exit
main endp
mytbl proc ; to be used with xlat later, not sure if correct
i=1
while i LE 26
byte 40h+i
i=i+1
endm
while i LE 26
byte 40h+i
i=i+1
endm
mytbl endp
uppercase proc
i=0
repeat 97
byte i
i=i+1
endm
repeat 26
byte i-32
i=i+1
endm
repeat 133
byte i
i=i+1
endm
uppercase endp
inputthekey proc
call readchar
cmp al,'!'
je quit
pushad
mov ecx,bufmax
mov edx,offset buffer
call readstring
mov bufsize,eax
call crlf
popad
ret
inputthekey endp
inputthestring proc
pushad
mov ecx,bufmax
mov edx,offset buffer
mov ebx,offset uppercase
mov al,[ebx]
xlat
mov [ebx],al
call readstring
mov bufsize,eax
call crlf
popad
ret
inputthestring endp
displaymessage proc
pushad
call writestring
call crlf
mov edx,offset buffer
call writestring
call crlf
popad
ret
displaymessage endp
translatebuffer proc
pushad
mov ecx,bufsize
mov esi,0
L1:
xor buffer[esi],key
inc esi
loop l1
popad
ret
translatebuffer endp
quit: exit
end main
and thats currently my code... it encrypts but not polualphabetically using the key... and the LENGTH of the string isnt coming out correct :dazzled:.......... thanks for any help!
I assume that you are doing the Vigenere cipher - it is the simplest keyword-based polyalphabetic substitution cipher.
Use this text encoding: a=0, b=1 ... z=25.
Put both your plaintext and your repeated keyword into this encoding.
Now, for each letter of the plaintext, add its value to to corresponding key value and convert it to the range 0 to 25 modulo 26.
Then translate this back into ASCII.
thanks aero , yea im trying to use the Vigenere method... and im not confused on how it works, jsut the actual coding.. my profesor loves to give projects and not explain the calls or procedures we can use or how to use them to do anything within the project, like he said to use tables and repeats to make the alphabet A-Z two times, and to make all the plaintext turn into Uppercase... he wrote down somewhat how to do it, but doesnt explain what each line does, so my whole class is just confused... i approach him so he can try to explain, and he jus brushes me off pretty much.. :'(
Depending on how you do the conversion, if the alphabets are uppercase then the ciphertext will be uppercase. If not, the Irvine16 library includes a str_ucase procedure that converts a null-terminated string to uppercase.
If you are supposed to use just two alphabets, then are you supposed to use the case of the key characters to select the alphabet?
As I stated previously, your alphabets would be easier to access if you placed them in the data segment. You could do this by expanding a macro in the data segment, but with just two alphabets you could do it manually in far less time than it would take to write the macro. For example:
.data
alpha_lc db "ABCDEFGHIJKLMNOPQRSTUVWXYZ",0
alpha_uc db "BCDEFGHIJKLMNOPQRSTUVWXYZA",0
prof. said not to use anything from the libraries, to do everything by hand.. hence my 'uppercase' procedure, which im not sure how to call it so it'l work. ::)... :dazzled:
Your mytbl and uppercase procedures are not functional procedures they are data definitions encased in procedure definitions, in the code segment. As a table, uppercase seems partially correct, but for index values 0-96 and 133-255 I would use the value zero. You could then use the character code of the character to be converted as an index into the table, and if the indexed value were non-zero, substitute it for the character code. In pseudocode, and assuming the table and string were both in the data segment:
bx = offset table
di = offset string
looper:
al = [di]
if al == 0 then finished (end of string)
xlat
if al != 0 then [di] = al (substitute upper case for lower case)
di = di + 1
loop looper
One possible reason for placing the alphabet twice in a row is to avoid the modulus operation. Vigenere is cyclic, and just repeating the alphabet allows you to use simple indexing, or XLAT. You will need to use Aero's suggestion of translating, at least, the keyword letters so that 'A' --> 0, 'B' --> 1, etc. Or use all of Aero's suggestion and translate both plaintext and keyword. In the second case, you can index (or XLAT) the dual alphabet directly.
The XOR code is puzzling. XOR-encryption was another popular substitution cipher that was usable with multibyte keys. However, it will not produce the "add 1, add 2" effect.
Aha, an explanation that I can understand. Starting with an already repeated key, my initial coding of a 32-bit encryption routine required just 13 instructions (and it worked, ATTACKATDAWN and LEMONLEMONLE produced LXFOPVEFRNHR, duplicating the results from the Wikipedia Vigenère cipher page).
Make that 12 instructions.
indexing.. is that taking one letter at a time, and adding it to my key? i wasnt taught how to do that... the proffesor wrote on an example ' txt[ebx] ' as a way to get each individual letter one by one, but when i try to assemble it kept givin me an error.. Michael, lol so u did the encryption program jus to try it out? hehe u guys are too funny
This would be an example of indexing (taken from a 16-bit version of my encryption routine):
mov bl, plaintext[si]
The plaintext[si] operand addresses a byte in the data segment at an offset address that is calculated (at runtime) by adding the offset address of the plaintext label to the value in SI. The instruction copies the addressed byte into BL.
For more information start at Direct Memory Operands here:
http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ProgrammersGuide/Chap_03.htm
And continue through the Indirect Memory Operands section.
My code was based on this part of tenkey's post:
Quote
Or use all of Aero's suggestion and translate both plaintext and keyword. In the second case, you can index (or XLAT) the dual alphabet directly.
I used indexing instead of XLAT, but I see no reason why you could not use XLAT. I used uppercase for everything. For the dual alphabet I used two identical copies of the alphabet.
See the section that starts with "Vigenère can also be viewed algebraically." Here:
http://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher
And the page at the modulo link to understand how the dual alphabet can eliminate the modulus operation.
me and a friend came up with an convert to uppercase program using xlat... but how do i encorporate it into my encryption program? i have been trying but dont know where to place it and what to use for 'text'...
include \masm615\include\irvine16.inc
.data
table byte 0
i=1
repeat 96
byte i
i=i+1
endm
repeat 26
byte i-32
i=i+1
endm
repeat 133
byte i
i=i+1
endm
abece byte 41h
i=42h
repeat 25
byte i
i=i+1
endm
i=42h
repeat 25
byte i
i=i+1
endm
text byte "uppercase!!!",0
.code
main proc
startup
mov ebx,offset table
mov ecx,sizeof text
ol:
mov al,text[ecx]
xlat
mov text[ecx],al
loop ol
mov al,text[0]
xlat
mov text[0],al
mov edx,offset text
call writestring
exit
main endp
end main
what do i use as 'text' when i have read the string entered by user?, here text is determined by me, in my encryption its based on what the user inputs... what register would it be stored in?
I see now what you are doing with the uppercase conversion table, and it's cleaner than what I had in mind. Irvine16 is, obviously, a 16-bit library. In your code the only 32-bit register that you actually need to use is ECX (in text[ecx]), because CX will not work as an index. You can use a 32-bit register to pass offset addresses and counts, but the library procedures will use only the lower-order 16-bits because in a 16-bit app offset addresses are 16-bit values, and the loop instruction actually uses CX as the loop counter. I edited your code so I could test it, cleaned it up and corrected a few problems, and demonstrated one method of getting a string from the user. The call to ReadChar is so I could see the output without having to modify the program properties or run it from a batch file or the command line.
include \masm615\include\irvine16.inc
.data
table byte 0
i=1
repeat 96
byte i
i=i+1
endm
repeat 26
byte i-32
i=i+1
endm
repeat 133
byte i
i=i+1
endm
abece byte 41h
i=42h
repeat 25
byte i
i=i+1
endm
;i=42h
I=41H ; NEED TWO IDENTICAL ALPHABETS
;repeat 25
REPEAT 26
byte i
i=i+1
endm
BYTE 0 ; SO CAN DISPLAY AS STRING
;text byte "uppercase!!!",0
TEXT DB 50 DUP(0)
.code
;main proc
;startup
.STARTUP
MOV DX,OFFSET ABECE
CALL WRITESTRING
CALL CRLF
MOV DX,OFFSET TEXT
MOV CX,SIZEOF TEXT
CALL READSTRING
CALL CRLF
mov ebx,offset table
mov ecx,sizeof text
CALL UCASE
mov edx,offset text
call writestring
CALL READCHAR
.EXIT
UCASE PROC
ol:
mov al,text[ecx]
xlat
mov text[ecx],al
loop ol
mov al,text[0]
xlat
mov text[0],al
RET
UCASE ENDP
;exit
;main endp
;end main
END
include \masm615\include\irvine16.inc
key = 239
bufmax = 35
.data
sprompt byte "Enter the plain text: ",0
sencrypt byte "CIPHERTEXT: ",0
skey byte "KEY: ",0
sdecrypt byte "Decrypted: ",0
theend byte "END OF DATA",0
lengthbuf byte "LENGTH = ",0
buffer byte bufmax dup(0)
bufsize dword ?
.code
main proc
startup
table byte 0
i=1
repeat 96
byte i
i=i+1
endm
repeat 26
byte i-32
i=i+1
endm
repeat 133
byte i
i=i+1
endm
abece byte 41h
i=42h
repeat 25
byte i
i=i+1
endm
i=42h
repeat 25
byte i
i=i+1
endm
start:
mov edx,offset skey
call writestring
call crlf
call inputthekey
mov edx,offset lengthbuf
call writestring
mov edx,sizeof bufsize ; trying to ge LENGTH of KEY, keep getting 4...?
call writedec
call crlf
mov edx,offset sprompt
call writestring
call crlf
call inputthestring
call translatebuffer
mov edx,offset sencrypt
call displaymessage
mov edx,offset theend
call writestring
exit
main endp
inputthekey proc
call readchar
cmp al,'!'
je quit
pushad
mov ecx,bufmax
mov edx,offset buffer
call readstring
mov bufsize,eax
call crlf
popad
ret
inputthekey endp
inputthestring proc
call readchar
mov ebx,offset table
mov ecx,sizeof buffer
call UCASE
pushad
mov ecx,bufmax
mov edx,offset buffer
call readstring
mov bufsize,eax
call crlf
popad
ret
inputthestring endp
displaymessage proc
pushad
call writestring
call crlf
mov edx,offset buffer
call writestring
call crlf
popad
ret
displaymessage endp
translatebuffer proc
;pushad
mov ecx,bufsize
mov esi,0
L1:
mov al,buffer[esi]
xlat
add buffer[esi],abece[esi] ; getting error here, what should i use?
inc esi
loop l1
mov al,buffer[0]
xlat
mov buffer[0],al
;popad
ret
translatebuffer endp
quit: exit
UCASE PROC
ml1:
mov al,buffer[ecx]
xlat
mov buffer[ecx],al
loop ml1
mov al,buffer[0]
xlat
mov buffer[0],al
RET
UCASE ENDP
end main
thats what i have so far.....
tryin to work with the xlat, still confused, am i goin about it the right way? its not conveting to uppercase, and im not gettin the encryption to work ::) . . . also im getting LENGTH: 321 or big numbers like that for my LENGTH even if i just enter 3 letters... aye wat a headache..
The problem with:
add buffer[esi],abece[esi]
Is that the instruction contains two memory operands. As stated here under General-Purpose Registers:
http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ProgrammersGuide/Chap_01.htm
QuoteThe 8086-based processors do not perform memory-to-memory operations. For example, the processor cannot directly copy a variable from one location in memory to another. You must first copy from memory to a register, then from the register to the new memory location. Similarly, to add two variables in memory, you must first copy one variable to a register, then add the contents of the register to the other variable in memory.
So in this case you could replace the instruction with something like this:
mov dl,abece[esi]
add buffer[esi],dl
Your code has a major problem in that the tables are in the code segment, directly in the execution path. As a result the processor is attempting to execute the table data as if it were a valid instruction sequence, which it obviously is not. The tables
must be outside the execution path, and should preferably be in the data segment. A program can access data in the code segment, but because most instructions that access data use DS by default, and for the small memory model that the Irvine16 libraries use CS != DS, each memory access would require a CS segment override.
In case you defined the table macros in the code segment thinking that the macros must "execute" to build the tables, you should recognize that macro expansion takes place when the source file is assembled. MASM will expand the macros as they are encountered, regardless of which segment they are defined in.
I see two problems with getting the length of the key that was input. First, I don't understand what this is for:
mov edx,sizeof bufsize
WriteDec expects the number in EAX, not EDX, and SIZEOF returns the total number of bytes allocated for a variable, in this case 4.
Your inputthekey procedure is loading the length of the string returned by ReadString into bufsize, but the code that calls ReadChar is discarding the first character that is input. If you need to provide the user with a way to abort, a better choice would probably be to detect a zero length input (i.e. detect that the user just pressed enter without typing any characters).
tables before the execution! ah no wonder, its things like this that get me mad the prof. doesnt explain.. well that fixes that error, and i changed the line from edx to eax for LENGTH, but not all i keep getting is 4 no matter what length KEY i input.., maybe its reading the actual words "KEY:"?... also i have the Readchar instruction, because according to the prof. i need to abort only when the KEY is = ' ! ', you showed me before how to do this by using readchar and comparing my input to to '!' and if equal, jump to exit...
current code:
include \masm615\include\irvine16.inc
key = 239
bufmax = 35
.data
sprompt byte "Enter the plain text: ",0
sencrypt byte "CIPHERTEXT: ",0
skey byte "KEY: ",0
sdecrypt byte "Decrypted: ",0
theend byte "END OF DATA",0
lengthbuf byte "LENGTH = ",0
buffer byte bufmax dup(0)
bufsize dword ?
.code
table byte 0
i=1
repeat 96
byte i
i=i+1
endm
repeat 26
byte i-32
i=i+1
endm
repeat 133
byte i
i=i+1
endm
abece byte 41h
i=42h
repeat 25
byte i
i=i+1
endm
i=42h
repeat 25
byte i
i=i+1
endm
main proc
startup
start:
mov edx,offset skey
call writestring
call crlf
call inputthekey
mov edx,offset lengthbuf
call writestring
mov eax, bufsize ; edit! i re-read what you write 4 times and understood this part :)
call writedec
call crlf
mov edx,offset sprompt
call writestring
call crlf
call inputthestring
call translatebuffer
mov edx,offset sencrypt
call displaymessage
mov edx,offset theend
call writestring
exit
main endp
inputthekey proc
call readchar
cmp al,'!'
je quit
pushad
mov ecx,bufmax
mov edx,offset buffer
call readstring
mov bufsize,eax
call crlf
popad
ret
inputthekey endp
inputthestring proc
mov ebx,offset table
mov ecx,sizeof buffer
call UCASE ; trying to make PLAINTEXT all be uppercase, not being converted though.?
pushad
mov ecx,bufmax
mov edx,offset buffer
call readstring
mov bufsize,eax
call crlf
popad
ret
inputthestring endp
displaymessage proc
pushad
call writestring
call crlf
mov edx,offset buffer
call writestring
call crlf
popad
ret
displaymessage endp
translatebuffer proc
;pushad
mov ecx,bufsize
mov esi,0 ; think this is wrong, but following example in my book :(
L1:
mov dl,abece[esi] ; encryption code, adding alphabet[index] to plaintext[index]..
add buffer[esi],dl
xlat
add buffer[esi],al
inc esi
loop l1
mov al,buffer[0]
xlat
mov buffer[0],al
;popad
ret
translatebuffer endp
UCASE PROC
ml1:
mov al,buffer[ecx]
xlat
mov buffer[ecx],al
loop ml1
mov al,buffer[0]
xlat
mov buffer[0],al
RET
UCASE ENDP
quit: exit
end main
You moved table and abece outside the execution path, so the program no longer hangs, but they are still in the code segment. If you move table and abece into the data segment then your code will be able to access them without using a CS override. As the code is right now:
CS = 55Eh
Offset address of table (in the segment where it is defined) = 0
Offset address of abece (in the segment where it is defined) = 100h
DS = 5F1h
Absolute address of table = 55Eh*16+0 = 55E0h
Absolute address of abece = 55Eh*16+100h = 56E0h.
Without a CS override MASM assumes that table and abece are in the data segment, so the instructions are trying to access table at absolute address 5F1h*16+0=5F10h and abece at absolute address 5F1h*16+100h=6010h, and failing because the addresses are not correct. You could add a CS override to each instruction that accesses a table (e.g. mov al,cs:buffer[ecx]), and this would correct the problem, but it would be easier to just place the tables in the data segment and leave the instructions that access the tables as they currently are.
Your inputthekey procedure is still discarding the first character input. The simplest method that I can think of to get around this would be to move the returned character into the buffer, add one to the offset address passed to ReadString (so it will not overwrite the first character), and add one to the length returned.
inputthekey proc
call readchar
cmp al,'!'
je quit
mov buffer,al ;<<
pushad
mov ecx,bufmax
mov edx,offset buffer+1 ;<<
call readstring
add eax,1 ;<<
mov bufsize,eax
call crlf
popad
ret
inputthekey endp
And you will need two full alphabets. The macros are currently expanding to:
ABCDEFGHIJKLMNOPQRSTUVWXYZBCDEFGHIJKLMNOPQRSTUVWXYZ
fixed the LENGTH with what you put, and fixed the position of my tables, now its reading the LENGTH correctly, also i used this code for Alphabet 2x.
abece byte 0
i=1
while i LE 26
byte 40h+1
i=i+1
endm
while i LE 26
byte 40h+i
i=i+1
endm
i have my program encrypting...just not the exact way i want it to... its giving me characters not just letters... im guessing my TranslateBuffer code is not correct ::)...
Hello. I am using readchar in a loop to read some input(I'm copying and pasting it). The problem is that when the "enter" key is pressed the cursor goes back to the begining of the line, not always a new line! This causes text to be overwritten. Therefore the encryption is not working. I am supposed to stop reading when the '#' character appears. Here's what I have so far. Thanks for any help!!
gettext proc
;Receives the text to be encrypted and puts it in "buffer"
pushad
mov edx,offset splain
call writestring
call crlf
call crlf
mov ecx,bufmax
mov edx,0
ls:
call readchar
cmp al,'#'
je @F
mov buffer[edx],al
inc edx
xor al,al
loop ls
@@:
call crlf
call crlf
mov bufsize,edx
inc bufsize
call crlf
popad
ret
gettext endp
gusto,
Your new alphabet generator macros have three problems:
The first byte at the abece label is a zero byte. To define a byte label without defining any data you could use:
abece label byte
The first data definition should have been byte 40h+i instead of 40h+1.
The second while loop will not run because you did not reinitialize i.
You could catch these errors if, while developing the code, you would have it display the combined alphabet each time it ran (the combined alphabet should be terminated with a null byte so you can use WriteString).
Also, it would be easier to code the macros (because you could avoid having to look up the character codes) and to understand what the macros are doing if instead of hex character codes you used the actual characters:
i='A'
while i LE 'Z'
byte i
i=i+1
endm
You need only a few pieces of information to do the encryption and decryption. From this page:
http://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher
Quote
Vigenère can also be viewed algebraically. If the letters A–Z are taken to be the numbers 0–25, and addition is performed modulo 26, then Vigenère encryption can be written,
Ci=Pi+Ki (mod 26)
and decryption,
Pi=Ci-Ki (mod 26)
To encrypt, you must first create the repeated key, equal in length to the plaintext, as shown on the referenced page. The plaintext and the key must be in uppercase, and both the plaintext and the ciphertext should be terminated with a null byte (to make it easy to detect when you have reached the end of either).
Then for each character in the plaintext:
ciphertext
= alphabet[(plaintext – 'A') + (repeatedkey – 'A')]
The look up in the combined alphabet effectively replaces the mod 26 operation. The result for (plaintext – 'A') + (repeatedkey – 'A') will be in the range 0-51.
To decrypt, for each character in the ciphertext:
plaintext = alphabet[((ciphertext – 'A') - (repeatedkey – 'A') + 26)]
The + 26 operation is necessary because the result for (ciphertext – 'A') - (repeatedkey – 'A') could be anywhere in the range –25 to +25, and the index values for the combined alphabet must be in the range 0-51.
Jorge,
I think the problem is that the ReadChar procedure calls the Read Keyboard with Echo function, which upon reading a carriage return character (0Dh) sends the standard output device a carriage return but not a linefeed. If you do not wish to exit from the procedure when you detect a carriage return, you could try using the Read Keyboard Without Echo function (Inerrupt 21h, function 8) instead. You will probably need to provide code to echo the characters as they are typed (other than the carriage return character), and for this you could use the Display Character function (Interrupt 21h, function 2).
Dude are you in my class, Prof. Burrs, CCNY? man i need help with that program also, i cant get project 5 please can you help me?