modulo encrypt problem

J

john blackburn

Hi,

I am trying to get an extremely simple character string encryption function
to work using modulo 10 arithmetic.

void ccencode(UNSIGNED8* pattern) {

UNSIGNED8 key[] = CCKEY;
UNSIGNED8 digval = 0;
UNSIGNED8 count;

for (count=0; count < (strlen(pattern)-4); count++) {

digval = ((*(pattern+strlen(pattern)-count-1)-'0')+key[strlen(pattern)-count-1]+digval)%10;
*(pattern+4+count) = digval+'0';
}

} /* ccencode */


The pattern to be encrypted is a string of ASCII numeric digits. This function
starts with the last digit and adds it to the corresponding digit in the key
(the key array of integers is #defined elsewhere) and then modulo divides it
by 10 to always end up with a digit in the range 0 - 9. The digit is then
added to '0' to make an ASCII character and written to the pattern. the digit
then accumulates into the next and so on.

Two other characteristcs are that the top 4 digits of the pattern are
deliberately unencrypted and the remainder are not only encrypted, but
also reversed in sequence.

My problem is that the first 6 digits are processed correctly but the
remainder do not. The next 3 encrypted digits are 1 greater than they should be
and the remaining 3 are then way out.

Surely this cannot be a rounding effect as % is an
integer division giving an integer remainder. The algorithm works fine
on a Borland C++ compiler but not on gcc. Note that I have to run gcc
in ISO mode for other reasons.

Any ideas what is wrong ?


Thanks in advance


John Blackburn
 
O

osmium

john blackburn said:
I am trying to get an extremely simple character string encryption
function
to work using modulo 10 arithmetic.

void ccencode(UNSIGNED8* pattern) {

UNSIGNED8 key[] = CCKEY;
UNSIGNED8 digval = 0;
UNSIGNED8 count;

for (count=0; count < (strlen(pattern)-4); count++) {

digval =
((*(pattern+strlen(pattern)-count-1)-'0')+key[strlen(pattern)-count-1]+digval)%10;
*(pattern+4+count) = digval+'0';
}

} /* ccencode */


The pattern to be encrypted is a string of ASCII numeric digits. This
function
starts with the last digit and adds it to the corresponding digit in the
key
(the key array of integers is #defined elsewhere) and then modulo divides
it
by 10 to always end up with a digit in the range 0 - 9. The digit is then
added to '0' to make an ASCII character and written to the pattern. the
digit
then accumulates into the next and so on.

Two other characteristcs are that the top 4 digits of the pattern are
deliberately unencrypted and the remainder are not only encrypted, but
also reversed in sequence.

My problem is that the first 6 digits are processed correctly but the
remainder do not. The next 3 encrypted digits are 1 greater than they
should be
and the remaining 3 are then way out.

Surely this cannot be a rounding effect as % is an
integer division giving an integer remainder. The algorithm works fine
on a Borland C++ compiler but not on gcc. Note that I have to run gcc
in ISO mode for other reasons.

Any ideas what is wrong ?

I didn't try to analyze that. But be aware that the default for char
"signage" is undefined in the standard; it can be either signed or unsigned,
it is a vendor option. So if you are using char type anywhere in your
program be sure to explicitly specify it as unsigned.
 
J

john blackburn

osmium said:
I didn't try to analyze that. But be aware that the default for char
"signage" is undefined in the standard; it can be either signed or
unsigned,
it is a vendor option. So if you are using char type anywhere in your
program be sure to explicitly specify it as unsigned.

In the main header file it states :-


#define unsigned char UNSIGNED8
 
R

Richard Bos

john blackburn said:
for (count=0; count < (strlen(pattern)-4); count++) {

digval = ((*(pattern+strlen(pattern)-count-1)-'0')+key[strlen(pattern)-count-1]+digval)%10;
*(pattern+4+count) = digval+'0';

Assuming that strlen(pattern)>5, you're scribbling over your own input
buffer. When count==0, you read from pattern[strlen(pattern)-1], but you
write to pattern[4]. By the time count gets to strlen(pattern)-5, you
write to pattern[strlen(pattern)-1], but you read from pattern[4]...
which already contains its new value. The original values of the early
members of pattern never even get read. You need to use a second buffer
to hold the output while you still need the original value of pattern.

Richard
 
J

john blackburn

Richard said:
john blackburn said:
for (count=0; count < (strlen(pattern)-4); count++) {

digval =
((*(pattern+strlen(pattern)-count-1)-'0')+key[strlen(pattern)-count-1]+digval)%10;
*(pattern+4+count) = digval+'0';

Assuming that strlen(pattern)>5, you're scribbling over your own input
buffer. When count==0, you read from pattern[strlen(pattern)-1], but you
write to pattern[4]. By the time count gets to strlen(pattern)-5, you
write to pattern[strlen(pattern)-1], but you read from pattern[4]...
which already contains its new value. The original values of the early
members of pattern never even get read. You need to use a second buffer
to hold the output while you still need the original value of pattern.

Richard


God, how can I have been so stupid - thanks a lot !
 
B

bd

john said:
In the main header file it states :-


#define unsigned char UNSIGNED8

Wrong way around:
#define UNSIGNED8 unsigned char

Or:
typedef unsigned char UNSIGNED8;

Your #define will replace 'unsigned' with 'char UNSIGNED8' which is probably
not what you want.
 
E

Eric Sosman

john said:
osmium wrote:




In the main header file it states :-


#define unsigned char UNSIGNED8

Then somebody had better repair the main header file.
Are you sure that's what it says? Perhaps you meant

#define UNSIGNED8 unsigned char

or

typedef unsigned char UNSIGNED8;

.... because if things are as you say, you can't expect
anything to work. (And if you're paraphrasing the
problematic code instead of quoting it *exactly*, you
can't expect an accurate diagnosis.)
 
F

Flash Gordon

In the main header file it states :-

#define unsigned char UNSIGNED8

Why use a #define rather than a typedef?

Also, you should be aware that a char may be more than 8 bits, although
I think it is mainly embedded systems where characters are larger than 8
bits.
 
J

john blackburn

Eric said:
Then somebody had better repair the main header file.
Are you sure that's what it says? Perhaps you meant

#define UNSIGNED8 unsigned char

or

typedef unsigned char UNSIGNED8;

... because if things are as you say, you can't expect
anything to work. (And if you're paraphrasing the
problematic code instead of quoting it *exactly*, you
can't expect an accurate diagnosis.)


No, you're right it is a typedef, I typed it quickly and got it wrong; the
actual encryption code, however, is an exact cut and paste.

Thanks for following up for me.

John
 

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
474,147
Messages
2,570,835
Members
47,382
Latest member
MichaleStr

Latest Threads

Top