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

encrypting with preprocessor

P: n/a
Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?

--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}

________________________________________
Looking for a good game? Do it yourself!
GLBasic - you can do
www.GLBasic.com
Jul 13 '06 #1
Share this Question
Share on Google+
25 Replies


P: n/a
Gernot Frisch wrote:
Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?
Yes, but it is a bit long to explain and needs a lot of macros (about
200-400 macros) to do it as far as you accept to write:

char secret[] = CRYPT(K,u,n,g,F,u);

instead of a string as a parameters, then CRYPT could output a crypted
string of octal codes for example.

I know this is not an answer, but doing this with macros really require
a "package" of macros to manipulate list of token (e.g. map, cat, merge,
etc...) plus a set of arithmetic and logic operations. I have a such
package so I can provide it on request but it hasn't any documentation.

a+, ld.
Jul 13 '06 #2

P: n/a

"Laurent Deniau" <la************@cern.chschrieb im Newsbeitrag
news:e9**********@sunnews.cern.ch...
Gernot Frisch wrote:
>Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16
characters. Simple XOR would suffice, too. Any ideas of how that
can be done?

Yes, but it is a bit long to explain and needs a lot of macros
(about 200-400 macros) to do it as far as you accept to write:

char secret[] = CRYPT(K,u,n,g,F,u);

instead of a string as a parameters, then CRYPT could output a
crypted string of octal codes for example.

I know this is not an answer, but doing this with macros really
require a "package" of macros to manipulate list of token (e.g. map,
cat, merge, etc...) plus a set of arithmetic and logic operations. I
have a such package so I can provide it on request but it hasn't any
documentation.
can you give a grief explaination on how to make it?
Jul 13 '06 #3

P: n/a
Gernot Frisch said:
Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?
#define CRYPT(x) my_encryption_routine(x)

I don't think you can do this without calling a function, although I would
be very interested in seeing a counter-example.

My reasoning is as follows: you'd need to do this in a single expression
that doesn't involve a compound statement (because compound statements are
not mere expressions, so they don't yield a value, which wouldn't be so bad
if they played nice with comma operators - but they don't). A function gets
around these problems nicely, but I don't see any other way to do it. In
C99 you could use an inline function, I suppose.

<OT>
If you happen to be using gcc, I think you can use a GNU extension which
allows compound statements in macros to yield results. A gcc newsgroup
would be a good place to ask about this.
</OT>

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jul 13 '06 #4

P: n/a
#define CRYPT(x) my_encryption_routine(x)
That way the string itself could be found&searched for in the binary.
That's what I want to prevent.
Jul 13 '06 #5

P: n/a
Gernot Frisch wrote:
"Laurent Deniau" <la************@cern.chschrieb im Newsbeitrag
news:e9**********@sunnews.cern.ch...
>>Gernot Frisch wrote:
>>>Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16
characters. Simple XOR would suffice, too. Any ideas of how that
can be done?

Yes, but it is a bit long to explain and needs a lot of macros
(about 200-400 macros) to do it as far as you accept to write:

char secret[] = CRYPT(K,u,n,g,F,u);

instead of a string as a parameters, then CRYPT could output a
crypted string of octal codes for example.

I know this is not an answer, but doing this with macros really
require a "package" of macros to manipulate list of token (e.g. map,
cat, merge, etc...) plus a set of arithmetic and logic operations. I
have a such package so I can provide it on request but it hasn't any
documentation.


can you give a grief explaination on how to make it?
- convert K,u,n,g,F,u to the list (6,(K,u,n,g,F,u))
- create a list of macros, say CODE_, ending with the letters (26*2 + 1
macros) which expand to value/code
- apply concat(CODE_,tok) to the list
- optionally apply some transformation/crypt algo to the list elements
- apply a convertion from value to octal code
- concat the element of the list into a single token
- stringify the result.

As I said, doing this requires somehow 200-300 stupid and repetitive
macros to handle set of values and about 20 smart macros to transform
the list.

a+, ld.
Jul 13 '06 #6

P: n/a
Richard Heathfield wrote:
Gernot Frisch said:
>Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");
(fx:snip)
#define CRYPT(x) my_encryption_routine(x)

I don't think you can do this without calling a function, although I would
be very interested in seeing a counter-example.
Doesn't that not-work in the OPs example? Possible uses of `sizeof (secret)`
may preclude transforming it to `char *secret = CRYPT("KungFu");`.

--
Chris "seeker" Dollin
"We did not have time to find out everything we wanted to know." /A Clash of Cymbals/

Jul 13 '06 #7

P: n/a
Chris Dollin said:
Richard Heathfield wrote:
>Gernot Frisch said:
>>Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

(fx:snip)
>#define CRYPT(x) my_encryption_routine(x)

I don't think you can do this without calling a function, although I
would be very interested in seeing a counter-example.

Doesn't that not-work in the OPs example?
Oh yes, of course you're right. And in any case, it now transpires that his
reason for wanting the macro is that he doesn't want the string literal to
appear in the binary. I wish he'd said so at the outset.

Now that I know this, I suggest he simply pre-computes the encryption via a
separate program that he does not release. Let the output of the separate
program be, for example:

{
0x34, 0x29, 0xF3, 0xA2, 0x77, 0x21
};

(or whatever), and be saved as secret1.enc. He can then do this:

char secret[] =
#include "secret1.enc"

Problem solved, without any gerharsterly macros.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jul 13 '06 #8

P: n/a
Richard Heathfield wrote:
Chris Dollin said:
>Richard Heathfield wrote:
>>Gernot Frisch said:

Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

(fx:snip)
>>#define CRYPT(x) my_encryption_routine(x)

I don't think you can do this without calling a function, although I
would be very interested in seeing a counter-example.

Doesn't that not-work in the OPs example?

Oh yes, of course you're right. And in any case, it now transpires that his
reason for wanting the macro is that he doesn't want the string literal to
appear in the binary. I wish he'd said so at the outset.

Now that I know this, I suggest he simply pre-computes the encryption via a
separate program that he does not release. Let the output of the separate
program be, for example:

{
0x34, 0x29, 0xF3, 0xA2, 0x77, 0x21
};

(or whatever), and be saved as secret1.enc. He can then do this:

char secret[] =
#include "secret1.enc"

Problem solved, without any gerharsterly macros.
A similar approach would be to write

char secret[] = CRYPTOF_KungFu;

where CRYPTOF_KungFu is a macro which gets #defined somehow: in a single
#included "cryptic.h" file or even as -D options to his compiler commands
if his implementation has such.

Of course suitable conventions and seddery and such allow the extraction
of any number of such CRYPTOF uses in the code, so long as the crypted
things can appear in macro names.

--
Chris "what do you mean, 'overkill'?" Dollin
"Life is full of mysteries. Consider this one of them." Sinclair, /Babylon 5/

Jul 13 '06 #9

P: n/a
>Now that I know this, I suggest he simply pre-computes the
encryption via a
separate program that he does not release. Let the output of the
separate
program be, for example:

{
0x34, 0x29, 0xF3, 0xA2, 0x77, 0x21
};

(or whatever), and be saved as secret1.enc. He can then do this:

char secret[] =
#include "secret1.enc"

Problem solved, without any gerharsterly macros.

A similar approach would be to write

char secret[] = CRYPTOF_KungFu;

where CRYPTOF_KungFu is a macro which gets #defined somehow: in a
single
#included "cryptic.h" file or even as -D options to his compiler
commands
if his implementation has such.

Of course suitable conventions and seddery and such allow the
extraction
of any number of such CRYPTOF uses in the code, so long as the
crypted
things can appear in macro names.
That's exaclty what I don't want - using an external program. I just
want to write my source code and have the precompiler mess with it.
Jul 13 '06 #10

P: n/a
Richard Heathfield wrote:
Gernot Frisch said:

>>Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?


#define CRYPT(x) my_encryption_routine(x)

I don't think you can do this without calling a function, although I would
be very interested in seeing a counter-example.

My reasoning is as follows: you'd need to do this in a single expression
that doesn't involve a compound statement (because compound statements are
not mere expressions, so they don't yield a value, which wouldn't be so bad
if they played nice with comma operators - but they don't). A function gets
around these problems nicely, but I don't see any other way to do it. In
C99 you could use an inline function, I suppose.
Here is a macro which compute the FNV hash function of the first 32
characters of a litteral string at compile time. The original litteral
string 'str' does not appear in the binary. I let you adapt this macro
to do encryption instead of computing hash code. I have another version
which stops when the tailing '\0' is encountered in the litteral string,
but the compile time is much much longer since the generated AST is
completely evaluated before reductions start (at least in gcc, but I
think in most compilers because it is in a separate compilation phase).

a+, ld.

#define ooc_staticHashStr32(str, initVal) \
OOC_STATICHASHSTR32_(str \
"\000\000\000\000\000\000\000\000" \
"\000\000\000\000\000\000\000\000" \
"\000\000\000\000\000\000\000\000" \
"\000\000\000\000\000\000\000\000", \
(initVal))

#define OOC_STATICHASHSTR32_(str, initVal) \
(((((((((((((((((((((((((((((((( \
(unsigned long)(initVal) \
*16777619ul+(unsigned char)(str)[ 0]) \
*16777619ul+(unsigned char)(str)[ 1]) \
*16777619ul+(unsigned char)(str)[ 2]) \
*16777619ul+(unsigned char)(str)[ 3]) \
*16777619ul+(unsigned char)(str)[ 4]) \
*16777619ul+(unsigned char)(str)[ 5]) \
*16777619ul+(unsigned char)(str)[ 6]) \
*16777619ul+(unsigned char)(str)[ 7]) \
*16777619ul+(unsigned char)(str)[ 8]) \
*16777619ul+(unsigned char)(str)[ 9]) \
*16777619ul+(unsigned char)(str)[10]) \
*16777619ul+(unsigned char)(str)[11]) \
*16777619ul+(unsigned char)(str)[12]) \
*16777619ul+(unsigned char)(str)[13]) \
*16777619ul+(unsigned char)(str)[14]) \
*16777619ul+(unsigned char)(str)[15]) \
*16777619ul+(unsigned char)(str)[16]) \
*16777619ul+(unsigned char)(str)[17]) \
*16777619ul+(unsigned char)(str)[18]) \
*16777619ul+(unsigned char)(str)[19]) \
*16777619ul+(unsigned char)(str)[20]) \
*16777619ul+(unsigned char)(str)[21]) \
*16777619ul+(unsigned char)(str)[22]) \
*16777619ul+(unsigned char)(str)[23]) \
*16777619ul+(unsigned char)(str)[24]) \
*16777619ul+(unsigned char)(str)[25]) \
*16777619ul+(unsigned char)(str)[26]) \
*16777619ul+(unsigned char)(str)[27]) \
*16777619ul+(unsigned char)(str)[28]) \
*16777619ul+(unsigned char)(str)[29]) \
*16777619ul+(unsigned char)(str)[30]) \
*16777619ul+(unsigned char)(str)[31])
Jul 13 '06 #11

P: n/a

I don't quite get it.
How would I left-trim a string by 3 characters using the precompiler?

Like:

#define TRIM3(str) t__TRIM3(str "\0\0\0")
#define t_TRIM3(str) ((str)+3)

(which does not work)

Jul 13 '06 #12

P: n/a
Gernot Frisch wrote:
[...]
can you give a grief explaination on how to make it?
I think that any explanation would give you plenty of grief. :-)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Jul 13 '06 #13

P: n/a
>Of course suitable conventions and seddery and such allow the
>extraction
of any number of such CRYPTOF uses in the code, so long as the
crypted
things can appear in macro names.

That's exaclty what I don't want - using an external program. I just
want to write my source code and have the precompiler mess with it.
The preprocessor cannot access memory. If you represent the string
to be crypted as a quoted string, it's not possible to get at individual
characters to manipulate them at preprocessor time.

You can do things like:

char cryptedtext[] = {'T' ^ 0x55, 'e' ^ 0x55, 'x' ^ 0x55, 't' ^ 0x55};

but it's *NOT* encrypted in the preprocessed source code.

Gordon L. Burditt
Jul 14 '06 #14

P: n/a
[...]
>can you give a grief explaination on how to make it?

I think that any explanation would give you plenty of grief. :-)
Doh! "brief" - I mean: short in length. Oh dear. My brain decay is
proceeding much faster than I thought ;)
Jul 14 '06 #15

P: n/a
Gernot Frisch wrote:
I don't quite get it.
How would I left-trim a string by 3 characters using the precompiler?

Like:

#define TRIM3(str) t__TRIM3(str "\0\0\0")
#define t_TRIM3(str) ((str)+3)

(which does not work)
It does not work because the orignal string still appears in the binary,
it is what you mean by "does not work"?

#define TRIM3(str) { t__TRIM3(str "\0\0\0") }
#define t_TRIM3(str) (str)[3],(str)[4],(str)[5]

a+, ld.
Jul 14 '06 #16

P: n/a

"Gernot Frisch" <Me@Privacy.netwrote in message
news:4h***********@individual.net...
Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?
I don't believe that using the preprocessor is the best solution, but here
is a simple solution:

#define _S(x) #x
#define _T(a,b,c,d,e,f) _S(a ## b ## c ## d ## e ## f)
#define CRYPT(a,b,c,d,e,f) _T(a,b,c,d,e,f)

/* define aliases for each letter, limited to _A-Za-z0-9 */
/* or you can use specific char's, say '!', directly in txt1 */
#define _CK A
#define _Cu z
#define _Cn y
#define _Cg q
#define _CF p

int main(void)
{

char txt1[]=CRYPT(_CK,_Cu,_Cn,_Cg,_CF,_Cu);
char *secret=txt1;

}

That is probably about as much "encryption" as you would ever want to do
with the preprocessor. Anything further will be a nightmare to implement
properly.

A better solution is to write a small program to open your binary, search
for a specific string, and replace it with the encrypted string. That is
what I would do.
Rod Pemberton
Jul 14 '06 #17

P: n/a
Rod Pemberton wrote:
"Gernot Frisch" <Me@Privacy.netwrote in message
news:4h***********@individual.net...
>>Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?


I don't believe that using the preprocessor is the best solution, but here
is a simple solution:

#define _S(x) #x
#define _T(a,b,c,d,e,f) _S(a ## b ## c ## d ## e ## f)
#define CRYPT(a,b,c,d,e,f) _T(a,b,c,d,e,f)

/* define aliases for each letter, limited to _A-Za-z0-9 */
/* or you can use specific char's, say '!', directly in txt1 */
#define _CK A
#define _Cu z
#define _Cn y
#define _Cg q
#define _CF p

int main(void)
{

char txt1[]=CRYPT(_CK,_Cu,_Cn,_Cg,_CF,_Cu);
Why don't you concatenate the _C prefix in the CRYPT macro?

#define CRYPT(a,b,c,d,e,f) _T(_C##a,_C##b,_C##c,_C##d,_C##e,_C##f)

Then you can directly write:

char txt1[]=CRYPT(K,u,n,g,F,u);
char *secret=txt1;

}

That is probably about as much "encryption" as you would ever want to do
with the preprocessor. Anything further will be a nightmare to implement
properly.
Why?
A better solution is to write a small program to open your binary, search
for a specific string, and replace it with the encrypted string. That is
what I would do.
I prefer the CPP way as the OP. By the way, the final result need not be
a valid C litteral string, but only an array of bytes (e.g no '\0' at
the end and the length coded at the beginning) to avoid strings to catch it.

a+, ld.
Jul 14 '06 #18

P: n/a

"Laurent Deniau" <la************@cern.chschrieb im Newsbeitrag
news:e9**********@sunnews.cern.ch...
Gernot Frisch wrote:
>I don't quite get it.
How would I left-trim a string by 3 characters using the
precompiler?

Like:

#define TRIM3(str) t__TRIM3(str "\0\0\0")
#define t_TRIM3(str) ((str)+3)

(which does not work)

It does not work because the orignal string still appears in the
binary, it is what you mean by "does not work"?

#define TRIM3(str) { t__TRIM3(str "\0\0\0") }
#define t_TRIM3(str) (str)[3],(str)[4],(str)[5]

I want it that way:
const char str[] = TRIM3("KungFu");

resulting in str[] == "ngFu";

That's impossible, right?
Jul 14 '06 #19

P: n/a
Gernot Frisch wrote:
"Laurent Deniau" <la************@cern.chschrieb im Newsbeitrag
news:e9**********@sunnews.cern.ch...
>>Gernot Frisch wrote:
>>>I don't quite get it.
How would I left-trim a string by 3 characters using the
precompiler?

Like:

#define TRIM3(str) t__TRIM3(str "\0\0\0")
#define t_TRIM3(str) ((str)+3)

(which does not work)

It does not work because the orignal string still appears in the
binary, it is what you mean by "does not work"?

#define TRIM3(str) { t__TRIM3(str "\0\0\0") }
#define t_TRIM3(str) (str)[3],(str)[4],(str)[5]

I want it that way:
const char str[] = TRIM3("KungFu");

resulting in str[] == "ngFu";
So here you want a trim of 2, not 3
That's impossible, right?
Why? The code above is a start but from there, you get it in 1min of
work (I thought my example on the hash code to be explicit). Assuming
that you deal with a string length of 8 characters max (can be extended
easily) and you want to apply a trim of 2 (like above):
cat tmp.c
#include <stdio.h>

#define CRYPT8(str) { CRYPT8_(str "\0\0\0\0\0\0\0\0") }
#define CRYPT8_(str) \
(str)[2],(str)[3],(str)[4],(str)[5],(str)[6],(str)[7],'\0'

int main(void)
{
const char str[] = CRYPT8("KungFu");
puts(strcmp(str,"ngFu") ? "KO" : "OK");
}
gcc tmp.c -o tmp
./tmp
OK
strings ./tmp | grep "KungFu" | wc -l
0

the string "KungFu" is *not* in the binary. Impossible?

a+, ld.


Jul 14 '06 #20

P: n/a
cat tmp.c
#include <stdio.h>

#define CRYPT8(str) { CRYPT8_(str "\0\0\0\0\0\0\0\0") }
#define CRYPT8_(str) \
(str)[2],(str)[3],(str)[4],(str)[5],(str)[6],(str)[7],'\0'

int main(void)
{
const char str[] = CRYPT8("KungFu");
puts(strcmp(str,"ngFu") ? "KO" : "OK");
}
gcc tmp.c -o tmp
./tmp
OK
strings ./tmp | grep "KungFu" | wc -l
0

the string "KungFu" is *not* in the binary. Impossible?

Now I've got it!!!!!! I have to provide the macro "CRYPT8_" for the
maximum characters used ever. So, longer strings will be trimmed right
side. If I use a max of 128, that will suffice for every line in my
code.
Excellent idea!
Jul 14 '06 #21

P: n/a
Gernot Frisch wrote:
>>>cat tmp.c

#include <stdio.h>

#define CRYPT8(str) { CRYPT8_(str "\0\0\0\0\0\0\0\0") }
#define CRYPT8_(str) \
(str)[2],(str)[3],(str)[4],(str)[5],(str)[6],(str)[7],'\0'

int main(void)
{
const char str[] = CRYPT8("KungFu");
puts(strcmp(str,"ngFu") ? "KO" : "OK");
}
>>>gcc tmp.c -o tmp
./tmp

OK
>>>strings ./tmp | grep "KungFu" | wc -l

0

the string "KungFu" is *not* in the binary. Impossible?

Now I've got it!!!!!! I have to provide the macro "CRYPT8_" for the
maximum characters used ever. So, longer strings will be trimmed right
side. If I use a max of 128, that will suffice for every line in my
code.
Excellent idea!
Note two small things, first I forgot to include string.h, second this
is c99 and not c89 since it uses array indexing which is not constant
(!), i.e. (str)[2] <=*(str+2) and indirection cannot be computed at
compile time even if str is a literal string. Therefore the variable str
in the example above cannot have static storage class (e.g. static or
global). I hope that it is still what you were looking for.

a+, ld.
Jul 14 '06 #22

P: n/a

"Laurent Deniau" <la************@cern.chwrote in message
news:e9**********@sunnews.cern.ch...
Rod Pemberton wrote:
"Gernot Frisch" <Me@Privacy.netwrote in message
news:4h***********@individual.net...
>Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?

I don't believe that using the preprocessor is the best solution, but
here
is a simple solution:

#define _S(x) #x
#define _T(a,b,c,d,e,f) _S(a ## b ## c ## d ## e ## f)
#define CRYPT(a,b,c,d,e,f) _T(a,b,c,d,e,f)

/* define aliases for each letter, limited to _A-Za-z0-9 */
/* or you can use specific char's, say '!', directly in txt1 */
#define _CK A
#define _Cu z
#define _Cn y
#define _Cg q
#define _CF p

int main(void)
{

char txt1[]=CRYPT(_CK,_Cu,_Cn,_Cg,_CF,_Cu);

Why don't you concatenate the _C prefix in the CRYPT macro?

#define CRYPT(a,b,c,d,e,f) _T(_C##a,_C##b,_C##c,_C##d,_C##e,_C##f)
Because it doesn't work... at least with the compilers I use. If it works
for the OP's, great! It's another thing he can use.

This is the problem that occurs for me:
if a=K, _C##a will become _CK, but _CK won't be replaced with A.

You'll need to turn on preprocessing only with your compiler. For GCC,
it's -E option. For OpenWatcom, it's -p option. For others, you'll need to
check your documentation.
Then you can directly write:

char txt1[]=CRYPT(K,u,n,g,F,u);
char *secret=txt1;

}

That is probably about as much "encryption" as you would ever want to do
with the preprocessor. Anything further will be a nightmare to
implement
properly.

Why?
IMO, limitations of the preprocessor to do text replacement. It was very
difficult to come up with an example that worked the same way for both DJGPP
and OW. Things that worked on one didn't work on the other and vice versa.
The preprocessor isn't intended to be a full string library capable of doing
encryption. In a few lines of mostly non-preprocessor C code, he could do
everything he wants without much hassle.

Rod Pemberton
Jul 15 '06 #23

P: n/a
Rod Pemberton wrote:
"Laurent Deniau" <la************@cern.chwrote in message
news:e9**********@sunnews.cern.ch...
>>Rod Pemberton wrote:
>>>is a simple solution:

#define _S(x) #x
#define _T(a,b,c,d,e,f) _S(a ## b ## c ## d ## e ## f)
#define CRYPT(a,b,c,d,e,f) _T(a,b,c,d,e,f)

/* define aliases for each letter, limited to _A-Za-z0-9 */
/* or you can use specific char's, say '!', directly in txt1 */
#define _CK A
#define _Cu z
#define _Cn y
#define _Cg q
#define _CF p

int main(void)
{

char txt1[]=CRYPT(_CK,_Cu,_Cn,_Cg,_CF,_Cu);

Why don't you concatenate the _C prefix in the CRYPT macro?

#define CRYPT(a,b,c,d,e,f) _T(_C##a,_C##b,_C##c,_C##d,_C##e,_C##f)


Because it doesn't work... at least with the compilers I use.
Oops. I forgot to add has the intermediate expansion macro:

#define _T0(a,b,c,d,e,f) _T(a,b,c,d,e,f)
#define CRYPT(a,b,c,d,e,f) _T0(_C##a,_C##b,_C##c,_C##d,_C##e,_C##f)

now this should work.

char txt1[]=CRYPT(K,u,n,g,F,u);
gcc -P -E tmp.c
int main(void)
{
char txt1[]="Azyqpz";
}
>>>That is probably about as much "encryption" as you would ever want to do
with the preprocessor. Anything further will be a nightmare to
implement properly.
Do you mean something like ;-) :

/* concatenate LIST1 and LIST2 */
#define cos_PPL_CAT(LIST1,LIST2) \
(cos_PP_ADD(cos_PP_LEN(LIST1),cos_PP_LEN(LIST2)), \
(cos_PP_IF(cos_PP_AND(cos_PP_LEN(LIST1),cos_PP_LEN (LIST2)), \
cos_PP_PAIR,cos_PP_CONS) \
(cos_PPL_TUPLE(LIST1),cos_PPL_TUPLE(LIST2))))

/* concatenate the LIST elements */
#define cos_PPL_ECAT(LIST) \
cos_PPL_APPLY(cos_PP_DECR(cos_PP_LEN(LIST)),cos_PP L_ECAT_,LIST)
#define cos_PPL_ECAT_(LIST) cos_PPL_CAT( \
(1, (cos_PP_CAT(cos_PPL_ELEM(0,LIST),cos_PPL_ELEM(1,LI ST)))), \
cos_PPL_TAIL(cos_PP_SUB(cos_PP_LEN(LIST),2),LIST))
IMO, limitations of the preprocessor to do text replacement. It was very
difficult to come up with an example that worked the same way for both DJGPP
and OW. Things that worked on one didn't work on the other and vice versa.
It is clear that porting code to a non ISO C99 preprocessor can be a
nightmare. But in that case, I just throw away the cpp and take a
compliant one (e.g. ucpp).
The preprocessor isn't intended to be a full string library capable of doing
encryption. In a few lines of mostly non-preprocessor C code, he could do
everything he wants without much hassle.
Once you have a "user-friendly" package of macros to deal with lists of
tokens, much can be done easily, especially for generating C code.

a+, ld.
Jul 17 '06 #24

P: n/a

"Laurent Deniau" <la************@cern.chwrote in message
news:e9**********@sunnews.cern.ch...
Rod Pemberton wrote:
"Laurent Deniau" <la************@cern.chwrote in message
news:e9**********@sunnews.cern.ch...
>Rod Pemberton wrote:
is a simple solution:

#define _S(x) #x
#define _T(a,b,c,d,e,f) _S(a ## b ## c ## d ## e ## f)
#define CRYPT(a,b,c,d,e,f) _T(a,b,c,d,e,f)

/* define aliases for each letter, limited to _A-Za-z0-9 */
/* or you can use specific char's, say '!', directly in txt1 */
#define _CK A
#define _Cu z
#define _Cn y
#define _Cg q
#define _CF p

int main(void)
{

char txt1[]=CRYPT(_CK,_Cu,_Cn,_Cg,_CF,_Cu);

Why don't you concatenate the _C prefix in the CRYPT macro?

#define CRYPT(a,b,c,d,e,f) _T(_C##a,_C##b,_C##c,_C##d,_C##e,_C##f)

Because it doesn't work... at least with the compilers I use.

Oops. I forgot to add has the intermediate expansion macro:

#define _T0(a,b,c,d,e,f) _T(a,b,c,d,e,f)
#define CRYPT(a,b,c,d,e,f) _T0(_C##a,_C##b,_C##c,_C##d,_C##e,_C##f)

now this should work.

char txt1[]=CRYPT(K,u,n,g,F,u);
gcc -P -E tmp.c
int main(void)
{
char txt1[]="Azyqpz";
}
Yes, and no for me. It works for me with OWv1.3. It fails with DJGPP's gcc
v3.4.1 and gcc v4.1.0. Is DJGPP's preprocessor broken?
>>That is probably about as much "encryption" as you would ever want to
do
>>with the preprocessor. Anything further will be a nightmare to
implement properly.

Do you mean something like ;-) :

/* concatenate LIST1 and LIST2 */
#define cos_PPL_CAT(LIST1,LIST2) \
(cos_PP_ADD(cos_PP_LEN(LIST1),cos_PP_LEN(LIST2)), \
(cos_PP_IF(cos_PP_AND(cos_PP_LEN(LIST1),cos_PP_LEN (LIST2)), \
cos_PP_PAIR,cos_PP_CONS) \
(cos_PPL_TUPLE(LIST1),cos_PPL_TUPLE(LIST2))))

/* concatenate the LIST elements */
#define cos_PPL_ECAT(LIST) \
cos_PPL_APPLY(cos_PP_DECR(cos_PP_LEN(LIST)),cos_PP L_ECAT_,LIST)
#define cos_PPL_ECAT_(LIST) cos_PPL_CAT( \
(1, (cos_PP_CAT(cos_PPL_ELEM(0,LIST),cos_PPL_ELEM(1,LI ST)))), \
cos_PPL_TAIL(cos_PP_SUB(cos_PP_LEN(LIST),2),LIST))
Any pointers for "taming the nightmare"? I could use them.
IMO, limitations of the preprocessor to do text replacement. It was
very
difficult to come up with an example that worked the same way for both
DJGPP
and OW. Things that worked on one didn't work on the other and vice
versa.
>
It is clear that porting code to a non ISO C99 preprocessor can be a
nightmare. But in that case, I just throw away the cpp and take a
compliant one (e.g. ucpp).
Nice. I don't recall seeing that one. Thanks, here's the link for others:
http://pornin.nerim.net/ucpp/
The preprocessor isn't intended to be a full string library capable of
doing
encryption. In a few lines of mostly non-preprocessor C code, he could
do
everything he wants without much hassle.

Once you have a "user-friendly" package of macros to deal with lists of
tokens, much can be done easily, especially for generating C code.
Later,

Rod Pemberton
Jul 18 '06 #25

P: n/a
Rod Pemberton wrote:
"Laurent Deniau" <la************@cern.chwrote in message
Yes, and no for me. It works for me with OWv1.3. It fails with DJGPP's gcc
v3.4.1 and gcc v4.1.0. Is DJGPP's preprocessor broken?
It works with 4.0.3 but I suspect that gcc4.1.0 to be more compliant
because according to 6.10.3.1-1, I suspect the ## operator to be applied
before parameter substitution. But anyway it is easy to force the
parameter substitution by delaying the action of ## by one level:

#define _S(x) #x
#define _C(x) _C##x
#define _T(a,b,c,d,e,f) _S(a ## b ## c ## d ## e ## f)
#define _T0(a,b,c,d,e,f) _T(a,b,c,d,e,f)
#define CRYPT(a,b,c,d,e,f) _T0(_C(a),_C(b),_C(c),_C(d),_C(e),_C(f))

#define _CK A
#define _Cu z
#define _Cn y
#define _Cg q
#define _CF p

int main(void)
{
char txt1[]=CRYPT(K,u,n,g,F,u);
}
>>Do you mean something like ;-) :

/* concatenate LIST1 and LIST2 */
#define cos_PPL_CAT(LIST1,LIST2) \
(cos_PP_ADD(cos_PP_LEN(LIST1),cos_PP_LEN(LIST2)), \
(cos_PP_IF(cos_PP_AND(cos_PP_LEN(LIST1),cos_PP_LEN (LIST2)), \
cos_PP_PAIR,cos_PP_CONS) \
(cos_PPL_TUPLE(LIST1),cos_PPL_TUPLE(LIST2))))

/* concatenate the LIST elements */
#define cos_PPL_ECAT(LIST) \
cos_PPL_APPLY(cos_PP_DECR(cos_PP_LEN(LIST)),cos_PP L_ECAT_,LIST)
#define cos_PPL_ECAT_(LIST) cos_PPL_CAT( \
(1, (cos_PP_CAT(cos_PPL_ELEM(0,LIST),cos_PPL_ELEM(1,LI ST)))), \
cos_PPL_TAIL(cos_PP_SUB(cos_PP_LEN(LIST),2),LIST))


Any pointers for "taming the nightmare"? I could use them.
No, as I said, I have a cpp (c99) "package" to manipulate list of tokens
and the macros above are just a small part of this "package". No doc, no
warranty but I can provide a tarball on request. The advantage of macros
is that they do not need makefile, just a -I directive ;-)
Nice. I don't recall seeing that one. Thanks, here's the link for others:
http://pornin.nerim.net/ucpp/
Yes, that is why for portability issue I use c99cpp + c89core since I
always can rely on this level ;-) I find the variadic macros very useful
(one of the best thing introduced by c99).

a+, ld.
Jul 18 '06 #26

This discussion thread is closed

Replies have been disabled for this discussion.