[crosspost] Perl -> C

P

Piotr Turkowski

Hi!
I've got some code in Perl and I have to have it in C, but my knowlege
of Perl is < 0 :-(, so I need your help. here's the code. Thanks in advance.

decrypt.pl

#!/usr/local/bin/perl
$keyword=$ARGV[0] ;
@key=split(//,$keyword) ;
$period=length($keyword) ;
$count=0 ;
while(<STDIN>) {
chop ;
tr/a-z/A-Z/ ;
tr/A-Z//cd ;
@line=split(//) ;
foreach $i (@line) {
$cipher=ord($i)-ord($key[$count % $period])+65;
if ($cipher<65) {$cipher+=26 ; }
print pack("C",$cipher) ;
$count+=1 ;
if ($count % 5 == 0) {print " ";}
}
print "\n" ;
}
print "\n" ;


and encrypt.pl

#!/usr/local/bin/perl
$keyword=$ARGV[0] ;
$keyword=~tr/a-z/A-Z/ ;
@key=split(//,$keyword) ;
$period=length($keyword) ;
$count=0 ;
while(<STDIN>) {
chop ;
tr/a-z/A-Z/ ;
tr/A-Z//cd ;
@line=split(//) ;
foreach $i (@line) {
$cipher=ord($i)+ord($key[$count % $period])-65;
if ($cipher>=91) {$cipher-=26 ; }
print pack("C",$cipher) ;
$count+=1 ;
if ($count % 5 == 0) {print " ";}
if ($count %60 == 0) {print "\n" ; }
}
}
print "\n" ;
 
M

Mike Wahler

Piotr Turkowski said:
Hi!
I've got some code in Perl and I have to have it in C, but my knowlege
of Perl is < 0 :-(, so I need your help. here's the code. Thanks in advance.

decrypt.pl

[snip code]

Well, Perl's OT in c.l.c., and C's OT in c.l.p., so
what's a body to do?? :)

I suggest you ask someone in the Perl group to explain
in English what the Perl code does, then you can write
the C code from the English specification. If you get
stuck, post the functional description to the C group
along with your code, and we can offer ideas and suggestions,
etc.

HTH,
-Mike
 
P

Piotr Turkowski

U¿ytkownik Mike Wahler napisa³:
Well, Perl's OT in c.l.c., and C's OT in c.l.p., so
what's a body to do?? :)

And this is the very true truth :) (sorry for my Engilsh ;-)
I suggest you ask someone in the Perl group to explain
in English what the Perl code does, then you can write
the C code from the English specification. If you get
stuck, post the functional description to the C group
along with your code, and we can offer ideas and suggestions,
etc.

OK, so here is what i want to create.
1. Text editor with GUI, which would have an opportunity to
encypt/decrypt text with Vigerene Cipher.
2. Options: saving/opening files :)
3. New file type: *.vig (encrypted file)
4. Two langauge program (polish/english) I can translate it :D
5. Changing font, size of text, just for display (you know what i mean)
*6. Registration form. Shareware, or sth. Someone send me his 'name' i
generate 'key' and then program is fully functionally. If not, the
program can encrypt/decrypt only 20 chars, and can't save and open
encrypted file.

*at the end


So, I'm a real noob. I don't want you to write this program, I just need
your help :). So guide me, what I shuold create at the beggining. Mayby
some examples of text editor ?

best regards
Peter
 
A

Arthur J. O'Dwyer

U¿ytkownik Mike Wahler napisa³:

OK, so here is what i want to create.
1. Text editor with GUI, which would have an opportunity to
encypt/decrypt text with Vigerene Cipher.

Writing full-screen editors or other GUIs is off-topic in this
newsgroup, where we discuss standard C only. Standard C has no
support for GUIs or screen manipulation. (And probably off-topic
in comp.lang.perl, too, but I don't read that group.)
As for Vigenere solvers, you can search Google or Google Groups
for C source code. J.W. Stumpel wrote some decent Vigenere code
a while back, for instance. Given an encrypted text, it returns
its best guess as to the key and the original plaintext. If you
want help *writing* a Vigenere program, ask in comp.programming
or sci.crypt. If you want help *understanding* Stumpel's code,
or anyone else's C code, *then* c.l.c will be happy to help you.
2. Options: saving/opening files :)

This is topical here; look up 'fopen' and 'fprintf' in the
standard C library.
3. New file type: *.vig (encrypted file)

Most operating systems let you call your files whatever you
want. The details of your particular OS are off-topic in
comp.lang.c, which discusses a programming language, not an OS.
4. Two langauge program (polish/english) I can translate it :D

Polish, as it uses a different alphabet (and one not actually
guaranteed to get much support from the C language), might require
a bit of work. But not too much.
5. Changing font, size of text, just for display (you know what i mean)

Not really. "Font" in a program that deals with encryption and
decryption of text? What possible use could that serve?
*6. Registration form. Shareware, or sth. Someone send me his 'name' i
generate 'key' and then program is fully functionally. If not, the
program can encrypt/decrypt only 20 chars, and can't save and open
encrypted file.

IMNSHO, if you can't write your program on your own, without coming
to Usenet for spoon-feeding, you don't deserve to get any money for
the final product (as it won't be *yours*, but belong to whoever
actually wrote the relevant code in the first place). Anyway,
philosophical objections aside, nobody is going to pay for a program
they can get for free anyway, unless you're planning to sell technical
support for the Vigenere cipher. :-D
So, I'm a real noob. I don't want you to write this program, I just need
your help :). So guide me, what I shuold create at the beggining. Mayby
some examples of text editor ?

pico, vim, emacs. In fact, although it's off-topic here, I bet
there's a way to add a "mod" to emacs so that it can do Vigenere
ciphering on its own. I'm sure a Polish version of emacs already
exists, probably even with a spell-checker and all those bells and
whistles. Try a group devoted to emacs (possibly in the gnu.*
hierarchy?).

-Arthur
 
M

Mike Wahler

Arthur J. O'Dwyer said:
pico, vim, emacs. In fact, although it's off-topic here, I bet
there's a way to add a "mod" to emacs so that it can do Vigenere
ciphering on its own. I'm sure a Polish version of emacs already
exists, probably even with a spell-checker and all those bells and
whistles.

I once tried to whistle in Polish. A horrible sound. My dogs ran away.
I suppose I need more practice. :)

-Mike
 
C

CBFalconer

Mike said:
Piotr Turkowski said:
I've got some code in Perl and I have to have it in C, but my
knowlege of Perl is < 0 :-(, so I need your help. here's the
code. Thanks in advance.

[snip code]

Well, Perl's OT in c.l.c., and C's OT in c.l.p., so
what's a body to do?? :)

Maybe go somewhere more tolerant, such as comp.programming.
 
P

Piotr Turkowski

U¿ytkownik Arthur J. O'Dwyer napisa³:
As for Vigenere solvers, you can search Google or Google Groups
for C source code. J.W. Stumpel wrote some decent Vigenere code
a while back, for instance. Given an encrypted text, it returns
its best guess as to the key and the original plaintext. If you
want help *writing* a Vigenere program, ask in comp.programming
or sci.crypt. If you want help *understanding* Stumpel's code,
or anyone else's C code, *then* c.l.c will be happy to help you.

I have found some codes, but many of them were too complicated for me.
16KB of code, where it could be 2KB. I got the general idea of this,
code, but i have no idea to wrtie 26 alphabets in C, and tell the
program to use them :-/
This is topical here; look up 'fopen' and 'fprintf' in the
standard C library.

Yes, I have red about that in Kerningham (ANSI C).
Most operating systems let you call your files whatever you
want. The details of your particular OS are off-topic in
comp.lang.c, which discusses a programming language, not an OS.

Got it.
Polish, as it uses a different alphabet (and one not actually
guaranteed to get much support from the C language), might require
a bit of work. But not too much.

I was thinking about putting all captions to a file, and program will
read them from the file, so i could change the file, e.g. polish.xml,
english.xml
Not really. "Font" in a program that deals with encryption and
decryption of text? What possible use could that serve?

I still would be only txt nothing more (rtf or sth). I want option for
personalizing display of the notepad. Just like in our simple notepad or
KEdit.
IMNSHO, if you can't write your program on your own, without coming
to Usenet for spoon-feeding, you don't deserve to get any money for
the final product (as it won't be *yours*, but belong to whoever
actually wrote the relevant code in the first place). Anyway,
philosophical objections aside, nobody is going to pay for a program
they can get for free anyway, unless you're planning to sell technical
support for the Vigenere cipher. :-D

We have something like Allegro.pl (your e-bay.com), and people are
selling there programs for taking colour from the bitmap in hex
(#RRGGBB). And actually there are a lot of free programs doing the same :)
pico, vim, emacs. In fact, although it's off-topic here, I bet
there's a way to add a "mod" to emacs so that it can do Vigenere
ciphering on its own. I'm sure a Polish version of emacs already
exists, probably even with a spell-checker and all those bells and
whistles. Try a group devoted to emacs (possibly in the gnu.*
hierarchy?).

Checking..... hmm pico was not found n my computer, my emacs is also in
english, and vim has no vigenere cipher.

So If you can help me with understanding code, here's the code.

/*

Compile it with GCC:
gcc vig.c -o vigenere
Execute it:
vigenere < input_file
Where the first line in the input_file must contain the key (which
length is minor of MAXKEYLENGTH) and the other lines may contain the plain
text that you would like to encrypt. Note that this sample program only
handles lowercase inputs.

*/

#include <stdio.h>

#define MAXKEYLENGTH 20 /* maximum length of the key */
char key[MAXKEYLENGTH+1]; /* encipherment key */
int keylength = 0; /* length of the used key */

FILE *fp; /* set to stdin if interactive, else file */

void getkeyfromfile(void)
{
char *tmp = key; /* pointer to key array */
for (keylength=0; keylength < MAXKEYLENGTH; keylength++)
if ((key[keylength]= getc(fp)) == '\n') break;
}

int encipher(int i) /* key position */
{
int tmp; /* for cipher char calculation */
char currentchar; /* current charachter */

currentchar = getc(fp);
if (currentchar >= 'a' && currentchar <= 'z')
{
tmp = (currentchar + key - 2*'a') % 26;
while (tmp < 0) tmp += 26;
tmp += 'a';
}
else
tmp = currentchar; /* if not alphabetic return unchanged */
return(tmp);
}

void vigenere(void)
{
int current, i=0; /* cipher character */

while (!feof(fp))
{
current = encipher(i); /* generate encrypted character */
if (current < 'a' || current > 'z')
{
putchar(' '); /* do a space */
continue; /* if not an alphabetic lowercase */
}

if (i == keylength-1) /* end of the key? */
i=0;
else
i++;
putchar(current);
}
putchar('\n');
}

void main(void)
{
fp = stdin;
getkeyfromfile();
vigenere();
}


It's not working, check yourself.
 
D

Dave Thompson

/*

Compile it with GCC:
gcc vig.c -o vigenere
Execute it:
vigenere < input_file
Where the first line in the input_file must contain the key (which
length is minor of MAXKEYLENGTH) and the other lines may contain the plain

In English we say "whose length", or "the length of which", "is less
than" or "is less than or equal to" MAXKEYLENGTH, or in the latter
case (which is the case for your program) "is not greater than" or
"does not exceed".
text that you would like to encrypt. Note that this sample program only
handles lowercase inputs.
which could be easily fixed, BTW; see below. It is more traditional in
classical cryptography to use only *upper*case -- and for that matter
in many of the communications technologies with which classical crypto
was associated, like radio and cable telegraphy.
*/

#include <stdio.h>

#define MAXKEYLENGTH 20 /* maximum length of the key */
char key[MAXKEYLENGTH+1]; /* encipherment key */
int keylength = 0; /* length of the used key */

FILE *fp; /* set to stdin if interactive, else file */

void getkeyfromfile(void)
{
char *tmp = key; /* pointer to key array */

which is not used for anything, nor needed
for (keylength=0; keylength < MAXKEYLENGTH; keylength++)
if ((key[keylength]= getc(fp)) == '\n') break;

Doesn't check for, nor correctly handle, the case where the file does
not contain any newline (which is possible on some systems but not
all) AND is shorter than MAXKEYLENGTH. That may not matter to you.
}

int encipher(int i) /* key position */
{
int tmp; /* for cipher char calculation */
char currentchar; /* current charachter */
Should be int as EOF can't safely (portably) be stored in char (see
below) and will be promoted to int in the computations below anyway.
currentchar = getc(fp);

It's (to me unaesthetically) asymmetric for this routine to do the
input but not the output. Given the difficulty of correctly handling
EOF (see below) I would suggest doing the input in the caller, namely
main(), and passing the input pt character to this function as well as
having it return the ct character to main which does the output.
if (currentchar >= 'a' && currentchar <= 'z')

C doesn't guarantee that the codes for letters are consecutive, as in
ASCII et seq, or even ascending. But it's a bit more work to handle
this completely portably, so for a first cut you might not. Note that
folding cases (your previous Perl code folded to uppercase) would be
easy; in ASCII just &~0x20 (or |0x20 to lower), and portably just use
{
tmp = (currentchar + key - 2*'a') % 26;
while (tmp < 0) tmp += 26;


Not needed; the enciphered value will always be >= 0 and the % 26 will
always be in the correct range. You could use *instead of* % 26
if /* only once */ (tmp >= 26) tmp -= 26;
It is in the *deciphering* direction that you need
if /* only once */ (tmp < 0) tmp += 26;

I believe it's traditional for Vigenere to make key A +1 and Z +26 =
+0 = plain, partly because A occurs much more often than Z in manually
chosen and remembered keys, not +0 and +25 as your Perl and C code
(consistent with each other) do. This would be easy to change.
tmp += 'a';
}
else
tmp = currentchar; /* if not alphabetic return unchanged */
return(tmp);
}

void vigenere(void)
{
int current, i=0; /* cipher character */

while (!feof(fp))
{

Unlike some other languages, in C EOF is reported only *after* an
attempt to read past the end of file, so this continues to encipher a
garbage value, namely (char)EOF, after the end of actual data; and
feof() doesn't become true at all if input is terminated by an error,
in which case your program becomes an infinite garbage source.

The simplest and usually preferred correct form is:
int c; /* not char ! */
while( (c = getc(fp) ) != EOF ) { do whatever with c }

where in your case 'whatever' is call encipher, modified to take the
plaintext char as an argument instead of reading it, and handle the
return value much as now.
current = encipher(i); /* generate encrypted character */
if (current < 'a' || current > 'z')

Same as above about codes for letters.
{
putchar(' '); /* do a space */

In classical crypto it is traditional to suppress all non-letters, and
add arbitrary breaks (for convenience in transmission and
transcription), as your Perl code did.

Incidentally, I assume you know that Vigenere has not provided any
real security for at least a century, and you are only using this as a
convenient subject for programming exercises/practice, or a toy. If
you actually want real encryption, go to sci.crypt, where they will
tell you to use one of the standardized or established algorithms like
3DES, AES, Twofish, tweaked RC4, or (public key) RSA, DH, ECC, etc.
continue; /* if not an alphabetic lowercase */
}

if (i == keylength-1) /* end of the key? */
i=0;
else
i++;

Or, terser but not necessarily better, i = (i+1) % keylength.
putchar(current);
}
putchar('\n');
}

void main(void)

The only correct return type for main is int. FAQ 11.12 et seq.
{
fp = stdin;
getkeyfromfile();
vigenere();
}


It's not working, check yourself.

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top