By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,148 Members | 1,339 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,148 IT Pros & Developers. It's quick & easy.

Works on Windows but not on HPUX, Help Please

P: n/a
Hi,

This code works fine on win and linux but not on hpux. All is compiled
with gcc. Can anyone help please?

/************************************************** ***************************/
/*
*/
/* encrypt
*/
/*
*/
/************************************************** ***************************/
/* Description: Utility function that simply encrypts a string. Used
for */
/* simple password storage in the config file.
*/
/*
*/
/************************************************** ***************************/
void encrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str[i] = str[i] - key;
}
}

/************************************************** ***************************/
/*
*/
/* decrypt
*/
/*
*/
/************************************************** ***************************/
/* Description: Utility function that simply decrypts a string. Used
for */
/* simple password storage in the config file.
*/
/*
*/
/************************************************** ***************************/
void decrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str[i] = str[i] + key;
}
}
The decrypt function even shortens the length, which as you can see,
shouldnt happen and doesnt on other OSs

Any help would be great, thanks
Kind regards
Danny

Jun 27 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a
In article <11*********************@i40g2000cwc.googlegroups. com>,
Smurff <da***********@gmail.com> wrote:
This code works fine on win and linux but not on hpux. All is compiled
with gcc. Can anyone help please?
You didn't really say what symptoms you saw.
void encrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str[i] = str[i] - key;
}
} void decrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str[i] = str[i] + key;
}
} The decrypt function even shortens the length, which as you can see,
shouldnt happen and doesnt on other OSs


If key happens to match any character in str[] then the subtraction
is going to produce a 0 at the corresponding position, and that is
going to have the effect of shortening the string as far as strlen()
is concerned.

But if that isn't happening for you on some systems with the same input,
then my hypothesis would be that you are encountering differences
as to whether char is signed or unsigned.
--
"It is important to remember that when it comes to law, computers
never make copies, only human beings make copies. Computers are given
commands, not permission. Only people can be given permission."
-- Brad Templeton
Jun 27 '06 #2

P: n/a
Walter Roberson wrote:

In article <11*********************@i40g2000cwc.googlegroups. com>,
Smurff <da***********@gmail.com> wrote:
This code works fine on win and linux but not on hpux.
All is compiled with gcc. Can anyone help please?


You didn't really say what symptoms you saw.
void encrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str[i] = str[i] - key;
}
}

void decrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str[i] = str[i] + key;
}
}

The decrypt function even shortens the length, which as you can see,
shouldnt happen and doesnt on other OSs


If key happens to match any character in str[] then the subtraction
is going to produce a 0 at the corresponding position, and that is
going to have the effect of shortening the string as far as strlen()
is concerned.

But if that isn't happening for you on some
systems with the same input,
then my hypothesis would be that you are encountering differences
as to whether char is signed or unsigned.


There might also be a problem with
implementation defined behavior
when char is signed and the result of the subtraction
isn't within the range of char.

If the value of key is INT_MIN,
that would cause undefined behavior in encrypt.

--
pete
Jun 27 '06 #3

P: n/a
Smurff wrote:
Hi,

This code works fine on win and linux but not on hpux. All is compiled
with gcc. Can anyone help please? The decrypt function even shortens the length, which as you can see,
shouldnt happen and doesnt on other OSs


Please post a COMPLETE minimal program that demonstrates the problem.
We need to see your test driver as well as the routine. What key? What
string?


Brian
Jun 27 '06 #4

P: n/a
Smurff wrote:
void encrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str[i] = str[i] - key;
}
}


Aside from being totally weak it's also plagued by the fact the LENGTH
OF THE STRING CAN CHANGE.

What if str[i] == key?

mmm homework.

Tom

Jun 27 '06 #5

P: n/a
Smurff wrote:
Hi,

This code works fine on win and linux but not on hpux. All is compiled
with gcc. Can anyone help please?

/************************************************** ***************************/
/*
Box comments suck.
*/
As we can see here. They're allergic to varying line lengths. Just /* and */
with appropriate whitespace will do.
/* encrypt
*/
/*
*/
/************************************************** ***************************/
/* Description: Utility function that simply encrypts a string. Used
for */
/* simple password storage in the config file.
*/
/*
*/
/************************************************** ***************************/
void encrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
Not advisable. You're counting on your compiler to optimize the evaluation
of strlen(). In this loop it can't do that, in fact, since you're changing
the string and hence may change its length.
{
str[i] = str[i] - key;


Wrong in two ways:

- What if str[i] - key == '\0'? You've just cut your string short.
- What if str[i] - key is not representable in a char? In particular, if
char is signed, the result is implementation-defined, since you're
subtracting an int from a char, which gets you an int. You don't want that.

Here's a possible trivial encryption function:

void encrypt(unsigned char *data, size_t datalen, const unsigned char
*key, size_t keylen) {
size_t i;
for (i = 0; i != datalen; ++i) {
data[i] ^= key[i % keylen];
}
}

This function is its own decryption function. Either call it again to
decrypt or copy the body if you don't want to expose this implementation detail.

It operates on bytes, not characters. The resulting block of data could
contain NUL characters, or in general characters you can't print. You should
use an escape mechanism to read and write the encrypted data -- for example,
writing it as a string of hexadecimal digits or using Base64 encoding.

Do not use this to hide actual secrets, the kind your company's livelihood
depends on. Breaking the encryption is trivial.

S.
Jun 27 '06 #6

P: n/a
Sorry I am a muppet. I used static void and that fixed it.

Sorry to waist your time
Danny

Jun 27 '06 #7

P: n/a
"Smurff" <da***********@gmail.com> writes:
Sorry I am a muppet. I used static void and that fixed it.

Sorry to waist your time


I don't see how using static void could affect the behavior of the
code fragments you posted.

Whatever else you do, you should pay attention to the excellent advice
you got in this thread. It's quite possible that your code will
happen to work in some circumstances, but will fail at precisely the
most embarrassing possible moment.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 28 '06 #8

P: n/a
Smurff wrote:
Sorry I am a muppet. I used static void and that fixed it.
You really are a muppet *if* you ignored all the good advice
in this thread.
Sorry to waist your time


goose,
a waist is a terrible thing to mind

Jun 28 '06 #9

P: n/a
In article <44***********@mindspring.com>,
pete <pf*****@mindspring.com> wrote:
In article <11*********************@i40g2000cwc.googlegroups. com>,
Smurff <da***********@gmail.com> wrote:
>void encrypt(char str[],int key)
>{
> unsigned int i;
> for(i=0;i<strlen(str);++i)
> {
> str[i] = str[i] - key;
> }
>}
If the value of key is INT_MIN,
that would cause undefined behavior in encrypt.


Hmmm, do I read C89 correctly that the char str[i] will be
converted to an int, not an unsigned int, even if char is unsigned,
with the exception of the case where sizeof char == sizeof int
[that being the case where the value of an unsigned char might
not fit within a signed int] ?
C89 3.2.1.1 Characters and Integers
Assuming that all values of char will fit within an int:

- if char is unsigned then its minimum value would be 0,
and if the value of key is INT_MIN then 0-INT_MIN could potentially
be INT_MAX+1 (2's complement system), but on 1's complement or
signed-magnitude then -INT_MIN is INT_MAX and no undefined behaviour
would have occured for those number systems

- if char is signed then its minimum value would be SCHAR_MIN
and that minus INT_MIN might exceed INT_MAX by abs(SCHAR_MIN)
or abs(SCHAR_MIN)+1 . But in this case, it would not just be the
key of value INT_MIN that leads to the undefined behaviour: it would
be any key between INT_MIN and INT_MIN-SCHAR_MIN that would lead
to arithmetic overflow on the subtraction.
On the other hand, once the subtraction is completed, the result
is being stored back into str[i] which is a char. If char is
signed then if the result of the subtraction is less than SCHAR_MIN
then the result of the store operation is undefined. If char
is unsigned then the result of the store operation *is* defined
no matter what the value of the subtraction was [unless the
subtraction result was undefined as per the above.]
In summary, if char is unsigned then there is undefined behaviour
in the case of key = INT_MIN on a 2s complement system, but no
undefined behaviour for 1s complement or signed magnitude;
if char is signed then there is a fair range of values of key
that will produce arithmetic overflow, and an even larger range of
values of key that will produce problems at the assignment operation
even if there was no arithmetic overflow.
--
"law -- it's a commodity"
-- Andrew Ryan (The Globe and Mail, 2005/11/26)
Jun 28 '06 #10

P: n/a
Walter Roberson wrote:

In article <44***********@mindspring.com>,
pete <pf*****@mindspring.com> wrote:
In article <11*********************@i40g2000cwc.googlegroups. com>,
Smurff <da***********@gmail.com> wrote:void encrypt(char str[],int key)
>{
> unsigned int i;
> for(i=0;i<strlen(str);++i)
> {
> str[i] = str[i] - key;
> }
>}
If the value of key is INT_MIN,
that would cause undefined behavior in encrypt.


Hmmm, do I read C89 correctly that the char str[i] will be
converted to an int, not an unsigned int, even if char is unsigned,
with the exception of the case where sizeof char == sizeof int
[that being the case where the value of an unsigned char might
not fit within a signed int] ?


Yes.
unsigned short can also be promoted to signed int.
Code which attempts to increment either unsigned short
or unsigned char until roll over,
without checking first to make sure that signed int
doesn't have the same number of value bits,
is undefined.
C89 3.2.1.1 Characters and Integers

Assuming that all values of char will fit within an int:

- if char is unsigned then its minimum value would be 0,
and if the value of key is INT_MIN then 0-INT_MIN could potentially
be INT_MAX+1 (2's complement system), but on 1's complement or
signed-magnitude then -INT_MIN is INT_MAX and no undefined behaviour
would have occured for those number systems

- if char is signed then its minimum value would be SCHAR_MIN
and that minus INT_MIN might exceed INT_MAX by abs(SCHAR_MIN)
or abs(SCHAR_MIN)+1 . But in this case, it would not just be the
key of value INT_MIN that leads to the undefined behaviour: it would
be any key between INT_MIN and INT_MIN-SCHAR_MIN that would lead
to arithmetic overflow on the subtraction.

On the other hand, once the subtraction is completed, the result
is being stored back into str[i] which is a char. If char is
signed then if the result of the subtraction is less than SCHAR_MIN
then the result of the store operation is undefined. If char
is unsigned then the result of the store operation *is* defined
no matter what the value of the subtraction was [unless the
subtraction result was undefined as per the above.]

In summary, if char is unsigned then there is undefined behaviour
in the case of key = INT_MIN on a 2s complement system, but no
undefined behaviour for 1s complement or signed magnitude;
The null terminator doesn't go through the loop in encrypt.
str[i] always has a non zero value in encrypt;
which is a positive value if char is unsigned.
If unsigned char gets promoted to signed int, as is likely,
and if key equals INT_MIN,
then the result of the subtraction will always excede INT_MAX,
regardless of 1s complement or signed magnitude.
if char is signed then there is a fair range of values of key
that will produce arithmetic overflow, and an even larger range of
values of key that will produce problems at the assignment operation
even if there was no arithmetic overflow.


--
pete
Jun 28 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.