469,623 Members | 1,800 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,623 developers. It's quick & easy.

string generation

I want to generate every possible 16 character combination of the
characters 0-9, A-Z, and a-z programatically. My current code follows:

#include <stdio.h>
#include <ctype.h>

int main() {
char strBuf[17] = {0};
int i, j;

for(i = 0; i < 16; i++) {
for(j = '0'; j <= 'z'; j++) {
if(!isalnum(j)) continue;
strBuf[i] = j;
printf("%s\n", strBuf);
}
}

return 0;
}

Only the last character increments. I understand my problem and I can
fix it with a for loop for each space in the array, but I'd like to know
if there's a better solution.
Nov 14 '05 #1
27 2289
Ken Human <ke******@comcast.net> writes:
I want to generate every possible 16 character combination of the
characters 0-9, A-Z, and a-z programatically. My current code follows:


Really, every one?
And on what computer are you hoping to run this?

--
Chris.
Nov 14 '05 #2
Ken Human wrote:
I want to generate every possible 16 character combination of the
characters 0-9, A-Z, and a-z programatically.
Are you sure? That's pow(62,16), which is a lot of combinations.
About 4.8e28, I think.
My current code follows:

#include <stdio.h>
#include <ctype.h>

int main() {
char strBuf[17] = {0};
int i, j;

for(i = 0; i < 16; i++) {
for(j = '0'; j <= 'z'; j++) {
if(!isalnum(j)) continue;
strBuf[i] = j;
printf("%s\n", strBuf);
}
}

return 0;
}

Only the last character increments. I understand my problem and I can
fix it with a for loop for each space in the array, but I'd like to know
if there's a better solution.


untested code block:
{
char foo[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
unsigned nfoos = sizeof foo/sizeof *foo;
unsigned ndx[16] = {0}, i;
while(ndx[15] != nfoos)
{
for (i = 0; i < 16; i++) putchar(foo[ndx[i]]);
putchar('\n');
for(i = 0; i < 16; i++)
{
ndx[i]++;
if (ndx[i] < nfoos) break;
ndx[i] = 0;
}
}
}
Nov 14 '05 #3
Chris McDonald wrote:
Ken Human <ke******@comcast.net> writes:

I want to generate every possible 16 character combination of the
characters 0-9, A-Z, and a-z programatically. My current code follows:

Really, every one?
And on what computer are you hoping to run this?


I was never very good at math, is the number of possible combinations
62^16? Thank you for your concern. I'm running it on the Plasmo Mag-8,
which can calculate this exact amount of data in 1 second. Needless to
say, it also has an unlimited amount of memory.

Let's say that I want a 4 character combination.
Nov 14 '05 #4
Martin Ambuhl wrote:
Ken Human wrote:
I want to generate every possible 16 character combination of the
characters 0-9, A-Z, and a-z programatically.

Are you sure? That's pow(62,16), which is a lot of combinations.
About 4.8e28, I think.

[...]
untested code block:
{
char foo[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
unsigned nfoos = sizeof foo/sizeof *foo;
unsigned ndx[16] = {0}, i;
while(ndx[15] != nfoos)
{
for (i = 0; i < 16; i++) putchar(foo[ndx[i]]);
putchar('\n');
for(i = 0; i < 16; i++)
{
ndx[i]++;
if (ndx[i] < nfoos) break;
ndx[i] = 0;
}
}
}


Thanks, Martin. That was what I was looking for.
Nov 14 '05 #5
In article <27********************@comcast.com>,
Ken Human <ke******@comcast.net> wrote:
I want to generate every possible 16 character combination of the
characters 0-9, A-Z, and a-z programatically.
Are you sure????

That's 62 symbols, and you want 16 of them, so that's pow(62,16)
combinations, which is 47672401706823533450263330816
If you are able to generate them at the rate of 1 GHz
then even presuming you have storage system able to handle
17 gigabyte/second, it would take 1.5E12 years.

At a 1 GHz production rate, you could get through 8 positions
worth in just over a day... and that alone would require over 1.3
petabytes of storage.

My current code follows: #include <stdio.h>
#include <ctype.h> int main() {
char strBuf[17] = {0};
int i, j; for(i = 0; i < 16; i++) {
for(j = '0'; j <= 'z'; j++) {
if(!isalnum(j)) continue;
strBuf[i] = j;
printf("%s\n", strBuf);
}
}
return 0;
}


I would suggest that instead of testing for isalnum, that
you create an array of the valid choices and index it by
the current j (which would range over 0 to the number of choices minus 1
instead of '0' to 'z'). That will save you from the conditional
test at each point.

This won't save you from the problem of only incrementing the
last byte. There are various ways of handling that situation,
but we have to leave you -something- to be inventive over ;-)
--
Oh, to be a Blobel!
Nov 14 '05 #6
Ken Human wrote on 22/05/05 :
I want to generate every possible 16 character combination of the characters
0-9, A-Z, and a-z programatically. My current code follows:
Really ? It may take hours or days to print them out... Sounds like a
cracking device...

#include <stdio.h>
#include <ctype.h>

int main() {
char strBuf[17] = {0};
int i, j;

for(i = 0; i < 16; i++) {
for(j = '0'; j <= 'z'; j++) {
Don't make assumptions on characters values. It only works with digits.
Use an array of char

static char const
characters[]="0123456789ABCDE<...>XYZ<...>abc<...>xyz";

if(!isalnum(j)) continue;
strBuf[i] = j;
printf("%s\n", strBuf);
}
}

return 0;
}

Only the last character increments. I understand my problem and I can fix it
with a for loop for each space in the array, but I'd like to know if there's
a better solution.


You probably want 16 nested loops... or a smart recursive function with
a huge automatic memory...

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

..sig under repair

Nov 14 '05 #7
Martin Ambuhl wrote on 22/05/05 :
untested code block:
{
char foo[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
unsigned nfoos = sizeof foo/sizeof *foo;
unsigned ndx[16] = {0}, i;
while(ndx[15] != nfoos)
{
for (i = 0; i < 16; i++) putchar(foo[ndx[i]]);
putchar('\n');
for(i = 0; i < 16; i++)
{
ndx[i]++;
if (ndx[i] < nfoos) break;
ndx[i] = 0;
}
}
}


Very smart. A little fix:

#include <stdio.h>

int main (void)
{
static char const foo[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
unsigned const nfoos = strlen(foo);
#define N 3
unsigned ndx[N] =
{0};

while (ndx[N-1] != nfoos)
{
{
unsigned i;

for (i = 0; i < N; i++)
{
putchar (foo[ndx[i]]);
}
putchar ('\n');
}

{
unsigned i;

for (i = 0; i < N; i++)
{
ndx[i]++;
if (ndx[i] < nfoos)
{
break;
}
ndx[i] = 0;
}
}
}
return 0;
}

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"

Nov 14 '05 #8
Ken Human wrote:

Thanks, Martin. That was what I was looking for.


Quickly looking back, I see that I have at least an off-by-one error in:
char foo[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
unsigned nfoos = sizeof foo/sizeof *foo;


Other errors may be lurking there as well. That's what happens when I
code on the fly while asleep.

Nov 14 '05 #9
"Emmanuel Delahaye" <em***@YOURBRAnoos.fr> writes:
Ken Human wrote on 22/05/05 :
I want to generate every possible 16 character combination of the
characters 0-9, A-Z, and a-z programatically. My current code
follows:


Really ? It may take hours or days to print them out... Sounds like a
cracking device...


Hours or days? You'd better buy a sweater; it's going to get chilly
after the sun burns out (which will happen long before this thing is
finished).

--
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.
Nov 14 '05 #10
Martin Ambuhl wrote:
Ken Human wrote:

Thanks, Martin. That was what I was looking for.

Quickly looking back, I see that I have at least an off-by-one error in:
>> char foo[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
>> "abcdefghijklmnopqrstuvwxyz";
>> unsigned nfoos = sizeof foo/sizeof *foo;


Other errors may be lurking there as well. That's what happens when I
code on the fly while asleep.


I caught that, yes. Your idea was a good base to finish what I was
working on, thanks.
Nov 14 '05 #11
Keith Thompson wrote:
"Emmanuel Delahaye" <em***@YOURBRAnoos.fr> writes:
Ken Human wrote on 22/05/05 :
I want to generate every possible 16 character combination of the
characters 0-9, A-Z, and a-z programatically. My current code
follows:


Really ? It may take hours or days to print them out... Sounds like a
cracking device...

Hours or days? You'd better buy a sweater; it's going to get chilly
after the sun burns out (which will happen long before this thing is
finished).


I'm afraid I worded my post badly. I picked the number 16 as to
demonstrate why a large nested-loop would not look good. It's usually
stopping at 4 - 6 digits and it'll never go past 8 at the moment.
Nov 14 '05 #12
"Ken Human" <ke******@comcast.net> wrote

I was never very good at math, is the number of possible combinations
62^16? Thank you for your concern. I'm running it on the Plasmo Mag-8,
which can calculate this exact amount of data in 1 second. Needless to
say, it also has an unlimited amount of memory.
Wow. Can I have your old Plasmo Mag-8, when you upgrade to the next model?
Let's say that I want a 4 character combination.

Martin Ambuhl's code should work. Just replace the 16 with a 4.

What do you need these 16-character permutations for? I suspect that there
may be a much more efficient way of achieving it than setting the Plasmo
Mag-8 on absolutely every combination. However I can't be certain.
Nov 14 '05 #13
On Sat, 21 May 2005 19:13:09 -0500, in comp.lang.c , Ken Human
<ke******@comcast.net> wrote:
I want to generate every possible 16 character combination of the
characters 0-9, A-Z, and a-z programatically.
Thats a lot of combinations.
for(j = '0'; j <= 'z'; j++) {


this isn't guaranteed to include all the characters you want. There's
nothing in C that requires the characters to be in order from 0 to z.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Nov 14 '05 #14
Malcolm wrote:

Martin Ambuhl's code should work. Just replace the 16 with a 4.

What do you need these 16-character permutations for? I suspect that there
may be a much more efficient way of achieving it than setting the Plasmo
Mag-8 on absolutely every combination. However I can't be certain.


It's for a game, actually. During a part of the game the user is asked
to develop a way to crack a random password that consists of those 62
characters. I provide a scripting language and this particular tool,
they have to figure out how to use it in the most efficient way. The
user usually won't actually try every possible combination, unless he
doesn't understand what he's supposed to be doing.

Basically there's a rule set that's similiar to: 5 - 7 digits and must
not start with a capital letter or number.

I needed the best way to find every combination because it's possible
that the user will want to try every combination, and 16 just happens to
be the longest length of password I want to use for the game. If the
user chooses to try every combination on a 16 digit password he'll most
likely not advance.
Nov 14 '05 #15
Emmanuel Delahaye wrote:
Ken Human wrote on 22/05/05 :
I want to generate every possible 16 character combination of
the characters 0-9, A-Z, and a-z programatically. My current
code follows:


Really ? It may take hours or days to print them out... Sounds
like a cracking device...


I don't think any of you, he, or I will live to see the program run
to completion.

--
Some informative links:
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html

Nov 14 '05 #16
Keith Thompson wrote:
Hours or days? You'd better buy a sweater; it's going to get chilly
after the sun burns out (which will happen long before this thing is
finished).


If computer speeds double every 3 years, and the fastest computer at the
beginning of 2005 can run 2^30 iterations per second, then the earliest
completion date is January 20, 2124. You would buy the computer on
August 22, 2119, and it would run for 4 years, 3 months, 29 days.

Mathematica expression used:
Minimize[2005 + 3 * Log[62^16 / (2^30 * 31556952 * length)]
/ Log[2] + length, {length}]

(where 2005 is the date at which computers have the given speed,
3 is the number of years to double,
62^16 is the number of computations,
2^30 is the number of computations per second,
31556952 is the number of seconds per year,
length is how long the computation will take in years)

The length of computation for the first possible completion date is
3 / Log[2]

Interestingly, this is merely a function of the rate of speed growth,
and is entirely independent of the complexity of the problem.

The start date is: 2005 + 3 / Log[2] * Log[
31^16 / (3 / Log[2] * 31556952 * 2^14)]

As an even sillier aside, keeping the same assumptions and working
backwards, for such a "standard" computer to iterate those combinations
of length 7 was first possible in 1963, length 8 was first possible in
1981, length 9 in 1999, and length 10 will be possible in 2016.

--
Simon.
Nov 14 '05 #17
In article <42**********************@news.optusnet.com.au>,
Simon Biber <ne**@ralmin.cc> wrote:
If computer speeds double every 3 years, and the fastest computer at the
beginning of 2005 can run 2^30 iterations per second, then the earliest
completion date is January 20, 2124. You would buy the computer on
August 22, 2119, and it would run for 4 years, 3 months, 29 days.
Heh ;-)

As an even sillier aside, keeping the same assumptions and working
backwards, for such a "standard" computer to iterate those combinations
of length 7 was first possible in 1963, length 8 was first possible in
1981, length 9 in 1999, and length 10 will be possible in 2016.


I am quite not sure here what you mean by "possible". Length 10
at 2^30 per second would take about 24 3/4 years, but that's
-possible-.
--
Look out, there are llamas!
Nov 14 '05 #18
"Ken Human" <ke******@comcast.net> wrote

It's for a game, actually. During a part of the game the user is asked to
develop a way to crack a random password that consists of those 62
characters. I provide a scripting language and this particular tool, they
have to figure out how to use it in the most efficient way. The user
usually won't actually try every possible combination, unless he doesn't
understand what he's supposed to be doing.

Basically there's a rule set that's similiar to: 5 - 7 digits and must not
start with a capital letter or number.

I needed the best way to find every combination because it's possible that
the user will want to try every combination, and 16 just happens to be the
longest length of password I want to use for the game. If the user
chooses to try every combination on a 16 digit password he'll most likely
not advance.

Why not write these functions

/*
return true if a string is a valid password.
*/
int validpassword(char *str)

/*
store a password entered by the user
*/
int storepassword(char *pass)

/*
return true if the password has already been tried
*/
int paswordtried(char *pass)

/*
clear the list of stored passwords
*/
void clearattemptlist(void)

I think with these functions you can achieve what you want, without any need
for an exhaustive iteration. The whole point of a password is that it is too
difficult to enumerate all possibilities, anyway.
Nov 14 '05 #19
Malcolm wrote:
"Ken Human" <ke******@comcast.net> wrote
It's for a game, actually. During a part of the game the user is asked to
develop a way to crack a random password that consists of those 62
characters. I provide a scripting language and this particular tool, they
have to figure out how to use it in the most efficient way. The user
usually won't actually try every possible combination, unless he doesn't
understand what he's supposed to be doing.

Basically there's a rule set that's similiar to: 5 - 7 digits and must not
start with a capital letter or number.

I needed the best way to find every combination because it's possible that
the user will want to try every combination, and 16 just happens to be the
longest length of password I want to use for the game. If the user
chooses to try every combination on a 16 digit password he'll most likely
not advance.


Why not write these functions

/*
return true if a string is a valid password.
*/
int validpassword(char *str)

/*
store a password entered by the user
*/
int storepassword(char *pass)

/*
return true if the password has already been tried
*/
int paswordtried(char *pass)

/*
clear the list of stored passwords
*/
void clearattemptlist(void)

I think with these functions you can achieve what you want, without any need
for an exhaustive iteration. The whole point of a password is that it is too
difficult to enumerate all possibilities, anyway.


I'm very interested in the possibility of not having to use this type of
code on the end user's machine, but the point of this part of the game
is to write a working brute force attack that won't take forever. I
want to keep the scripting language itself as simple as possible.

To demonstrate exactly what the problem is, I'll explain the problem in
the game: The user is given an MD5 hash of a password to gain access to
a privileged part of the program. The user has an idea of how the
password is formed, and an idea of the size. So say that information is
4 - 6 digits, and the password looks like 00Ab(A?)(b?) (he got this
information by walking around in a building and looking at people typing
in their passwords).

So in the scripting language he'd write something like:

bool BruteForce(string MD5, string format) {
if(format) while(MD5 != crack(format));
else while(MD5 != crack());
}

int main(void) {
bool found = BruteForce(hash, "%N%N%L%l%?L%?l");
if(!found) return errorCode();
return 0;
}

and crack() is the previously posted code
(news://news.comcast.giganews.com:119/dS*****************@newsread2.news.atl.earthlink.n et)
that checks every combination of those 62 characters with the
modification of knowing what to do with a "string format". The actual
script does not resemble C as much and would look more complex.

My scripting language can not accomplish what crack() would, as I'm
trying to keep it minimalistic. Unfortunatley I don't really think the
ideas you posted could apply, but if you see something I don't, I'd love
to hear it.
Nov 14 '05 #20
Ken Human wrote:
and crack() is the previously posted code
(news://news.comcast.giganews.com:119/dS*****************@newsread2.news.atl.earthlink.n et)
that checks every combination of those 62 characters with the
modification of knowing what to do with a "string format".


Forgive me, I did not post the correct address to the code in question.
It is
news://news.comcast.giganews.com:119/Rs*****************@newsread2.news.atl.earthlink.n et
Nov 14 '05 #21
Walter Roberson wrote:
In article <42**********************@news.optusnet.com.au>,
Simon Biber <ne**@ralmin.cc> wrote:
If computer speeds double every 3 years, and the fastest computer at the
beginning of 2005 can run 2^30 iterations per second, then the earliest
completion date is January 20, 2124. You would buy the computer on
August 22, 2119, and it would run for 4 years, 3 months, 29 days.


Heh ;-)
As an even sillier aside, keeping the same assumptions and working
backwards, for such a "standard" computer to iterate those combinations
of length 7 was first possible in 1963, length 8 was first possible in
1981, length 9 in 1999, and length 10 will be possible in 2016.


I am quite not sure here what you mean by "possible". Length 10
at 2^30 per second would take about 24 3/4 years, but that's
-possible-.


Yes, but if computers capable of 2^30 per second are not available until
2005, and it takes 24 3/4 years, then it won't finish by the year 2016,
will it?

I mean that the earliest possible completion date is 2016, and that will
only be possible if you wait until around 2012 to buy the computer, so
it will complete in only 4 years.

--
Simon.
Nov 14 '05 #22

In article <ln************@nuthaus.mib.org>, Keith Thompson <ks***@mib.org> writes:
"Emmanuel Delahaye" <em***@YOURBRAnoos.fr> writes:
Ken Human wrote on 22/05/05 :
I want to generate every possible 16 character combination of the
characters 0-9, A-Z, and a-z programatically. My current code
follows:


Really ? It may take hours or days to print them out... Sounds like a
cracking device...


Hours or days? You'd better buy a sweater; it's going to get chilly
after the sun burns out (which will happen long before this thing is
finished).


Yes, but it still sounds like a cracking device, Dangermouse!

Of course, there's no need to generate them anyway. We already have
the list, in a handy compressed form that allows random access. Just
pick an integer between 0 and 62**16-1 and convert it into its base-
62 representation. A function implementing that algorithm serves as
the "array" of values, and its parameter as the "index".

Iteration is slower than iterating through an actual array, but since
constructing the actual array is, er, infeasible, that hardly matters.

(64 characters would actually be better here, since converting a
number in "pure binary" representation to base 64 is easier than
converting to base 62, but neither is difficult.)

--
Michael Wojcik mi************@microfocus.com

Push up the bottom with your finger, it will puffy and makes stand up.
-- instructions for "swan" from an origami kit
Nov 14 '05 #23
Michael Wojcik wrote:
Keith Thompson <ks***@mib.org> writes:
"Emmanuel Delahaye" <em***@YOURBRAnoos.fr> writes:
> Ken Human wrote on 22/05/05 : I want to generate every possible 16 character combination of
the characters 0-9, A-Z, and a-z programatically. My current
code follows:

Really ? It may take hours or days to print them out... Sounds
like a cracking device...


Hours or days? You'd better buy a sweater; it's going to get
chilly after the sun burns out (which will happen long before
this thing is finished).


Yes, but it still sounds like a cracking device, Dangermouse!

Of course, there's no need to generate them anyway. We already
have the list, in a handy compressed form that allows random
access. Just pick an integer between 0 and 62**16-1 and convert
it into its base-62 representation. A function implementing that
algorithm serves as the "array" of values, and its parameter as
the "index".

Iteration is slower than iterating through an actual array, but
since constructing the actual array is, er, infeasible, that
hardly matters.

(64 characters would actually be better here, since converting a
number in "pure binary" representation to base 64 is easier than
converting to base 62, but neither is difficult.)


Having a handy number to stream in base routine, I tried diddling
it to go up to base 64, basically by modifying the digit conversion
routine below:

/* Mask and convert digit to hex representation */
/* Output range is 0..9 and a..v only (base 32) */
static int hexify(unsigned int value)
{
static char hexchars[] = "0123456789abcdef"
"ghijklmnopqrstuv"
"wxyzABCDEFGHIJKL"
"MNOPQRSTUVWXYZ@#";

/* allow for terminal '\0' */
#define MAXBASE 64 /*(sizeof(hexchars)-1)*/

return (hexchars[value & (MAXBASE-1)]);
} /* hexify */

What I want to do is keep hexchars private, and export the value of
MAXBASE, computed from the actual hexchars definition. Doesn't
work, because hexchars is undefined when the macro is expanded.
Can I get around this? The macro needs to be evaluated at the
declaration point.

--
Some useful references about C:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://www.eskimo.com/~scs/C-faq/top.html>
<http://benpfaff.org/writings/clc/off-topic.html>
<http://anubis.dkuug.dk/jtc1/sc22/wg14/www/docs/n869/> (C99)
<http://www.dinkumware.com/refxc.html> (C-library}
<http://gcc.gnu.org/onlinedocs/> (GNU docs)
Nov 14 '05 #24

In article <42***************@yahoo.com>, CBFalconer <cb********@yahoo.com> writes:

static int hexify(unsigned int value)
{
static char hexchars[] = "0123456789abcdef"
"ghijklmnopqrstuv"
"wxyzABCDEFGHIJKL"
"MNOPQRSTUVWXYZ@#";

/* allow for terminal '\0' */
#define MAXBASE 64 /*(sizeof(hexchars)-1)*/

return (hexchars[value & (MAXBASE-1)]);
} /* hexify */

What I want to do is keep hexchars private, and export the value of
MAXBASE, computed from the actual hexchars definition. Doesn't
work, because hexchars is undefined when the macro is expanded.
Can I get around this? The macro needs to be evaluated at the
declaration point.


I can't see any way of doing that - sizeof needs an object of complete
type.

As an alternative, you could always make MAXBASE a fixed value in your
header, then do a compile-time check to verify that it's the same as
sizeof hexchars in the C file:

#include "hexify.h"

static int hexify(unsigned int value)
{
static char hexchars[] = "0123456789abcdef"
"ghijklmnopqrstuv"
"wxyzABCDEFGHIJKL"
"MNOPQRSTUVWXYZ@#";

#if sizeof hexchars != MAXBASE
#error "MAXBASE is defined incorrectly"
#endif

Not as satisfying as having MAXBASE computed automatically, but it
does at least catch skew between the header and the implementation.

--
Michael Wojcik mi************@microfocus.com

[After the lynching of George "Big Nose" Parrot, Dr. John] Osborne
had the skin tanned and made into a pair of shoes and a medical bag.
Osborne, who became governor, frequently wore the shoes.
-- _Lincoln [Nebraska] Journal Star_
Nov 14 '05 #25
Michael Wojcik wrote:

As an alternative, you could always make MAXBASE a fixed value in your
header, then do a compile-time check to verify that it's the same as
sizeof hexchars in the C file:

static int hexify(unsigned int value)
{
static char hexchars[] = "0123456789abcdef"
"ghijklmnopqrstuv"
"wxyzABCDEFGHIJKL"
"MNOPQRSTUVWXYZ@#";

#if sizeof hexchars != MAXBASE
#error "MAXBASE is defined incorrectly"
#endif

Not as satisfying as having MAXBASE computed automatically, but it
does at least catch skew between the header and the implementation.


You can't use 'sizeof' in a preprocessor test, because the
preprocessing is done before the compiling!

Although I have seen a preprocessor that supports what you
suggest, it is uncommon and non-standard.

Nov 14 '05 #26

In article <11**********************@z14g2000cwz.googlegroups .com>, "Old Wolf" <ol*****@inspire.net.nz> writes:
Michael Wojcik wrote:

#if sizeof hexchars != MAXBASE
#error "MAXBASE is defined incorrectly"
#endif
You can't use 'sizeof' in a preprocessor test,


Ugh. Right. Didn't engage my brain.

You'd have to use a macro for the size of the hexchars array in the
first place; the appropriate thing would be to put MAXBASE in the
header and then use it as the explicit length of the hexchars array.
because the preprocessing is done before the compiling!


Well, no, it isn't, strictly speaking. "Preprocessing" is trans-
lation phase 4. The standard doesn't define "compiling", but I'd
consider it the entire translation process. You might consider, say,
translation phase 7 "compiling", but the term is open to interpre-
tation.

(I also note that the grammar in C90 Annex B implies that you *can*
use sizeof in a #if expression, as constant-expressions include
relational-expressions which can include unary-expressions which
include the sizeof operator applied to another unary-expression;
but this is just another case where the grammar is not the whole
story. The constraints in 6.8.1 include other restrictions.)

--
Michael Wojcik mi************@microfocus.com

Thanatos, thanatos! The labourer, dropping his lever,
Hides a black letter close to his heart and goes,
Thanatos, thanatos, home for the day and for ever. -- George Barker
Nov 14 '05 #27
"Old Wolf" <ol*****@inspire.net.nz> writes:
[...]
You can't use 'sizeof' in a preprocessor test, because the
preprocessing is done before the compiling!

Although I have seen a preprocessor that supports what you
suggest, it is uncommon and non-standard.


Dennis Ritchie posted something on this topic in comp.std.c back in
1998 (sorry, groups.google.com mangled some of the headers):

] From: Dennis Ritchie <d...@bell-labs.com>
] Subject: Re: Computing sizeof() during compilation
] Date: 1998/05/08
] Message-ID: <35***********@bell-labs.com>#1/1
] References: <6i**********@client3.news.psi.net> <de**************@netcom.com>
] Organization: Bell Labs, Lucent Technologies
] Reply-To: d...@bell-labs.com
] Newsgroups: comp.std.c
]
]
] > You are right. It was nice back in the days when things like
] >
] > #if (sizeof(int) == 8)
] >
] > actually worked (on some compilers).
]
] Must have been before my time.
]
] Dennis

--
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.
Nov 14 '05 #28

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

51 posts views Thread by Mudge | last post: by
8 posts views Thread by Max M | last post: by
reply views Thread by Rasmus Fogh | last post: by
2 posts views Thread by Alan Robert Clark | last post: by
9 posts views Thread by Java script Dude | last post: by
12 posts views Thread by Charlie | last post: by
3 posts views Thread by Eddy Ilg | last post: by
31 posts views Thread by eliben | last post: by
6 posts views Thread by James Arnold | last post: by
13 posts views Thread by Tony Johansson | last post: by
reply views Thread by devrayhaan | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.