Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #74314 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2015-10-30 08:23 -0700 |
| Last post | 2015-11-04 09:50 +0100 |
| Articles | 20 on this page of 68 — 15 participants |
Back to article view | Back to comp.lang.c
Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-30 08:23 -0700
Re: Program to cipher a text, new thread, fresh one Bartc <bc@freeuk.com> - 2015-10-30 15:39 +0000
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-30 09:33 -0700
Re: Program to cipher a text, new thread, fresh one Richard Heathfield <rjh@cpax.org.uk> - 2015-11-01 09:33 +0000
Re: Program to cipher a text, new thread, fresh one Mark Storkamp <mstorkamp@yahoo.com> - 2015-10-30 11:17 -0500
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-30 09:32 -0700
Re: Program to cipher a text, new thread, fresh one Richard Heathfield <rjh@cpax.org.uk> - 2015-11-01 09:38 +0000
Re: Program to cipher a text, new thread, fresh one "Osmium" <r124c4u102@comcast.net> - 2015-10-30 10:55 -0600
Re: Program to cipher a text, new thread, fresh one Richard Heathfield <rjh@cpax.org.uk> - 2015-11-01 10:07 +0000
Re: Program to cipher a text, new thread, fresh one Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-01 10:42 +0000
Re: Program to cipher a text, new thread, fresh one Richard Heathfield <rjh@cpax.org.uk> - 2015-11-01 11:35 +0000
Re: Program to cipher a text, new thread, fresh one James Kuyper <jameskuyper@verizon.net> - 2015-11-01 08:33 -0500
Re: Program to cipher a text, new thread, fresh one Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-01 16:09 +0000
Re: Program to cipher a text, new thread, fresh one Bartc <bc@freeuk.com> - 2015-11-02 12:43 +0000
Re: Program to cipher a text, new thread, fresh one Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-02 13:25 +0000
Re: Program to cipher a text, new thread, fresh one Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-02 06:13 -0800
Re: Program to cipher a text, new thread, fresh one Keith Thompson <kst-u@mib.org> - 2015-11-01 12:26 -0800
Re: Program to cipher a text, new thread, fresh one supercat@casperkitty.com - 2015-11-01 07:59 -0800
Re: Program to cipher a text, new thread, fresh one Richard Heathfield <rjh@cpax.org.uk> - 2015-11-02 13:48 +0000
Re: Program to cipher a text, new thread, fresh one Bartc <bc@freeuk.com> - 2015-11-02 14:06 +0000
Re: Program to cipher a text, new thread, fresh one Richard Heathfield <rjh@cpax.org.uk> - 2015-11-02 14:51 +0000
Re: Program to cipher a text, new thread, fresh one Bartc <bc@freeuk.com> - 2015-11-02 15:48 +0000
Re: Program to cipher a text, new thread, fresh one Richard Heathfield <rjh@cpax.org.uk> - 2015-11-02 16:00 +0000
Re: Program to cipher a text, new thread, fresh one asetofsymbols@gmail.com - 2015-11-03 01:40 -0800
Re: Program to cipher a text, new thread, fresh one Richard Heathfield <rjh@cpax.org.uk> - 2015-11-03 11:16 +0000
Re: Program to cipher a text, new thread, fresh one "Osmium" <r124c4u102@comcast.net> - 2015-11-03 05:21 -0600
Re: Program to cipher a text, new thread, fresh one asetofsymbols@gmail.com - 2015-11-03 03:41 -0800
Re: Program to cipher a text, new thread, fresh one Richard Heathfield <rjh@cpax.org.uk> - 2015-11-03 11:53 +0000
Re: Program to cipher a text, new thread, fresh one "Osmium" <r124c4u102@comcast.net> - 2015-11-03 05:57 -0600
Re: Program to cipher a text, new thread, fresh one Richard Heathfield <rjh@cpax.org.uk> - 2015-11-03 12:48 +0000
Re: Program to cipher a text, new thread, fresh one Rosario19 <Ros@invalid.invalid> - 2015-11-04 09:09 +0100
Re: Program to cipher a text, new thread, fresh one Rosario19 <Ros@invalid.invalid> - 2015-11-04 09:37 +0100
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-11-04 07:09 -0800
Re: Program to cipher a text, new thread, fresh one "Osmium" <r124c4u102@comcast.net> - 2015-11-03 05:53 -0600
Re: Program to cipher a text, new thread, fresh one asetofsymbols@gmail.com - 2015-11-03 04:29 -0800
Re: Program to cipher a text, new thread, fresh one "Osmium" <r124c4u102@comcast.net> - 2015-11-03 06:42 -0600
Re: Program to cipher a text, new thread, fresh one Geoff <geoff@invalid.invalid> - 2015-11-01 08:07 -0800
Re: Program to cipher a text, new thread, fresh one Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-02 02:26 -0800
Re: Program to cipher a text, new thread, fresh one Rosario19 <Ros@invalid.invalid> - 2015-11-06 07:53 +0100
Re: Program to cipher a text, new thread, fresh one Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-07 10:01 -0800
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-30 10:50 -0700
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-30 10:53 -0700
Re: Program to cipher a text, new thread, fresh one Barry Schwarz <schwarzb@dqel.com> - 2015-10-30 11:52 -0700
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-30 12:12 -0700
Re: Program to cipher a text, new thread, fresh one Barry Schwarz <schwarzb@dqel.com> - 2015-10-30 21:05 -0700
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-30 23:58 -0700
Re: Program to cipher a text, new thread, fresh one Barry Schwarz <schwarzb@dqel.com> - 2015-10-31 03:09 -0700
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-31 03:47 -0700
Re: Program to cipher a text, new thread, fresh one Barry Schwarz <schwarzb@dqel.com> - 2015-10-31 11:42 -0700
Re: Program to cipher a text, new thread, fresh one Barry Schwarz <schwarzb@dqel.com> - 2015-10-30 12:04 -0700
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-30 12:10 -0700
Re: Program to cipher a text, new thread, fresh one "Osmium" <r124c4u102@comcast.net> - 2015-10-30 13:17 -0600
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-31 00:04 -0700
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-31 00:25 -0700
Re: Program to cipher a text, new thread, fresh one Keith Thompson <kst-u@mib.org> - 2015-10-30 12:34 -0700
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-30 21:49 -0700
Re: Program to cipher a text, new thread, fresh one Keith Thompson <kst-u@mib.org> - 2015-10-31 13:18 -0700
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-31 00:29 -0700
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-31 01:12 -0700
Re: Program to cipher a text, new thread, fresh one Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-31 12:24 +0000
Re: Program to cipher a text, new thread, fresh one Alla _ <modelling.data@gmail.com> - 2015-10-31 06:11 -0700
Re: Program to cipher a text, new thread, fresh one Bartc <bc@freeuk.com> - 2015-10-31 15:58 +0000
Re: Program to cipher a text, new thread, fresh one Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-31 17:37 +0000
Re: Program to cipher a text, new thread, fresh one Bartc <bc@freeuk.com> - 2015-10-31 18:14 +0000
Re: Program to cipher a text, new thread, fresh one Keith Thompson <kst-u@mib.org> - 2015-10-31 13:29 -0700
Re: Program to cipher a text, new thread, fresh one Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-31 20:35 +0000
Re: Program to cipher a text, new thread, fresh one Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-31 20:32 +0000
Re: Program to cipher a text, new thread, fresh one Rosario19 <Ros@invalid.invalid> - 2015-11-04 09:50 +0100
Page 1 of 4 [1] 2 3 4 Next page →
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-10-30 08:23 -0700 |
| Subject | Program to cipher a text, new thread, fresh one |
| Message-ID | <8465675b-8538-4031-a5b7-d5ddba34197d@googlegroups.com> |
Hello!
I have decided to start a new thread on the program
I discussed in the previous one, because the later thread
got too busy with my numerous mistakes and wrong doings.
I would be grateful for deciphering bugs in the program.
The description of the program:
The program should take two arguments from command line:
the name of the program and the key word. The key word
is used to cipher the message typed in by the user.
If the user has typed in less, or more, then two arguments
into a command line, and/or the key word contains non-alphabetical
characters, the program should return 1, and quit.
Else, the program prompts the user for any text message.
Therefore the program should have two arguments to work with:
1) text message
2) key word
Based on vigenere cipher algorithm the program converts
original message into a ciphered one.
Here is an example:
the user types in: ./programname baz
// baz is a key word for the cipher
the user enters the message:
world, say hello!
(bazba zba zbazb) // this is how key word should be "distributed"
the program should convert this phrase to
'xoqmd, rby gflkp!'
by correctly computing the index; if there are non-alphabetical
characters in the message, the program prints them as they are, and
moves next letter of a key word commensurate to the next alphabetical
character of the message (skipping non-alphabetical ones).
The next_text function within this program should the following:
The for loop starts.
Checks if the character at i = 0 is a letter or another character.
If it is an alphabetical character, then:
- it assigns a value of a letter at the position i = 0 to variable letter
- if this letter is in upper case, then based on an index, received from
the function word_index, it computes the value of the new letter, and
assigns a new value to variable new_letter;
- same process if the letter is in lower case.
- prints out a new_letter
Else, it prints out a character as it is.
The process should go on until the for loop reaches the final character
in the original message.
The word_index function:
The for loop starts.
Checks if the character of the original text at i = 0 is an alphabetic
character, or some other character.
Only if it is an alphabetic letter, then:
- the program checks if a letter of the key word (key word typed in
at the command line) at position [i % length of the key word] is in upper or lower case;
- computes index [] according to the case of the letter (as described
above);
- returns the value of the index (later used in the algorithm
in new_text function).
Buggy Program:
//** Program to cipher the text based on vigenere algorithm **/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int is_word(const char *string);
int word_index(const char *text, const char *word);
void new_text(char text[], char key_word[]);
int main (int argc, char *argv[])
{
char message[80];
if (argc == 2)
{
if (is_word(argv[1])) /** if is_word returns 1, i.e. is TRUE, then
do the following; if is_word returns zero, then go
to else part **/
{
char *key = argv[1];
printf("Please, enter your message: \n");
if (fgets (message, sizeof message, stdin) != NULL)
{
new_text(message, key);
}
}
}
else
{
printf("\a");
printf("Please, provide one argument - a word\n");
return 1;
}
return 0;
}
int is_word(const char *string)
{
int word = 0;
if (string != NULL)
{
word = 1;
while(word != 0 && *string != '\0')
{
word = (isalpha(*string++)); /** the pointer refers to the address of the first
character, hence *string++ is used **/
/** if the string is not an alphabetical one, then
isalpha returns 0, the while loop terminates, and
the function returns 0 as the value of the word**/
}
}
return word;
}
int word_index(const char *text, const char *word)
{
int i, index;
int word_len = strlen(word);
int text_len = strlen(text);
for(i = 0; i < text_len; i++)
{
if (isalpha(text[i]))
{
if (islower(word[i % word_len]))
{
index = word[i % word_len] - 'a';
}
if (isupper(word[i % word_len]))
{
index = word[i % word_len] - 'A';
}
}
return index;
}
return -1;
}
void new_text(char text[], char key_word[])
{
int i;
int len = strlen(text);
char new_letter;
for (i = 0; i < len; i++)
{
if (isalpha (text[i]))
{
int letter = text[i];
if (islower (letter))
{
new_letter = (letter - 'a' + word_index(text, key_word)) % 26 + 'a';
}
if (isupper (letter))
{
new_letter = (letter - 'A' + word_index(text, key_word)) % 26 + 'A';
}
printf("%c", new_letter);
}
else
printf("%c", text[i]);
}
printf ("\n");
}
Thank you!
[toc] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-10-30 15:39 +0000 |
| Message-ID | <n102s8$2k6$1@dont-email.me> |
| In reply to | #74314 |
On 30/10/2015 15:23, Alla _ wrote: > The description of the program: > > The program should take two arguments from command line: > the name of the program This one usually isn't optional! and the key word. The key word > is used to cipher the message typed in by the user. > //** Program to cipher the text based on vigenere algorithm **/ <snip complicated C program> The problem here might be trying to develop and debug an algorithm, and learning enough C to do it at the same time. It is possible to split the two. For example, I used to 'cheat' by using the nearest easy language to hand to get the algorithm right. Once it works, /then/ write it in C. If it then doesn't work, you know it's a problem with writing the correct C, and not the algorithm which has been tested. But I guess not everyone will agree with this. (For the easy language, Python has been mentioned. But whichever it is, don't use its high level features to dispose of the problem in one line. Use low-level features such as arrays that will map directly to C. Of course, you will have to learn that other language too (and how to get around certain problems such as immutable strings), but it could be worthwhile.) -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-10-30 09:33 -0700 |
| Message-ID | <7dc73a44-e158-478e-a0ec-d183b953da99@googlegroups.com> |
| In reply to | #74322 |
On Friday, October 30, 2015 at 7:40:05 PM UTC+4, Bart wrote: > On 30/10/2015 15:23, Alla _ wrote: > > > The description of the program: > > > > The program should take two arguments from command line: > > the name of the program > > This one usually isn't optional! > > and the key word. The key word > > is used to cipher the message typed in by the user. > > > //** Program to cipher the text based on vigenere algorithm **/ > > <snip complicated C program> > > The problem here might be trying to develop and debug an algorithm, and > learning enough C to do it at the same time. > > It is possible to split the two. For example, I used to 'cheat' by using > the nearest easy language to hand to get the algorithm right. > > Once it works, /then/ write it in C. If it then doesn't work, you know > it's a problem with writing the correct C, and not the algorithm which > has been tested. > > But I guess not everyone will agree with this. > Sorry, I disagree, and have mentioned that elsewhere. Thank you for suggestion, but I am not switching to any other language.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-11-01 09:33 +0000 |
| Message-ID | <n14m5s$jpl$1@dont-email.me> |
| In reply to | #74322 |
On 30/10/15 15:39, Bartc wrote: > On 30/10/2015 15:23, Alla _ wrote: > >> The description of the program: >> >> The program should take two arguments from command line: >> the name of the program > > This one usually isn't optional! > > and the key word. The key word >> is used to cipher the message typed in by the user. > >> //** Program to cipher the text based on vigenere algorithm **/ > > <snip complicated C program> Hardly. > The problem here might be trying to develop and debug an algorithm, and > learning enough C to do it at the same time. Perhaps. > It is possible to split the two. For example, I used to 'cheat' by using > the nearest easy language to hand to get the algorithm right. You don't need a language (other than English or other natural language) for getting the algorithm right. > Once it works, /then/ write it in C. If it then doesn't work, you know > it's a problem with writing the correct C, and not the algorithm which > has been tested. Yes. > But I guess not everyone will agree with this. Up to a point, Lord Copper. > (For the easy language, Python has been mentioned. No, use English. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Mark Storkamp <mstorkamp@yahoo.com> |
|---|---|
| Date | 2015-10-30 11:17 -0500 |
| Message-ID | <mstorkamp-0C592B.11174330102015@88-209-239-213.giganet.hu> |
| In reply to | #74314 |
In article <8465675b-8538-4031-a5b7-d5ddba34197d@googlegroups.com>, Alla _ <modelling.data@gmail.com> wrote: > Hello! > > I have decided to start a new thread on the program > I discussed in the previous one, because the later thread > got too busy with my numerous mistakes and wrong doings. > > I would be grateful for deciphering bugs in the program. > > The description of the program: > > The program should take two arguments from command line: > the name of the program and the key word. The key word > is used to cipher the message typed in by the user. > > If the user has typed in less, or more, then two arguments > into a command line, and/or the key word contains non-alphabetical > characters, the program should return 1, and quit. > > Else, the program prompts the user for any text message. > > Therefore the program should have two arguments to work with: > 1) text message > 2) key word > You're not defining your problem very clearly. First you said "The program should take two arguments ... the name of the program and the key word." Then you said the "program should have two arguments ... text message ... key word" It is impossible to program something you don't understand. You need to clearly define what you want, what goes in, what comes out the other end, what happens when what you want isn't what you get, how to accomplish the task you set out to do &c. Only after you know just exactly what the program is expected to do should you even begin to write out the code. If you have to diagram it first, draw out a flow chart, make an outline ... do whatever works for you to break the problem down into steps you can manage, then work on each step until it is right.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-10-30 09:32 -0700 |
| Message-ID | <f7f6ae0f-3018-456a-8341-26056aecc2c7@googlegroups.com> |
| In reply to | #74335 |
On Friday, October 30, 2015 at 8:17:54 PM UTC+4, Mark Storkamp wrote: > In article <8465675b-8538-4031-a5b7-d5ddba34197d@googlegroups.com>, > Alla _ <modelling.data@gmail.com> wrote: > > > Hello! > > > > I have decided to start a new thread on the program > > I discussed in the previous one, because the later thread > > got too busy with my numerous mistakes and wrong doings. > > > > I would be grateful for deciphering bugs in the program. > > > > The description of the program: > > > > The program should take two arguments from command line: > > the name of the program and the key word. The key word > > is used to cipher the message typed in by the user. > > > > If the user has typed in less, or more, then two arguments > > into a command line, and/or the key word contains non-alphabetical > > characters, the program should return 1, and quit. > > > > Else, the program prompts the user for any text message. > > > > Therefore the program should have two arguments to work with: > > 1) text message > > 2) key word > > > > You're not defining your problem very clearly. > > First you said "The program should take two arguments ... the name of > the program and the key word." > > Then you said the "program should have two arguments ... text message > ... key word" > > It is impossible to program something you don't understand. You need to > clearly define what you want, what goes in, what comes out the other > end, what happens when what you want isn't what you get, how to > accomplish the task you set out to do &c. Only after you know just > exactly what the program is expected to do should you even begin to > write out the code. If you have to diagram it first, draw out a flow > chart, make an outline ... do whatever works for you to break the > problem down into steps you can manage, then work on each step until it > is right. You are absolutely right. But I do know what I want from the program, and it's been defined. I even had the program that almost did the correct thing, but I stumbled upon one problem which might be a math one - the way to correctly indicate the index to convert letters, in the case of my program depicted in the word_index function. I am sorry if I didn't produce a clear description. I also thought that vigenere cipher algorithm is one of the simplest algorithms, known to everyone who has ever learned programming. I did hope that the example I gave describes the way the program should work.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-11-01 09:38 +0000 |
| Message-ID | <n14me0$klo$1@dont-email.me> |
| In reply to | #74340 |
On 30/10/15 16:32, Alla _ wrote: > On Friday, October 30, 2015 at 8:17:54 PM UTC+4, Mark Storkamp wrote: >> In article <8465675b-8538-4031-a5b7-d5ddba34197d@googlegroups.com>, >> Alla _ <modelling.data@gmail.com> wrote: >> >>> Hello! >>> >>> I have decided to start a new thread on the program >>> I discussed in the previous one, because the later thread >>> got too busy with my numerous mistakes and wrong doings. >>> >>> I would be grateful for deciphering bugs in the program. >>> >>> The description of the program: >>> >>> The program should take two arguments from command line: >>> the name of the program and the key word. The key word >>> is used to cipher the message typed in by the user. >>> >>> If the user has typed in less, or more, then two arguments >>> into a command line, and/or the key word contains non-alphabetical >>> characters, the program should return 1, and quit. >>> >>> Else, the program prompts the user for any text message. >>> >>> Therefore the program should have two arguments to work with: >>> 1) text message >>> 2) key word >>> >> >> You're not defining your problem very clearly. >> >> First you said "The program should take two arguments ... the name of >> the program and the key word." >> >> Then you said the "program should have two arguments ... text message >> ... key word" >> >> It is impossible to program something you don't understand. You need to >> clearly define what you want, what goes in, what comes out the other >> end, what happens when what you want isn't what you get, how to >> accomplish the task you set out to do &c. Only after you know just >> exactly what the program is expected to do should you even begin to >> write out the code. If you have to diagram it first, draw out a flow >> chart, make an outline ... do whatever works for you to break the >> problem down into steps you can manage, then work on each step until it >> is right. > > You are absolutely right. But I do know what I want from the program, > and it's been defined. You're missing his point. The definition was self-contradicting - the program's two arguments should be the name of the program and the keyword AND the program's two arguments should be the text message and the keyword. You can't have both of these being true (unless you expect the user to rename the program every time they want to send a new message!) > I even had the program that almost did the correct > thing, but I stumbled upon one problem which might be a math one - the way > to correctly indicate the index to convert letters, in the case of my program > depicted in the word_index function. Well, that's why you need a clear definition of the problem. It's also why you need a clear definition of each function. > I am sorry if I didn't produce a clear description. That is mostly for your benefit, not ours. > I also thought that vigenere cipher algorithm > is one of the simplest algorithms, known to > everyone who has ever learned programming. There are people here who can write a Vigenere encrypter/decrypter in their sleep. They are encouraging you to produce a clear description not for their benefit but for your own. > I did hope that the example I gave describes the way the program should work. If it is self-contradictory, how can it? -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | "Osmium" <r124c4u102@comcast.net> |
|---|---|
| Date | 2015-10-30 10:55 -0600 |
| Message-ID | <d9hlo7F4tr6U1@mid.individual.net> |
| In reply to | #74314 |
"Alla _" wrote: > I have decided to start a new thread on the program > I discussed in the previous one, because the later thread > got too busy with my numerous mistakes and wrong doings. > > I would be grateful for deciphering bugs in the program. > > The description of the program: > > The program should take two arguments from command line: > the name of the program and the key word. The key word > is used to cipher the message typed in by the user. > > If the user has typed in less, or more, then two arguments > into a command line, and/or the key word contains non-alphabetical > characters, the program should return 1, and quit. > > Else, the program prompts the user for any text message. > > Therefore the program should have two arguments to work with: > 1) text message > 2) key word > > Based on vigenere cipher algorithm the program converts > original message into a ciphered one. <snip> If your problems are severe enough that you feel a need for help, I suggest you reduce this to a simpler problem and work, with that as a base, to a final solution. I don't like the idea of two kinds of characters. Require the input to be lower-case letters only, no punctuation. Discard the spaces or replace them with 'x' as the Germans did in Enigma.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-11-01 10:07 +0000 |
| Message-ID | <n14o50$qqb$1@dont-email.me> |
| In reply to | #74343 |
On 30/10/15 16:55, Osmium wrote:
> "Alla _" wrote:
>
>> I have decided to start a new thread on the program
>> I discussed in the previous one, because the later thread
>> got too busy with my numerous mistakes and wrong doings.
>>
>> I would be grateful for deciphering bugs in the program.
>>
>> The description of the program:
>>
>> The program should take two arguments from command line:
>> the name of the program and the key word. The key word
>> is used to cipher the message typed in by the user.
>>
>> If the user has typed in less, or more, then two arguments
>> into a command line, and/or the key word contains non-alphabetical
>> characters, the program should return 1, and quit.
>>
>> Else, the program prompts the user for any text message.
>>
>> Therefore the program should have two arguments to work with:
>> 1) text message
>> 2) key word
>>
>> Based on vigenere cipher algorithm the program converts
>> original message into a ciphered one.
> <snip>
>
> If your problems are severe enough that you feel a need for help, I
> suggest you reduce this to a simpler problem and work, with that as a
> base, to a final solution. I don't like the idea of two kinds of
> characters. Require the input to be lower-case letters only, no
> punctuation. Discard the spaces or replace them with 'x' as the Germans
> did in Enigma.
I can easily imagine the Vigenere cipher's original users being
case-blind - that is, not actually making any distinction between upper
and lower case either in the keyword or in the message text. I can
equally imagine them skipping punctuation - that is, duplicating it
without consuming key material.
Even with these apparent complications, it is not a difficult problem,
and neither is Alla's code particularly complicated - which is not to
say that it could not be simplified.
The first step I would take towards simplifying the implementation is to
record the case of an input character, and thereafter do everything in
lower case, translating back at the end if need be.
This massively simplifies the whole business of calculating indices and
offsets, as can be seen here:
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
size_t az_to_index(int ch);
int index_to_az(size_t idx);
void vig(const char *key);
/* Given a letter of the alphabet, return its index */
size_t az_to_index(int ch)
{
const char *az = "abcdefghijklmnopqrstuvwxyz";
assert(isalpha(ch));
return strchr(az, ch) - az;
}
/* Given a number of the alphabet, return its letter */
int index_to_az(size_t idx)
{
const char *az = "abcdefghijklmnopqrstuvwxyz";
assert(idx < 26);
return az[idx];
}
/* Perform Vigenere encipherment of stdin */
void vig(const char *key)
{
size_t klen = strlen(key);
size_t k = 0;
size_t kpos = 0;
int ch = 0;
int ct = 0;
while((ch = getchar()) != EOF)
{
if(isalpha((unsigned char)ch))
{
int upch = isupper(ch);
k = az_to_index(tolower(key[kpos++]));
if(kpos == klen)
{
kpos = 0;
}
ct = index_to_az((k + az_to_index(tolower(ch))) % 26);
if(upch)
{
ct = toupper(ct);
}
putchar(ct);
}
else
{
putchar(ch);
}
}
}
int main(int argc, char **argv)
{
if(argc--)
{
vig(argv[argc]);
}
return 0;
}
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-01 10:42 +0000 |
| Message-ID | <87wpu26lwx.fsf@bsb.me.uk> |
| In reply to | #74532 |
Richard Heathfield <rjh@cpax.org.uk> writes:
<snip>
> #include <ctype.h>
> #include <string.h>
> #include <stdio.h>
> #include <assert.h>
>
> size_t az_to_index(int ch);
> int index_to_az(size_t idx);
> void vig(const char *key);
>
> /* Given a letter of the alphabet, return its index */
> size_t az_to_index(int ch)
> {
> const char *az = "abcdefghijklmnopqrstuvwxyz";
> assert(isalpha(ch));
That looks like an odd assert. Why not assert(islower(ch)) or even
assert(strchr(az, ch))?
> return strchr(az, ch) - az;
> }
>
> /* Given a number of the alphabet, return its letter */
> int index_to_az(size_t idx)
> {
> const char *az = "abcdefghijklmnopqrstuvwxyz";
> assert(idx < 26);
> return az[idx];
> }
>
> /* Perform Vigenere encipherment of stdin */
> void vig(const char *key)
> {
> size_t klen = strlen(key);
> size_t k = 0;
> size_t kpos = 0;
> int ch = 0;
> int ct = 0;
> while((ch = getchar()) != EOF)
> {
> if(isalpha((unsigned char)ch))
You don't need the cast here...
> {
> int upch = isupper(ch);
> k = az_to_index(tolower(key[kpos++]));
... but you do need one here.
Also, it's odd (to me) to see upch declared here when k and ct are "out
there". It's probably just due to how the program changed over time,
but it's more helpful to the reader to a have uniform rule.
> if(kpos == klen)
> {
> kpos = 0;
> }
> ct = index_to_az((k + az_to_index(tolower(ch))) % 26);
> if(upch)
> {
> ct = toupper(ct);
> }
> putchar(ct);
> }
> else
> {
> putchar(ch);
> }
> }
> }
>
> int main(int argc, char **argv)
> {
> if(argc--)
> {
> vig(argv[argc]);
Your version does not check that the key is valid (I'm assuming you did
not intend to use assert to check user input).
> }
> return 0;
> }
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-11-01 11:35 +0000 |
| Message-ID | <n14t9j$e1q$1@dont-email.me> |
| In reply to | #74533 |
[Alla - I hope you're watching. I did everything right:
(a) I thought quite hard about the code before writing it;
(b) I actually compiled the code, and took notice of what the compiler
told me about it (which resulted in several changes);
(c) I tried out the program to make sure it did what it is supposed to do;
(d) *THEN* I posted the code to Usenet.
And then Ben managed to find not one, but *four*, problems with the
code. EVEN THOUGH I thought I'd taken some care to write it properly.
Lesson: peer review is really, really important.]
Okay, Ben, let's get on with the torture:
On 01/11/15 10:42, Ben Bacarisse wrote:
> Richard Heathfield <rjh@cpax.org.uk> writes:
> <snip>
>> #include <ctype.h>
>> #include <string.h>
>> #include <stdio.h>
>> #include <assert.h>
>>
>> size_t az_to_index(int ch);
>> int index_to_az(size_t idx);
>> void vig(const char *key);
>>
>> /* Given a letter of the alphabet, return its index */
>> size_t az_to_index(int ch)
>> {
>> const char *az = "abcdefghijklmnopqrstuvwxyz";
>> assert(isalpha(ch));
>
> That looks like an odd assert. Why not assert(islower(ch)) or even
> assert(strchr(az, ch))?
For the excellent reason that I didn't think it through for more than
about half a second.
>> while((ch = getchar()) != EOF)
>> {
>> if(isalpha((unsigned char)ch))
>
> You don't need the cast here...
Actually, rather to my surprise, you're right. This is because ch comes
from getchar(), which is defined in terms of getc, which is defined in
terms of fgetc, which is defined to return a character as an unsigned
char converted to an int. That's yet another cast I can consign to the
dustbin (although only because of the particular knowledge we have of
the origin of ch).
>> {
>> int upch = isupper(ch);
>> k = az_to_index(tolower(key[kpos++]));
>
> ... but you do need one here.
Fortunately, I have just acquired a spare.
> Also, it's odd (to me) to see upch declared here when k and ct are "out
> there". It's probably just due to how the program changed over time,
> but it's more helpful to the reader to a have uniform rule.
I like "over time". :-) No, it was just my usual failure to plan ahea
d. "I'll need this, that, the other, and of course a foo and a bar."
Later: "Whoops, I need a baz, too. Oh well, that can go here..."
>> if(kpos == klen)
>> {
>> kpos = 0;
>> }
>> ct = index_to_az((k + az_to_index(tolower(ch))) % 26);
>> if(upch)
>> {
>> ct = toupper(ct);
>> }
>> putchar(ct);
>> }
>> else
>> {
>> putchar(ch);
>> }
>> }
>> }
>>
>> int main(int argc, char **argv)
>> {
>> if(argc--)
>> {
>> vig(argv[argc]);
>
> Your version does not check that the key is valid
That was, I think, the most serious problem. What is required here is a
simple loop:
int key_is_valid(const char *k)
{
int valid = 0;
if(k != NULL)
{
valid = 1;
while(valid && *k)
{
valid = isalpha((unsigned char)*k);
++k;
}
}
return valid;
}
(Yes, I think I'm right in saying the cast is required here because k
comes from argv[1], the elements of which are not guaranteed to be
representable as unsigned char.)
> (I'm assuming you did
> not intend to use assert to check user input).
You are assuming right.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-11-01 08:33 -0500 |
| Message-ID | <n15479$8p4$1@dont-email.me> |
| In reply to | #74539 |
On 11/01/2015 06:35 AM, Richard Heathfield wrote:
...
> On 01/11/15 10:42, Ben Bacarisse wrote:
>> Richard Heathfield <rjh@cpax.org.uk> writes:
...
>>> while((ch = getchar()) != EOF)
>>> {
>>> if(isalpha((unsigned char)ch))
>>
>> You don't need the cast here...
>
> Actually, rather to my surprise, you're right. This is because ch comes
> from getchar(), which is defined in terms of getc, which is defined in
> terms of fgetc, which is defined to return a character as an unsigned
> char converted to an int. That's yet another cast I can consign to the
> dustbin (although only because of the particular knowledge we have of
> the origin of ch).
Yes - needing to convert to unsigned char is one of the poor design
features of the <ctype.h> functions, but it actually works conveniently
in combination with fgetc() and family - I suspect that's deliberate.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-01 16:09 +0000 |
| Message-ID | <87io5l7lbh.fsf@bsb.me.uk> |
| In reply to | #74539 |
Richard Heathfield <rjh@cpax.org.uk> writes:
> [Alla - I hope you're watching. I did everything right:
>
> (a) I thought quite hard about the code before writing it;
> (b) I actually compiled the code, and took notice of what the compiler
> told me about it (which resulted in several changes);
> (c) I tried out the program to make sure it did what it is supposed to do;
> (d) *THEN* I posted the code to Usenet.
>
> And then Ben managed to find not one, but *four*, problems with the
> code. EVEN THOUGH I thought I'd taken some care to write it properly.
And my version also had a bug. A lot if the issues in both cases were
to do with the quirks of C. I'll bet that given a better language we'd
have got a correct result first time.
I've just had a go in Haskell it seemed very simple. The only language
irritation comes form the fact the Haskell assumes Unicode and so has
limited support for ASCII tests. I needed a one-line isAsciiAlpha
function for simplicity.
Interestingly, the Haskell version is as fast as my C version though it
has the advantage of being able to assume ASCII input, so it's not
really a fair comparison. You also get, for free, so to speak, a
function that operates on a string along with a main program that
operates on its input. Haskell can process the input as a
lazy-evaluated string, so there is no need write it as a
character-by-character filer just to get the effect of a filer.
It's off-topic, but here it is for the sake of completeness. Complain
about the style on comp.lang.haskell.
import System.IO
import Data.Char
import System.Environment
main = do
args <- getArgs
if length args == 1 && all isAsciiAlpha (head args) && head args /= ""
then do
content <- getContents
putStr (encode (head args) content)
else do
hPutStrLn stderr "One keyword argument, please."
encode key str = apply offsets [] str
where offsets = map ((-ord 'a' +) . ord . toLower) key
apply _ _ [] = []
apply offsets [] str = apply offsets offsets str
apply offsets (o:os) (c:cs)
| isAsciiLower c = offset 'a' o c : apply offsets os cs
| isAsciiUpper c = offset 'A' o c : apply offsets os cs
| otherwise = c : apply offsets (o:os) cs
offset base n c = chr ((if nc >= 26 then nc - 26 else nc) + ord base)
where nc = ord c - ord base + n
isAsciiAlpha c = isAsciiLower c || isAsciiUpper c
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-11-02 12:43 +0000 |
| Message-ID | <n17lkq$kq5$1@dont-email.me> |
| In reply to | #74565 |
On 01/11/2015 16:09, Ben Bacarisse wrote: > I've just had a go in Haskell it seemed very simple. The only language > irritation comes form the fact the Haskell assumes Unicode and so has > limited support for ASCII tests. I needed a one-line isAsciiAlpha > function for simplicity. > > Interestingly, the Haskell version is as fast as my C version though it > has the advantage of being able to assume ASCII input Why can it assume ASCII but the C version can't? Does Haskell only work with Unicode? (ASCII is a subset of Unicode.) > It's off-topic, but here it is for the sake of completeness. Complain > about the style on comp.lang.haskell. > main = do > args <- getArgs <snip Haskell code> I couldn't really follow the Haskell code. I had a go using my own simple scripting language. It's not as compact or clever, but I believe it reads easily enough even for someone not familiar with it. This version is character-stream based to match your versions. (For fun, it even uses one or two C functions directly.) http://pastebin.com/GSudDwLg -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-02 13:25 +0000 |
| Message-ID | <874mh45y9n.fsf@bsb.me.uk> |
| In reply to | #74638 |
Bartc <bc@freeuk.com> writes: > On 01/11/2015 16:09, Ben Bacarisse wrote: > >> I've just had a go in Haskell it seemed very simple. The only language >> irritation comes form the fact the Haskell assumes Unicode and so has >> limited support for ASCII tests. I needed a one-line isAsciiAlpha >> function for simplicity. >> >> Interestingly, the Haskell version is as fast as my C version though it >> has the advantage of being able to assume ASCII input > > Why can it assume ASCII but the C version can't? Does Haskell only > work with Unicode? (ASCII is a subset of Unicode.) The C version *could*, it just so happens that the version I wrote does not. Haskell uses UTF-8 input by default (at least on my system) so it was simplest just to go with that. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-11-02 06:13 -0800 |
| Message-ID | <38c531eb-2d2e-4f49-85f2-062fd01fab19@googlegroups.com> |
| In reply to | #74638 |
On Monday, November 2, 2015 at 12:43:22 PM UTC, Bart wrote: > On 01/11/2015 16:09, Ben Bacarisse wrote: > > I couldn't really follow the Haskell code. > > I had a go using my own simple scripting language. It's not as compact > or clever, but I believe it reads easily enough even for someone not > familiar with it. > No, that's the problem with functional languages. They're easier for the machine to follow, but harder for a human, especially if he's familiar with procedural languages. A procedural script in an unfamiliar but not eccentric language is usually quite straightforwards to modify and debug. If + is string concatenation, you can usually work it out from context, ditto if it's something else.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-01 12:26 -0800 |
| Message-ID | <lnmvux79fg.fsf@kst-u.example.com> |
| In reply to | #74539 |
Richard Heathfield <rjh@cpax.org.uk> writes:
[...]
> On 01/11/15 10:42, Ben Bacarisse wrote:
>> Richard Heathfield <rjh@cpax.org.uk> writes:
[...]
>>> while((ch = getchar()) != EOF)
>>> {
>>> if(isalpha((unsigned char)ch))
>>
>> You don't need the cast here...
>
> Actually, rather to my surprise, you're right. This is because ch comes
> from getchar(), which is defined in terms of getc, which is defined in
> terms of fgetc, which is defined to return a character as an unsigned
> char converted to an int. That's yet another cast I can consign to the
> dustbin (although only because of the particular knowledge we have of
> the origin of ch).
[...]
A key insight is that ch is of type int.
If ch were of type char, we'd have to assume that it might contain
a negative value, particularly if it came from user input or from
a command-line argument. If a character value is stored in an int
object *and* we haven't done anything silly, we can assume it's
a non-negative value within the range of unsigned char (or EOF,
but we've already checked that). (Copying a char value to an int
object would qualify as doing something silly.)
A consistent way to handle this is to follow these rules:
- A char argument to is*() or to*() must be cast to unsigned int.
- An int argument need not be cast.
- Important: If you store a character value in an int, it must be in the
range 0..UCHAR_MAX, for example if it's the result of calling
getchar(). Don't copy a character from a string into an int object.
Oddly, this would have been clearer to me if it had been named "c"
rather than "ch", since the common idiom is
while ((c = getchar()) != EOF) ...
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-01 07:59 -0800 |
| Message-ID | <318982b5-b8e6-4cfc-ad08-79cc99a2b162@googlegroups.com> |
| In reply to | #74532 |
On Sunday, November 1, 2015 at 4:07:44 AM UTC-6, Richard Heathfield wrote: > I can easily imagine the Vigenere cipher's original users being > case-blind - that is, not actually making any distinction between upper > and lower case either in the keyword or in the message text. I can > equally imagine them skipping punctuation - that is, duplicating it > without consuming key material. From what I understand, common cryptographic practice was to strip out all punctuation and word spaces, see if the message made sense, if it didn't either rewrite it and/or add some obvious "noise characters" like Q or X to imply word breaks, then encipher the message and add word breaks at regular intervals. Preserving original word spaces and punctuation would give excessively strong clues as to the message content, which could not only assist in deciphering it, but could even allow the enemy to glean information *without* deciphering it.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-11-02 13:48 +0000 |
| Message-ID | <n17pfa$2lr$1@dont-email.me> |
| In reply to | #74563 |
On 01/11/15 15:59, supercat@casperkitty.com wrote: > On Sunday, November 1, 2015 at 4:07:44 AM UTC-6, Richard Heathfield wrote: >> I can easily imagine the Vigenere cipher's original users being >> case-blind - that is, not actually making any distinction between upper >> and lower case either in the keyword or in the message text. I can >> equally imagine them skipping punctuation - that is, duplicating it >> without consuming key material. > > From what I understand, common cryptographic practice was to strip out all > punctuation and word spaces, see if the message made sense, if it didn't > either rewrite it and/or add some obvious "noise characters" like Q or X > to imply word breaks, then encipher the message and add word breaks at > regular intervals. Preserving original word spaces and punctuation would > give excessively strong clues as to the message content, which could not > only assist in deciphering it, but could even allow the enemy to glean > information *without* deciphering it. Whether most users would have been that cautious, knowing as they did that the cipher was unbreakable, is probably an open question. One thing that is not an open question, though, is the fact that Vigenere has been broken, and no sensible person relies on it for security nowadays. Therefore, we may safely assume that any Vigenere program written today is for educational (or home entertainment) purposes, and we therefore don't have to get too snarled up on the details. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-11-02 14:06 +0000 |
| Message-ID | <n17qhs$7o1$1@dont-email.me> |
| In reply to | #74640 |
On 02/11/2015 13:48, Richard Heathfield wrote: > On 01/11/15 15:59, supercat@casperkitty.com wrote: >> From what I understand, common cryptographic practice was to strip >> out all >> punctuation and word spaces, see if the message made sense, if it didn't >> either rewrite it and/or add some obvious "noise characters" like Q or X >> to imply word breaks, then encipher the message and add word breaks at >> regular intervals. Preserving original word spaces and punctuation would >> give excessively strong clues as to the message content, which could not >> only assist in deciphering it, but could even allow the enemy to glean >> information *without* deciphering it. > > > Whether most users would have been that cautious, knowing as they did > that the cipher was unbreakable, is probably an open question. It wouldn't have taken long to discover that, if the encryption preserves spaces, it is sometimes possible to guess what the words might be from the 'shape' of the sentences. Here's a couple of examples, with clues to help out: XXXXX XXXXX (70s pop star; from a Hangman game) X XXXXXXX XX XXXXX (Book and film; from a crossword) You can regard the Xs as a tough form of cipher where any letter maps to 'X'. -- Xxxxx
[toc] | [prev] | [next] | [standalone]
Page 1 of 4 [1] 2 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web