diff --git a/1985/lycklama/Makefile b/1985/lycklama/Makefile index a5565d8f3..858bd0d80 100644 --- a/1985/lycklama/Makefile +++ b/1985/lycklama/Makefile @@ -58,7 +58,7 @@ ARCH= # Defines that are needed to compile # -CDEFINE= -DZ=500 +CDEFINE= -DZ=${SLEEP} # Include files that are needed to compile # @@ -137,6 +137,13 @@ ${PROG}: ${PROG}.c alt: data ${ALT_TARGET} @${TRUE} +# variable to control amount of time to sleep between writes for alt code. +SLEEP=500 + +${PROG}.alt: ${PROG}.alt.c + ${CC} ${CFLAGS} -DZ=${SLEEP} $< -o $@ ${LDFLAGS} + + # data files # data: ${DATA} diff --git a/1985/lycklama/README.md b/1985/lycklama/README.md index 984b319fd..1cfb41ccb 100644 --- a/1985/lycklama/README.md +++ b/1985/lycklama/README.md @@ -12,7 +12,7 @@ make alt ``` To see why we recommend the alternate version instead of the original version, -see below and the [original code](#original-code) section. +see below and the [Original code](#original-code) section. ### Try: @@ -25,7 +25,7 @@ reconfigure it like: ```sh -make CDEFINE+="-DZ=700" clobber alt +make SLEEP=700 clobber alt ``` which would set it at 700. Then, whether you use the default value or not, try: diff --git a/1985/shapiro/Makefile b/1985/shapiro/Makefile index b25f0e5b2..6aa897cc0 100644 --- a/1985/shapiro/Makefile +++ b/1985/shapiro/Makefile @@ -58,7 +58,7 @@ ARCH= # Defines that are needed to compile # -CDEFINE= -DC=39 +CDEFINE= -DC=${SIZE} # Include files that are needed to compile # @@ -136,8 +136,11 @@ ${PROG}: ${PROG}.c alt: data ${ALT_TARGET} @${TRUE} +# variable to control size of maze for alt code +SIZE= 39 + ${PROG}.alt: ${PROG}.alt.c - ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} + ${CC} ${CFLAGS} -DC=${SIZE} $< -o $@ ${LDFLAGS} # data files # diff --git a/1985/shapiro/README.md b/1985/shapiro/README.md index 2471841c0..ab23af709 100644 --- a/1985/shapiro/README.md +++ b/1985/shapiro/README.md @@ -5,7 +5,7 @@ make all ``` There is alternate code which allows one to change the size of the maze. See -[alternate code](#alternate-code) below. +[Alternate code](#alternate-code) below. ### To run: @@ -32,7 +32,7 @@ make alt If you wish to change the value you can do it like: ```sh -make clobber CDEFINE="-DC=5" alt +make clobber SIZE=5 alt ``` Note that if it is not a number then obviously there will be a compilation diff --git a/1985/shapiro/try.alt.sh b/1985/shapiro/try.alt.sh index b5cbfdc43..6ab48c125 100755 --- a/1985/shapiro/try.alt.sh +++ b/1985/shapiro/try.alt.sh @@ -25,7 +25,8 @@ while ((i < 5)); do fi read -r -n 1 -p "Press any key to set to $C: " - make clobber CC="$CC" CDEFINE="-DC=$C" alt >/dev/null + echo 1>&2 + make clobber CC="$CC" SIZE="$C" alt >/dev/null ./shapiro.alt ((i++)) done @@ -39,7 +40,7 @@ while :; do # ^-- SC2143 (style): Use grep -q instead of comparing output with [ -n .. ]. # shellcheck disable=SC2143 if [[ $(echo "$REPLY" | grep -E '\<[0-9]+\>') ]]; then - make clobber CC="$CC" CDEFINE="-DC=\"$REPLY\"" alt >/dev/null + make clobber CC="$CC" SIZE="$REPLY" alt >/dev/null ./shapiro.alt else exit 0 diff --git a/1991/rince/Makefile b/1991/rince/Makefile index 681278ff1..9c60e9201 100644 --- a/1991/rince/Makefile +++ b/1991/rince/Makefile @@ -58,7 +58,7 @@ ARCH= # Defines that are needed to compile # -CDEFINE= -DMAX_MOVES=484 +CDEFINE= -DMAX_MOVES=${MAXMOVES} # Include files that are needed to compile # @@ -137,11 +137,13 @@ ${PROG}: ${PROG}.c alt: data ${ALT_TARGET} @${TRUE} +# variable to control max number of moves +MAXMOVES= 484 ${PROG}.alt: ${PROG}.alt.c ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} ${PROG}2.alt: ${PROG}.alt2.c - ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} + ${CC} ${CFLAGS} -DMAX_MOVES=${MAXMOVES} $< -o $@ ${LDFLAGS} # data files # diff --git a/1991/rince/README.md b/1991/rince/README.md index f936ed236..7ed7df087 100644 --- a/1991/rince/README.md +++ b/1991/rince/README.md @@ -20,9 +20,10 @@ that's fewer than the original program. The first alternate version, [rince.alt.c](rince.alt.c), disables a maximum move count so that anyone with enough patience and time can complete the puzzle, -without having to worry about how many moves they make. The second version, -[rince.alt2.c](rince.alt2.c), allows one to reconfigure at compilation the -maximum number of moves, even if that is lowering the count. +without having to worry about how many moves they make, assuming they don't get +stuck. The second version, [rince.alt2.c](rince.alt2.c), allows one to +reconfigure at compilation the maximum number of moves, even if that is lowering +the count. The author set the maximum number of moves to 484. @@ -39,12 +40,13 @@ restrictions in the number of movements and the second one, `rince.alt2`, has a configurable maximum number of moves allowed, defaulting to the entry's max, 484. -To reconfigure the maximum number of moves: +To reconfigure the maximum number of moves to 700: ```sh -make clobber CDEFINE+="-DMAX_MOVES=5" alt +make clobber MAXMOVES=700 alt ``` + ### Alternate use: To run the first alt version: diff --git a/1992/kivinen/Makefile b/1992/kivinen/Makefile index 0aae99170..730917f9d 100644 --- a/1992/kivinen/Makefile +++ b/1992/kivinen/Makefile @@ -59,7 +59,7 @@ ARCH= # Defines that are needed to compile # -CDEFINE= -DZ=20000 +CDEFINE= -DZ=${SLEEP} # Include files that are needed to compile # @@ -138,6 +138,12 @@ ${PROG}: ${PROG}.c alt: data ${ALT_TARGET} @${TRUE} +# variable to control amount of time to sleep between writes for alt code. +SLEEP= 20000 +${PROG}.alt: ${PROG}.alt.c + ${CC} ${CFLAGS} -DZ=${SLEEP} $< -o $@ ${LDFLAGS} + + # data files # data: ${DATA} diff --git a/1992/kivinen/README.md b/1992/kivinen/README.md index 6e86a1a4f..8f9458e96 100644 --- a/1992/kivinen/README.md +++ b/1992/kivinen/README.md @@ -39,9 +39,9 @@ Also try changing the speed this game moves. For instance if you wish to change the `usleep(3)` value to `30000` from `20000`, try: ```sh -make clobber CDEFINE="-DZ=30000" alt # make it slower +make clobber SLEEP=30000 alt # make it slower -make clobber CDEFINE="-DZ=10000" alt # make it faster +make clobber SLEEP=10000 alt # make it faster ``` Then use the same syntax as above and described by the author. diff --git a/1993/cmills/Makefile b/1993/cmills/Makefile index 967ece1e9..85af27aab 100644 --- a/1993/cmills/Makefile +++ b/1993/cmills/Makefile @@ -57,7 +57,7 @@ ARCH= # Defines that are needed to compile # -CDEFINE= -DZ=100 +CDEFINE= -DZ=${SLEEP} # Include files that are needed to compile # @@ -141,8 +141,11 @@ chris: ${PROG} alt: data ${ALT_TARGET} @${TRUE} +# variable to control how long to sleep in alt version between updates +SLEEP= 100 + ${PROG}.alt: ${PROG}.alt.c - ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} + ${CC} ${CFLAGS} -DZ=${SLEEP} $< -o $@ ${LDFLAGS} # data files # diff --git a/1993/cmills/README.md b/1993/cmills/README.md index 15ad711c1..eae5bc027 100644 --- a/1993/cmills/README.md +++ b/1993/cmills/README.md @@ -12,7 +12,7 @@ make alt To configure how many microseconds to sleep before updates try: ```sh -make clobber CDEFINE="-DZ=200" alt +make clobber SLEEP=200 alt ``` NOTE: this entry requires `X11/Xlib.h` header file and the X11 library to @@ -32,7 +32,6 @@ STATUS: known bug - please help us fix For more detailed information see [1993 cmills in bugs.md](/bugs.md#1993-cmills). - ## To use: ```sh diff --git a/1993/plummer/Makefile b/1993/plummer/Makefile index b1c56da2e..8107ae4e8 100644 --- a/1993/plummer/Makefile +++ b/1993/plummer/Makefile @@ -58,7 +58,7 @@ ARCH= # Defines that are needed to compile # -CDEFINE= -DZ=200 +CDEFINE= -DZ=${SLEEP} # Include files that are needed to compile # @@ -138,8 +138,10 @@ ${PROG}: ${PROG}.c alt: data ${ALT_TARGET} @${TRUE} +# variable to control how long to sleep in alt version +SLEEP= 200 ${PROG}.alt: ${PROG}.alt.c - ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} + ${CC} ${CFLAGS} -DZ=${SLEEP} $< -o $@ ${LDFLAGS} # data files # diff --git a/1993/plummer/README.md b/1993/plummer/README.md index 26de8dda2..7d6288840 100644 --- a/1993/plummer/README.md +++ b/1993/plummer/README.md @@ -44,7 +44,7 @@ make alt If you wish to change the time to sleep (default `200`) you can do so like: ```sh -make clobber CDEFINE="-DZ=50" alt +make clobber SLEEP=50 alt ``` diff --git a/1993/rince/.gitignore b/1993/rince/.gitignore index c935df6bd..9bee489dc 100644 --- a/1993/rince/.gitignore +++ b/1993/rince/.gitignore @@ -1,4 +1,6 @@ jkb +jkb.alt +jkb.alt2 rince rince.orig rince.alt diff --git a/1993/rince/Makefile b/1993/rince/Makefile index badac181e..b0d789b75 100644 --- a/1993/rince/Makefile +++ b/1993/rince/Makefile @@ -58,7 +58,7 @@ ARCH= # Defines that are needed to compile # -CDEFINE= -DZ=17 +CDEFINE= -DZ=${SLEEP} # Include files that are needed to compile # @@ -143,6 +143,24 @@ jkb: ${PROG} alt: data ${ALT_TARGET} @${TRUE} +# variable to control how long to sleep in alt version +SLEEP= 17 + +${PROG}.alt: ${PROG}.alt.c + ${CC} ${CFLAGS} -DZ=${SLEEP} $< -o $@ ${LDFLAGS} + +${PROG}.alt2: ${PROG}.alt2.c + ${CC} ${CFLAGS} -DZ=${SLEEP} $< -o $@ ${LDFLAGS} + +jkb.alt: ${PROG}.alt + ${RM} -f $@ + ${LN} $< $@ + +jkb.alt2: ${PROG}.alt + ${RM} -f $@ + ${LN} $< $@ + + # data files # data: ${DATA} diff --git a/1993/rince/README.md b/1993/rince/README.md index c2d4cbeb6..63e218c73 100644 --- a/1993/rince/README.md +++ b/1993/rince/README.md @@ -20,8 +20,6 @@ STATUS: INABIAF - please **DO NOT** fix For more detailed information see [1993 rince in bugs.md](/bugs.md#1993-rince). - - ## To use: ```sh @@ -61,7 +59,7 @@ changed). ```sh -make CDEFINE="-DZ=18" clobber alt +make SLEEP=18 clobber alt ``` Replace 18 with whatever number you wish. diff --git a/1994/dodsond2/Makefile b/1994/dodsond2/Makefile index d93a70cab..2c276590a 100644 --- a/1994/dodsond2/Makefile +++ b/1994/dodsond2/Makefile @@ -58,7 +58,7 @@ ARCH= # Defines that are needed to compile # -CDEFINE= -DW=3 +CDEFINE= -DW=${ARROWS} # Include files that are needed to compile # @@ -138,8 +138,11 @@ ${PROG}: ${PROG}.c alt: data ${ALT_TARGET} @${TRUE} +# variable to allow overriding how many arrows to start with +ARROWS= 3 + ${PROG}.alt: ${PROG}.alt.c - ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} + ${CC} ${CFLAGS} -DW=${ARROWS} $< -o $@ ${LDFLAGS} # data files # diff --git a/1994/dodsond2/README.md b/1994/dodsond2/README.md index 5c86b55e4..dcfd713d2 100644 --- a/1994/dodsond2/README.md +++ b/1994/dodsond2/README.md @@ -46,7 +46,7 @@ The default number of arrows in this version is 3 but if you want to change it, say to 5, try: ```sh -make clobber CDEFINE="-DW=5" alt +make clobber ARROWS=5 alt ``` diff --git a/1998/banks/Makefile b/1998/banks/Makefile index 315611910..2097f2162 100644 --- a/1998/banks/Makefile +++ b/1998/banks/Makefile @@ -57,11 +57,21 @@ CSTD= -std=gnu90 # ARCH= +# variables that control the control keys + +IT= XK_Page_Up +DT= XK_Page_Down +UP= XK_Up +DN= XK_Down +LT= XK_Left +RT= XK_Right +CS= XK_Return +dt= 0.02 # Defines that are needed to compile # -CDEFINE= -DIT=XK_Page_Up -DDT=XK_Page_Down \ - -DUP=XK_Up -DDN=XK_Down -DLT=XK_Left -DRT=XK_Right \ - -DCS=XK_Return -Ddt=0.02 +CDEFINE= -DIT=${IT} -DDT=${DT} \ + -DUP=${UP} -DDN=${DN} -DLT=${LT} -DRT=${RT} \ + -DCS=${CS} -Ddt=${dt} # Include files that are needed to compile # @@ -142,8 +152,7 @@ alt: data ${ALT_TARGET} @${TRUE} ${PROG}.alt: ${PROG}.c - ${CC} ${CFLAGS} -UIT -UDT -DIT=XK_f -DDT=XK_d -DUP=XK_Up -DDN=XK_Down -DLT=XK_Left -DRT=XK_Right \ - -DCS=XK_Return -Ddt=0.02 $< -o $@ ${LDFLAGS} + ${CC} ${CFLAGS} -UIT -UDT -DIT=XK_f -DDT=XK_d $< -o $@ ${LDFLAGS} # data files diff --git a/1998/banks/README.md b/1998/banks/README.md index b2934e52c..563eb18c2 100644 --- a/1998/banks/README.md +++ b/1998/banks/README.md @@ -4,10 +4,59 @@ make all ``` + + +You may redefine all the keys and the time step with predefined macros. The +author provided the following able: + +``` +Control Description Default Key +------- ------------------------- ----------- + IT Increase throttle XK_Page_Up + DT Decrease throttle XK_Page_Down + FD Move stick forward XK_Up + BK Move stick back XK_Down + LT Move stick left XK_Left + RT Move stick right XK_Right + CS Center stick XK_Enter +``` + +There is another macro, `dt`, which is the time step. See some important points +on this in the author's comments in the [Alternate Build +Instructions](#alternate-build-instructions) section. + +If however you wish to change the above controls, see the header file +[keysym.h](keysym.h) for the definitions of other characters that you might wish +to use. The name of the macro in the header file is what you need to set the +macros to, depending on what controls you wish to redefine. For instance, to set +the throttle up and down to `u` and `d`: + + +```sh +make clobber IT=XK_u DT=XK_d all +``` + +because in the header file you can see that `XK_u` corresponds to `u` and `XK_d` +corresponds to `d`: + +```c +#define XK_d 0x0064 /* U+0064 LATIN SMALL LETTER D */ +#define XK_u 0x0075 /* U+0075 LATIN SMALL LETTER U */ +``` + +Note that the [keysym.h](keysym.h) file is not complete from X11; it's just the +more likely candidates (and some that are probably unlikely :-) ). + +The upper case letters would be `XK_U` and `XK_D` and you can search the header +file for 'LATIN CAPITAL D', for example. + For those who do not have a Page Up or Page Down key, see [alternate -code](#alternate-code) below. The same method may be used if you wish to -redefine other keys but the alt build sets a default for those without page up -and page down. +code](#alternate-code) below. The difference from the alt build and the original +entry is that the page up and page down keys are defined to a default but they +are hard coded as doing otherwise would necessarily complicate the build +instructions. Since you can use the original entry to redefine these this is not +a problem and is purely a convenience .. if only for those who are okay with the +preselected alternative keys. ## To use: @@ -33,62 +82,35 @@ you can regain control? If you do not have access to a page up or page down key, for instance you're using a Mac, you can use the alt code (though it actually uses the same code) that will redefine the keys to increase throttle and decrease throttle. This -same method can be used with the original code but this is sets up a default for -the missing keys of Macs. +same method can be used with the original code but this sets up predefined keys +in place of Page Up and Page Down. -The keys were somewhat arbitrarily selected but it was decided to make them on -the left side of the keyboard as one might have a harder time using the arrows -at the same time as typing on the right side. +The keys were somewhat arbitrarily selected but it was decided to make them both +on the left side of a QWERTY keyboard as one might have a harder time using the +arrows at the same time as typing on the right side. ### Alternate build: As the Makefile allows you to configure the keys to use you may redefine the -keys. This can be done for both versions but if you don't have certain keys it's -even more important. In the main program increasing throttle is by page up and -decreasing throttle is page down. In the alt build it is `f` and `d` -respectively as these are letters on the left side of the keyboard which is -easier to use if one is using the right side for movement. +keys but with the alt build you cannot, as described earlier, redefine the page +up and page down replacement keys. If you want to do that you should use the +original entry as described in the to build section above. -To use the default changes: +In the alt build it is `f` and `d` respectively as these are letters on the left +side of the keyboard which is easier to use if one is using the right side for +movement. These are hard coded, as noted. + +To use the default settings for the alternate build: ```sh make alt ``` -If however you wish to change these, see the header file [keysym.h](keysym.h) -for the definitions of other characters that you might wish to use. The name of -the macro in the header file is what you need to set the macros in the Makefile -to, depending on what controls you wish to redefine. +You may change the other keys as described in the build instructions, above, but +this alt code can be seen as an alternative for those who don't have or don't +want to use page up and page down. -For instance if you want to use 'u' to increase throttle and 'd' to decrease -throttle you would do: - -```sh -make clobber CDEFINE="-UIT -UDT -DIT=XK_u -DDT=XK_d -DUP=XK_Up -DDN=XK_Down -DLT=XK_Left -DRT=XK_Right \ - -DCS=XK_Return" alt -``` - -because in the header file you can see that `XK_u` corresponds to `u` and `XK_d` -corresponds to `d`: - -```c -#define XK_d 0x0064 /* U+0064 LATIN SMALL LETTER D */ -#define XK_u 0x0075 /* U+0075 LATIN SMALL LETTER U */ -``` - -Note that you must specify all keys and other `-D` macros if you redefine any of -them. - -The upper case letters would be `XK_U` and `XK_D` and you can search the header -file for 'LATIN CAPITAL D', for example. - -See [alternate build instructions](#alternate-build-instructions) for the proper -macro names. You may do the above for the entry itself as well, of course, if -you do not like the defaults selected. - -Note that the [keysym.h](keysym.h) file is not complete from X11; it's just the -more likely candidates (and some that are probably unlikely :-) ). ### Alternate use: @@ -133,6 +155,7 @@ indicator, or compass. 0 is north, 90 is east, 180 is south, 270 is west. The third instrument is the altimeter, which measures your height above ground level in feet. + ### Features * Simulator models a [Piper @@ -241,8 +264,10 @@ to default values. Use this section if you want to compile with different options. To map a key to a control, you must pass an option to the -compiler in the format `-Dcontrol=key`. The possible controls -you can map are described in the table below: +compiler in the format `-Dcontrol=key` or if you use the Makefile you can do +`make control=key`. + +The possible controls you can map are described in the table below: ``` Control Description Default Key @@ -260,16 +285,14 @@ Values for the possible keys can be found in the X Windows header file ``. This file is most likely a cross-reference to another header, ``. -You must map all seven controls to keys at compile time, or the -compilation will fail. - For example, to map Center Stick to the space-bar, the compile -option would be `-DCS=XK_space`. +option would be `-DCS=XK_space` or `make CS=XK_space`. To set the time step size, you must pass the following option to the compiler: `-Ddt=duration`, where `dt` is literal, and where -`duration` is the time in seconds you want the time step to be. +`duration` is the time in seconds you want the time step to be. Alternatively, +if you use the provided Makefile, you may just do `make dt=time`. Two things to keep in mind when selecting a time step. Time steps that are too large (more than about `0.03`) will cause diff --git a/1998/schweikh3/Makefile b/1998/schweikh3/Makefile index d7e2f2bab..fefa31df9 100644 --- a/1998/schweikh3/Makefile +++ b/1998/schweikh3/Makefile @@ -55,10 +55,13 @@ CSTD= -std=gnu90 # ARCH= +# variable for size, primarily for alt code +# +SIZE=32767 # Defines that are needed to compile # CDEFINE= -DM0=sizeof -DM1=long -DM2=void \ - -DM3=realloc -DM4=calloc -DM5=free -DSZ=32767 + -DM3=realloc -DM4=calloc -DM5=free -DSZ=${SIZE} # Include files that are needed to compile # @@ -138,6 +141,11 @@ ${PROG}: ${PROG}.c alt: data ${ALT_TARGET} @${TRUE} + +${PROG}.alt: ${PROG}.alt.c + ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} + ${LN} -sf $@ samefile.alt + # data files # data: ${DATA} diff --git a/1998/schweikh3/README.md b/1998/schweikh3/README.md index aac682d00..190aca9ab 100644 --- a/1998/schweikh3/README.md +++ b/1998/schweikh3/README.md @@ -54,11 +54,10 @@ If you wish to change the size to say, 55555: ```sh -make clobber CDEFINE="-DSZ=55555" alt +make clobber SIZE=55555 alt ``` -or whatever you wish to redefine it to. See [alternate code](#alternate-code) -below. +or whatever you wish to redefine it to. ## Judges' remarks: diff --git a/2000/thadgavin/Makefile b/2000/thadgavin/Makefile index 8ed8c5916..551244ba6 100644 --- a/2000/thadgavin/Makefile +++ b/2000/thadgavin/Makefile @@ -56,9 +56,13 @@ CSTD= -std=gnu99 # ARCH= +# variables for redefining the time to sleep, primarily for alt code +# +SLEEP= 30 +SDL_SLEEP= 150000 # Defines that are needed to compile # -CDEFINE= -DZ=30 -DZS=150000 +CDEFINE= -DZ=${SLEEP} -DZS=${SDL_SLEEP} # Include files that are needed to compile # diff --git a/2000/thadgavin/README.md b/2000/thadgavin/README.md index c27eaf4ed..748218453 100644 --- a/2000/thadgavin/README.md +++ b/2000/thadgavin/README.md @@ -37,8 +37,10 @@ You might also care to reconfigure the speed at which the programs run. The code calls `usleep(3)` with two default values, one for SDL and one for curses. The curses and SDL macros are defined respectively in the Makefile: -``` --DZ=30 -DZS=150000 +```make +SLEEP= 30 +SDL_SLEEP= 150000 +CDEFINE= -DZ=${SLEEP} -DZS=${SDL_SLEEP} ``` which corresponds to how long the program sleeps (in microseconds) between @@ -47,19 +49,20 @@ to the defaults as above so that you don't have to specify both just to configure one. To change the SDL one to something like `15000` you can do: ```sh -make CDEFINE="-DZS=15000" clobber alt +make SDL_SLEEP=15000 clobber alt ``` and to change the curses one to `40`: ```sh -make CDEFINE="-DZ=40" clobber alt +make SLEEP=40 clobber alt ``` Then use the program(s) in the same way. The different macros is because the curses version is already much slower and so -it's better to not tie the two values together. +it's better to not tie the two values together. You may of course combine them +in one command. ## Original code: diff --git a/2001/kev/Makefile b/2001/kev/Makefile index 4449ffbc6..ff6d6e312 100644 --- a/2001/kev/Makefile +++ b/2001/kev/Makefile @@ -57,9 +57,15 @@ CSTD= -std=gnu99 # ARCH= +# variables for the macros for easier redefining +# +PORT= 5455 +SPEED= 100 +L= "socket(il.sin_family=AF_INET,SOCK_STREAM,0)" + # Defines that are needed to compile # -CDEFINE= -DPORT=5455 -DSPEED=100 -Dl_="socket(il.sin_family=AF_INET,SOCK_STREAM,0)" +CDEFINE= -DPORT=${PORT} -DSPEED=${SPEED} -Dl_=${L} # Include files that are needed to compile # diff --git a/2001/kev/README.md b/2001/kev/README.md index 98580b79f..de2ab8b34 100644 --- a/2001/kev/README.md +++ b/2001/kev/README.md @@ -42,23 +42,24 @@ If you need to change the speed you can reconfigure it like (say for over a network and not the same host): ```sh -make clobber CDEFINE="-DSPEED=50" all # original default value which is very fast +make clobber SPEED=50 all # original default value which is very fast ``` If you wish to change the port you can do so like: ```sh -make clobber CDEFINE="-DPORT=3773" all +make clobber PORT=3773 all ``` Of course if you want a port < 1024 you'll need to be root so don't do that. And if you know what you're doing you can redefine the call to the `socket(2)` -syscall with the `l_` macro. Of course you can do more than one at the same -time. For instance to change the speed and port: +syscall with the `l_` macro, changing the `L` variable like one would `PORT`. Of +course you can do more than one at the same time. For instance to change the +speed and port: ```sh -make clobber CDEFINE="-DSPEED=512 -DPORT=3773" all +make clobber SPEED=512 PORT=3773 all ``` If you have `xterm` try on one system: diff --git a/2004/gavare/Makefile b/2004/gavare/Makefile index 673fc7fd4..18fd65c94 100644 --- a/2004/gavare/Makefile +++ b/2004/gavare/Makefile @@ -56,9 +56,13 @@ CSTD= -std=gnu99 # ARCH= +# variables for the macros for easier redefining +XX= 1024 +YY= 768 +AA= 3 # Defines that are needed to compile # -CDEFINE= -DXX=1024 -DYY=768 -DAA=3 +CDEFINE= -DXX=${XX} -DYY=${YY} -DAA=${AA} # Include files that are needed to compile # diff --git a/2004/gavare/README.md b/2004/gavare/README.md index 21c046b6c..598d2da01 100644 --- a/2004/gavare/README.md +++ b/2004/gavare/README.md @@ -46,17 +46,17 @@ make alt To change the default size from 1024x768 try: ```sh -make clobber CDEFINE="-DXX=640 -DYY=480" alt +make clobber XX=640 YY=480 alt ``` You might also wish to change the anti-alias setting: ```sh -make clobber CDEFINE="-DAA=2" alt +make clobber AA=2 alt ``` -This is not possible with the author's version but it is with the Windows -version (see below). +This is not possible with the author's version but it is with the alt versions +(Windows - see below - and otherwise). As the Windows version will not compile on most viewers' systems we do not build it with `make alt`; instead try: diff --git a/2004/jdalbec/Makefile b/2004/jdalbec/Makefile index 6758a837b..c3ffea978 100644 --- a/2004/jdalbec/Makefile +++ b/2004/jdalbec/Makefile @@ -56,9 +56,12 @@ CSTD= -ansi # ARCH= +# variable for redefining macro Ag +# +Ag= 11 # Defines that are needed to compile # -CDEFINE= -DAg=11 +CDEFINE= -DAg=${Ag} # Include files that are needed to compile # diff --git a/2004/jdalbec/README.md b/2004/jdalbec/README.md index 041f9f023..8ce367774 100644 --- a/2004/jdalbec/README.md +++ b/2004/jdalbec/README.md @@ -52,7 +52,7 @@ you wish to make it silver, 47 (a prime) protons, do: ```sh -make clobber CDEFINE="-DAg=47" alt +make clobber Ag=47 alt ``` though it might be odd to have 47 numbers on a line as it would defeat the @@ -60,7 +60,7 @@ purpose. :-) Or if you prefer some prime, golden irony: ```sh -make clobber CDEFINE="-DAg=79" alt +make clobber Ag=79 alt ``` diff --git a/2006/monge/Makefile b/2006/monge/Makefile index 3b6fc5d4a..f1e5045bf 100644 --- a/2006/monge/Makefile +++ b/2006/monge/Makefile @@ -143,8 +143,14 @@ ${PROG}: ${PROG}.c alt: data ${ALT_TARGET} @${TRUE} +# variables to help redefine width, height or iterations in alt version +# +WIDTH= 400 +HEIGHT= 300 +ITERATIONS= 128 + ${PROG}.alt: ${PROG}.alt.c - ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} + ${CC} ${CFLAGS} -DW=${WIDTH} -DH=${HEIGHT} -DI=${ITERATIONS} $< -o $@ ${LDFLAGS} # data files # diff --git a/2006/monge/README.md b/2006/monge/README.md index 4fe28852b..8f2574df5 100644 --- a/2006/monge/README.md +++ b/2006/monge/README.md @@ -6,8 +6,8 @@ Make sure you have the SDL1 (not SDL2!) development environment installed. make ``` -There is alternate code that lets you redefine the width and height and number -of iterations to use. See [alternate code](#alternate-code) below. +There is alternate version that lets you redefine the width and height and number +of iterations to use. See [Alternate code](#alternate-code) below. ### Bugs and (Mis)features: @@ -67,13 +67,13 @@ of the variables `W`, `H` and `I`. The defaults are (respectively) 400, 300 and the same then do: ```sh -make clobber CDEFINE="-DW=500 -DH=500" alt +make clobber WIDTH=500 HEIGHT=500 alt ``` If you wish to keep the dimensions the same but change the iterations to 512: ```sh -make clobber CDEFINE="-DI=512" alt +make clobber ITERATIONS=512 alt ``` If you specify a value less than 1 for any of these it sets it back to the diff --git a/2006/sloane/Makefile b/2006/sloane/Makefile index e60349445..bf4edcbbd 100644 --- a/2006/sloane/Makefile +++ b/2006/sloane/Makefile @@ -57,9 +57,12 @@ CSTD= -std=gnu99 # ARCH= +# variable to simplify redefining sleep duration for alt code +# +SLEEP= 75000 # Defines that are needed to compile # -CDEFINE= -DS=75000 +CDEFINE= -DS=${SLEEP} # Include files that are needed to compile # diff --git a/2006/sloane/README.md b/2006/sloane/README.md index 18d10b22e..751278624 100644 --- a/2006/sloane/README.md +++ b/2006/sloane/README.md @@ -24,7 +24,7 @@ value used in `usleep()`. The default is `-DS=75000` but you can easily change it. To do so try: ```sh -make CDEFINE="-DS=70000" clobber alt +make clobber SLEEP=70000 clobber alt ./sloane.alt ``` @@ -32,7 +32,7 @@ If you wish to make it like the original, as if the below [Original code](#original-code) was being used, you can do: ```sh -make CDEFINE="-DS=0" clobber alt +make SLEEP=0 clobber alt ./sloane.alt ``` diff --git a/2015/duble/README.md b/2015/duble/README.md index 4de5be6f6..b21cb6656 100644 --- a/2015/duble/README.md +++ b/2015/duble/README.md @@ -4,6 +4,9 @@ make ``` +There is an alternate version of this entry, discussed in the author's remarks. +See [Alternate code](#alternate-code) below. + ## To use: @@ -15,36 +18,34 @@ echo Some text | ./prog ### Try: ```sh -echo Hello, world | ./prog - -DRAFT=1 ./prog < prog.c - -./prog -> [type] -(...observe...) - -./prog < prog.c +./try.sh ``` ## Alternate code: -An alternate version of this entry, prog.alt.c, is provided. This alternate -code is discussed below in the "prog.c vs prog.alt.c" section of the Author's -comments below. +This alternate code, provided by the author, is discussed in more detail by the +author in the 'prog.c vs prog.alt.c' section of their remarks. -To compile this alternate version: - make alt +### Alternate build: + +```sh +make alt +``` + + +### Alternate use: Use `prog.alt` as you would `prog` above. -### Selected Judges Remarks: + +### Judges' remarks: Beautiful penmanship! However, your fonts may vary. -How does this entry compress the font it uses? What's the purpose of lrand48()? -Why does the program dump core, when it does :) ? +How does this entry compress the font it uses? What's the purpose of +`lrand48(3)`? Why does the program dump core, when it does :) ? ## Author's remarks: @@ -54,13 +55,14 @@ Why does the program dump core, when it does :) ? This program **prints text in your terminal with an interesting hand-writing effect**. -It uses the *braille patterns* range of the unicode standard: this +It uses the *Braille patterns* range of the unicode standard: this allows to consider each terminal character as a tiny 2x4 bitmap. Turning the Braille code into something visual might be considered blasphemous. When I was fighting to make this program work, I started wondering if it was not the reason for its very erratic behaviour. + ### prog.c vs prog.alt.c The file `prog.alt.c` is the one I submitted. @@ -71,30 +73,36 @@ with other compilers or optimization levels). These have been fixed in `prog.c`. After this fix, in order to remain rule-2-compliant, a variable name has also been shortened in this file. + ### How to build If you have `clang`: - $ CC=clang make -e +```sh +CC=clang make -e +``` Otherwise (gcc): - $ make +```sh +make +``` (You will get a few warnings in this case.) + ### How to use it You need a terminal configured to handle a *UTF-8* encoding and a font including -*braille patterns*. +*Braille patterns*. This is the default on most modern GNU/Linux operating systems. The default terminal application (gnome-terminal) or even a simple xterm should render things properly. -I tested this on several Debian and Ubuntu systems, 32 and 64bits (no -configuration was needed). +I tested this on several Debian and Ubuntu systems, 32 and 64bits and no +configuration was needed. I also tested it on FreeBSD 9.3 32bits (font and encoding configuration was needed in this case). @@ -123,9 +131,9 @@ $ ./prog This entry is obfuscated in various ways: * The structure is hidden by avoiding loops, `if` statements, ternary -conditionals, and jump-related instructions. Instead, recursivity is heavily +conditionals, and jump-related instructions. Instead, recursion is heavily used. -* Merging all functions into one added even more recursivity. ;) +* Merging all functions into one added even more recursion. ;) * The provided code does not contain the same number of opening and closing parenthesis. * Preprocessing the code inflates it and adds lots of indents. Removing some @@ -144,8 +152,8 @@ On the other hand, the following may help: * The code layout should help to identify which part of the code is obfuscated. ;) -* File 'codes.txt' shows how each character is drawn. This data is encoded in -macro `O_o` at the top of the source file. +* File [codes.txt](codes.txt) shows how each character is drawn. This data is +encoded in macro `O_o` at the top of the source file. ### Limitations: @@ -160,23 +168,27 @@ a-z, A-Z, '.' ':' ',' ';' '!' and '?'. ``` Uppercase and lowercase chars are rendered the same. The program also understand -the space and the linefeed (\n). Other chars are simply ignored (most of the +the space and the linefeed (`\n`). Other chars are simply ignored (most of the time ;) + #### Stack size -This limitation is due to the heavy use of recursivity. After having processed a +This limitation is due to the heavy use of recursion. After having processed a large number of characters, the process may exceed the stack size and crash. (However I did not experience this myself. The top-level recursion might be removed by the compiler as part of its optimizations.) + #### Line rendering The program does its best to avoid cutting words at the end of lines, but it could still happen in case of long words. + ### Subtleties and extra features + #### Handling more than text docs? Given the limited set of characters handled, the program is mostly limited to @@ -185,12 +197,13 @@ simple text documents. Thus, if you try for example: ```sh -$ ./prog < prog.c\ +$ ./prog < prog.c ``` You will not get something that looks like C code. (but you can still try, if you are curious. :) + #### A 'draft' mode Defining an environment variable called DRAFT will enable the 'draft-mode'. @@ -202,6 +215,7 @@ $ echo 'testing the draft mode' | DRAFT=1 ./prog The program will run much faster but the rendering will be less precise. + #### The subtle interactive mode I saved the best for last: usually, programs that handle an "interactive mode" diff --git a/2015/duble/try.sh b/2015/duble/try.sh new file mode 100755 index 000000000..a6d75794a --- /dev/null +++ b/2015/duble/try.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# +# try.sh - demonstrate IOCCC winner 2015/duble +# + +# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it +# this way allows us to have the user specify a different compiler in an easy +# way. +if [[ -z "$CC" ]]; then + CC="cc" +fi + +make CC="$CC" all >/dev/null || exit 1 + +# clear screen after compilation so that only the entry is shown +clear + +echo "$ echo \"Hello, world!\" | ./prog" 1>&2 +echo "Hello, world!" | ./prog + +echo "$ echo \"IOCCC 2015\" | ./prog" 1>&2 +echo "IOCCC 2015" | ./prog + +echo "$ DRAFT=1 ./prog < prog.c" 1>&2 +DRAFT=1 ./prog < prog.c + +echo "$ ./prog < prog.c" 1>&2 +./prog < prog.c + +echo "$ ./prog < lorem-ipsum.txt" 1>&2 +./prog < lorem-ipsum.txt + +echo "Type in text, hitting enter after each line." 1>&2 +echo "Watch the output each time and try again." 1>&2 +echo "Hit ctrl-c to exit." 1>&2 +echo 1>&2 +echo "$ ./prog" 1>&2 +./prog diff --git a/2015/hou/README.md b/2015/hou/README.md index 5e6abfa6f..7b6146b2f 100644 --- a/2015/hou/README.md +++ b/2015/hou/README.md @@ -22,7 +22,7 @@ echo "" | ./prog ## Judges' remarks: A good start for understanding this entry might be -https://www.ietf.org/rfc/rfc1321.txt. How does it compute this using only a +[rfc1321.txt](rfc1321.txt). How does it compute this using only a single looping construct? The original reference source code for this algorithm is about 355 lines of code, yet this entry is only 199 lines with one statement per line and it isn't using lots of macro expansion tricks like diff --git a/2015/hou/rfc1321.txt b/2015/hou/rfc1321.txt new file mode 100644 index 000000000..68af27d2b --- /dev/null +++ b/2015/hou/rfc1321.txt @@ -0,0 +1,1179 @@ + + + + + + +Network Working Group R. Rivest +Request for Comments: 1321 MIT Laboratory for Computer Science + and RSA Data Security, Inc. + April 1992 + + + The MD5 Message-Digest Algorithm + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard. Distribution of this memo is + unlimited. + +Acknowlegements + + We would like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle, + David Chaum, and Noam Nisan for numerous helpful comments and + suggestions. + +Table of Contents + + 1. Executive Summary 1 + 2. Terminology and Notation 2 + 3. MD5 Algorithm Description 3 + 4. Summary 6 + 5. Differences Between MD4 and MD5 6 + References 7 + APPENDIX A - Reference Implementation 7 + Security Considerations 21 + Author's Address 21 + +1. Executive Summary + + This document describes the MD5 message-digest algorithm. The + algorithm takes as input a message of arbitrary length and produces + as output a 128-bit "fingerprint" or "message digest" of the input. + It is conjectured that it is computationally infeasible to produce + two messages having the same message digest, or to produce any + message having a given prespecified target message digest. The MD5 + algorithm is intended for digital signature applications, where a + large file must be "compressed" in a secure manner before being + encrypted with a private (secret) key under a public-key cryptosystem + such as RSA. + + + + + + + +Rivest [Page 1] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + + The MD5 algorithm is designed to be quite fast on 32-bit machines. In + addition, the MD5 algorithm does not require any large substitution + tables; the algorithm can be coded quite compactly. + + The MD5 algorithm is an extension of the MD4 message-digest algorithm + 1,2]. MD5 is slightly slower than MD4, but is more "conservative" in + design. MD5 was designed because it was felt that MD4 was perhaps + being adopted for use more quickly than justified by the existing + critical review; because MD4 was designed to be exceptionally fast, + it is "at the edge" in terms of risking successful cryptanalytic + attack. MD5 backs off a bit, giving up a little in speed for a much + greater likelihood of ultimate security. It incorporates some + suggestions made by various reviewers, and contains additional + optimizations. The MD5 algorithm is being placed in the public domain + for review and possible adoption as a standard. + + For OSI-based applications, MD5's object identifier is + + md5 OBJECT IDENTIFIER ::= + iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5} + + In the X.509 type AlgorithmIdentifier [3], the parameters for MD5 + should have type NULL. + +2. Terminology and Notation + + In this document a "word" is a 32-bit quantity and a "byte" is an + eight-bit quantity. A sequence of bits can be interpreted in a + natural manner as a sequence of bytes, where each consecutive group + of eight bits is interpreted as a byte with the high-order (most + significant) bit of each byte listed first. Similarly, a sequence of + bytes can be interpreted as a sequence of 32-bit words, where each + consecutive group of four bytes is interpreted as a word with the + low-order (least significant) byte given first. + + Let x_i denote "x sub i". If the subscript is an expression, we + surround it in braces, as in x_{i+1}. Similarly, we use ^ for + superscripts (exponentiation), so that x^i denotes x to the i-th + power. + + Let the symbol "+" denote addition of words (i.e., modulo-2^32 + addition). Let X <<< s denote the 32-bit value obtained by circularly + shifting (rotating) X left by s bit positions. Let not(X) denote the + bit-wise complement of X, and let X v Y denote the bit-wise OR of X + and Y. Let X xor Y denote the bit-wise XOR of X and Y, and let XY + denote the bit-wise AND of X and Y. + + + + + +Rivest [Page 2] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + +3. MD5 Algorithm Description + + We begin by supposing that we have a b-bit message as input, and that + we wish to find its message digest. Here b is an arbitrary + nonnegative integer; b may be zero, it need not be a multiple of + eight, and it may be arbitrarily large. We imagine the bits of the + message written down as follows: + + m_0 m_1 ... m_{b-1} + + The following five steps are performed to compute the message digest + of the message. + +3.1 Step 1. Append Padding Bits + + The message is "padded" (extended) so that its length (in bits) is + congruent to 448, modulo 512. That is, the message is extended so + that it is just 64 bits shy of being a multiple of 512 bits long. + Padding is always performed, even if the length of the message is + already congruent to 448, modulo 512. + + Padding is performed as follows: a single "1" bit is appended to the + message, and then "0" bits are appended so that the length in bits of + the padded message becomes congruent to 448, modulo 512. In all, at + least one bit and at most 512 bits are appended. + +3.2 Step 2. Append Length + + A 64-bit representation of b (the length of the message before the + padding bits were added) is appended to the result of the previous + step. In the unlikely event that b is greater than 2^64, then only + the low-order 64 bits of b are used. (These bits are appended as two + 32-bit words and appended low-order word first in accordance with the + previous conventions.) + + At this point the resulting message (after padding with bits and with + b) has a length that is an exact multiple of 512 bits. Equivalently, + this message has a length that is an exact multiple of 16 (32-bit) + words. Let M[0 ... N-1] denote the words of the resulting message, + where N is a multiple of 16. + +3.3 Step 3. Initialize MD Buffer + + A four-word buffer (A,B,C,D) is used to compute the message digest. + Here each of A, B, C, D is a 32-bit register. These registers are + initialized to the following values in hexadecimal, low-order bytes + first): + + + + +Rivest [Page 3] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + + word A: 01 23 45 67 + word B: 89 ab cd ef + word C: fe dc ba 98 + word D: 76 54 32 10 + +3.4 Step 4. Process Message in 16-Word Blocks + + We first define four auxiliary functions that each take as input + three 32-bit words and produce as output one 32-bit word. + + F(X,Y,Z) = XY v not(X) Z + G(X,Y,Z) = XZ v Y not(Z) + H(X,Y,Z) = X xor Y xor Z + I(X,Y,Z) = Y xor (X v not(Z)) + + In each bit position F acts as a conditional: if X then Y else Z. + The function F could have been defined using + instead of v since XY + and not(X)Z will never have 1's in the same bit position.) It is + interesting to note that if the bits of X, Y, and Z are independent + and unbiased, the each bit of F(X,Y,Z) will be independent and + unbiased. + + The functions G, H, and I are similar to the function F, in that they + act in "bitwise parallel" to produce their output from the bits of X, + Y, and Z, in such a manner that if the corresponding bits of X, Y, + and Z are independent and unbiased, then each bit of G(X,Y,Z), + H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased. Note that + the function H is the bit-wise "xor" or "parity" function of its + inputs. + + This step uses a 64-element table T[1 ... 64] constructed from the + sine function. Let T[i] denote the i-th element of the table, which + is equal to the integer part of 4294967296 times abs(sin(i)), where i + is in radians. The elements of the table are given in the appendix. + + Do the following: + + /* Process each 16-word block. */ + For i = 0 to N/16-1 do + + /* Copy block i into X. */ + For j = 0 to 15 do + Set X[j] to M[i*16+j]. + end /* of loop on j */ + + /* Save A as AA, B as BB, C as CC, and D as DD. */ + AA = A + BB = B + + + +Rivest [Page 4] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + + CC = C + DD = D + + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ + /* Do the following 16 operations. */ + [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4] + [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8] + [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12] + [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16] + + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ + /* Do the following 16 operations. */ + [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20] + [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24] + [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28] + [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32] + + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ + /* Do the following 16 operations. */ + [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36] + [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40] + [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44] + [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48] + + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ + /* Do the following 16 operations. */ + [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52] + [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56] + [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60] + [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64] + + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + A = A + AA + B = B + BB + C = C + CC + D = D + DD + + end /* of loop on i */ + + + +Rivest [Page 5] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + +3.5 Step 5. Output + + The message digest produced as output is A, B, C, D. That is, we + begin with the low-order byte of A, and end with the high-order byte + of D. + + This completes the description of MD5. A reference implementation in + C is given in the appendix. + +4. Summary + + The MD5 message-digest algorithm is simple to implement, and provides + a "fingerprint" or message digest of a message of arbitrary length. + It is conjectured that the difficulty of coming up with two messages + having the same message digest is on the order of 2^64 operations, + and that the difficulty of coming up with any message having a given + message digest is on the order of 2^128 operations. The MD5 algorithm + has been carefully scrutinized for weaknesses. It is, however, a + relatively new algorithm and further security analysis is of course + justified, as is the case with any new proposal of this sort. + +5. Differences Between MD4 and MD5 + + The following are the differences between MD4 and MD5: + + 1. A fourth round has been added. + + 2. Each step now has a unique additive constant. + + 3. The function g in round 2 was changed from (XY v XZ v YZ) to + (XZ v Y not(Z)) to make g less symmetric. + + 4. Each step now adds in the result of the previous step. This + promotes a faster "avalanche effect". + + 5. The order in which input words are accessed in rounds 2 and + 3 is changed, to make these patterns less like each other. + + 6. The shift amounts in each round have been approximately + optimized, to yield a faster "avalanche effect." The shifts in + different rounds are distinct. + + + + + + + + + + +Rivest [Page 6] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + +References + + [1] Rivest, R., "The MD4 Message Digest Algorithm", RFC 1320, MIT and + RSA Data Security, Inc., April 1992. + + [2] Rivest, R., "The MD4 message digest algorithm", in A.J. Menezes + and S.A. Vanstone, editors, Advances in Cryptology - CRYPTO '90 + Proceedings, pages 303-311, Springer-Verlag, 1991. + + [3] CCITT Recommendation X.509 (1988), "The Directory - + Authentication Framework." + +APPENDIX A - Reference Implementation + + This appendix contains the following files taken from RSAREF: A + Cryptographic Toolkit for Privacy-Enhanced Mail: + + global.h -- global header file + + md5.h -- header file for MD5 + + md5c.c -- source code for MD5 + + For more information on RSAREF, send email to . + + The appendix also includes the following file: + + mddriver.c -- test driver for MD2, MD4 and MD5 + + The driver compiles for MD5 by default but can compile for MD2 or MD4 + if the symbol MD is defined on the C compiler command line as 2 or 4. + + The implementation is portable and should work on many different + plaforms. However, it is not difficult to optimize the implementation + on particular platforms, an exercise left to the reader. For example, + on "little-endian" platforms where the lowest-addressed byte in a 32- + bit word is the least significant and there are no alignment + restrictions, the call to Decode in MD5Transform can be replaced with + a typecast. + +A.1 global.h + +/* GLOBAL.H - RSAREF types and constants + */ + +/* PROTOTYPES should be set to one if and only if the compiler supports + function argument prototyping. +The following makes PROTOTYPES default to 0 if it has not already + + + +Rivest [Page 7] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + + been defined with C compiler flags. + */ +#ifndef PROTOTYPES +#define PROTOTYPES 0 +#endif + +/* POINTER defines a generic pointer type */ +typedef unsigned char *POINTER; + +/* UINT2 defines a two byte word */ +typedef unsigned short int UINT2; + +/* UINT4 defines a four byte word */ +typedef unsigned long int UINT4; + +/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. +If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it + returns an empty list. + */ +#if PROTOTYPES +#define PROTO_LIST(list) list +#else +#define PROTO_LIST(list) () +#endif + +A.2 md5.h + +/* MD5.H - header file for MD5C.C + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + + + + +Rivest [Page 8] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + +/* MD5 context. */ +typedef struct { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; + +void MD5Init PROTO_LIST ((MD5_CTX *)); +void MD5Update PROTO_LIST + ((MD5_CTX *, unsigned char *, unsigned int)); +void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); + +A.3 md5c.c + +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + +#include "global.h" +#include "md5.h" + +/* Constants for MD5Transform routine. + */ + + + +Rivest [Page 9] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); +static void Encode PROTO_LIST + ((unsigned char *, UINT4 *, unsigned int)); +static void Decode PROTO_LIST + ((UINT4 *, unsigned char *, unsigned int)); +static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); +static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); + +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + + + +Rivest [Page 10] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/* MD5 initialization. Begins an MD5 operation, writing a new context. + */ +void MD5Init (context) +MD5_CTX *context; /* context */ +{ + context->count[0] = context->count[1] = 0; + /* Load magic initialization constants. +*/ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + operation, processing another message block, and updating the + context. + */ +void MD5Update (context, input, inputLen) +MD5_CTX *context; /* context */ +unsigned char *input; /* input block */ +unsigned int inputLen; /* length of input block */ +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((UINT4)inputLen << 3)) + + + +Rivest [Page 11] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + + < ((UINT4)inputLen << 3)) + context->count[1]++; + context->count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible. +*/ + if (inputLen >= partLen) { + MD5_memcpy + ((POINTER)&context->buffer[index], (POINTER)input, partLen); + MD5Transform (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + MD5_memcpy + ((POINTER)&context->buffer[index], (POINTER)&input[i], + inputLen-i); +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + the message digest and zeroizing the context. + */ +void MD5Final (digest, context) +unsigned char digest[16]; /* message digest */ +MD5_CTX *context; /* context */ +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. +*/ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD5Update (context, bits, 8); + + + +Rivest [Page 12] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. +*/ + MD5_memset ((POINTER)context, 0, sizeof (*context)); +} + +/* MD5 basic transformation. Transforms state based on block. + */ +static void MD5Transform (state, block) +UINT4 state[4]; +unsigned char block[64]; +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + + + +Rivest [Page 13] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. + + + +Rivest [Page 14] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + +*/ + MD5_memset ((POINTER)x, 0, sizeof (x)); +} + +/* Encodes input (UINT4) into output (unsigned char). Assumes len is + a multiple of 4. + */ +static void Encode (output, input, len) +unsigned char *output; +UINT4 *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (unsigned char) into output (UINT4). Assumes len is + a multiple of 4. + */ +static void Decode (output, input, len) +UINT4 *output; +unsigned char *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); +} + +/* Note: Replace "for loop" with standard memcpy if possible. + */ + +static void MD5_memcpy (output, input, len) +POINTER output; +POINTER input; +unsigned int len; +{ + unsigned int i; + + for (i = 0; i < len; i++) + + + +Rivest [Page 15] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + + output[i] = input[i]; +} + +/* Note: Replace "for loop" with standard memset if possible. + */ +static void MD5_memset (output, value, len) +POINTER output; +int value; +unsigned int len; +{ + unsigned int i; + + for (i = 0; i < len; i++) + ((char *)output)[i] = (char)value; +} + +A.4 mddriver.c + +/* MDDRIVER.C - test driver for MD2, MD4 and MD5 + */ + +/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All +rights reserved. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + +/* The following makes MD default to MD5 if it has not already been + defined with C compiler flags. + */ +#ifndef MD +#define MD MD5 +#endif + +#include +#include +#include +#include "global.h" +#if MD == 2 +#include "md2.h" +#endif +#if MD == 4 + + + +Rivest [Page 16] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + +#include "md4.h" +#endif +#if MD == 5 +#include "md5.h" +#endif + +/* Length of test block, number of test blocks. + */ +#define TEST_BLOCK_LEN 1000 +#define TEST_BLOCK_COUNT 1000 + +static void MDString PROTO_LIST ((char *)); +static void MDTimeTrial PROTO_LIST ((void)); +static void MDTestSuite PROTO_LIST ((void)); +static void MDFile PROTO_LIST ((char *)); +static void MDFilter PROTO_LIST ((void)); +static void MDPrint PROTO_LIST ((unsigned char [16])); + +#if MD == 2 +#define MD_CTX MD2_CTX +#define MDInit MD2Init +#define MDUpdate MD2Update +#define MDFinal MD2Final +#endif +#if MD == 4 +#define MD_CTX MD4_CTX +#define MDInit MD4Init +#define MDUpdate MD4Update +#define MDFinal MD4Final +#endif +#if MD == 5 +#define MD_CTX MD5_CTX +#define MDInit MD5Init +#define MDUpdate MD5Update +#define MDFinal MD5Final +#endif + +/* Main driver. + +Arguments (may be any combination): + -sstring - digests string + -t - runs time trial + -x - runs test script + filename - digests file + (none) - digests standard input + */ +int main (argc, argv) +int argc; + + + +Rivest [Page 17] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + +char *argv[]; +{ + int i; + + if (argc > 1) + for (i = 1; i < argc; i++) + if (argv[i][0] == '-' && argv[i][1] == 's') + MDString (argv[i] + 2); + else if (strcmp (argv[i], "-t") == 0) + MDTimeTrial (); + else if (strcmp (argv[i], "-x") == 0) + MDTestSuite (); + else + MDFile (argv[i]); + else + MDFilter (); + + return (0); +} + +/* Digests a string and prints the result. + */ +static void MDString (string) +char *string; +{ + MD_CTX context; + unsigned char digest[16]; + unsigned int len = strlen (string); + + MDInit (&context); + MDUpdate (&context, string, len); + MDFinal (digest, &context); + + printf ("MD%d (\"%s\") = ", MD, string); + MDPrint (digest); + printf ("\n"); +} + +/* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte + blocks. + */ +static void MDTimeTrial () +{ + MD_CTX context; + time_t endTime, startTime; + unsigned char block[TEST_BLOCK_LEN], digest[16]; + unsigned int i; + + + + +Rivest [Page 18] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + + printf + ("MD%d time trial. Digesting %d %d-byte blocks ...", MD, + TEST_BLOCK_LEN, TEST_BLOCK_COUNT); + + /* Initialize block */ + for (i = 0; i < TEST_BLOCK_LEN; i++) + block[i] = (unsigned char)(i & 0xff); + + /* Start timer */ + time (&startTime); + + /* Digest blocks */ + MDInit (&context); + for (i = 0; i < TEST_BLOCK_COUNT; i++) + MDUpdate (&context, block, TEST_BLOCK_LEN); + MDFinal (digest, &context); + + /* Stop timer */ + time (&endTime); + + printf (" done\n"); + printf ("Digest = "); + MDPrint (digest); + printf ("\nTime = %ld seconds\n", (long)(endTime-startTime)); + printf + ("Speed = %ld bytes/second\n", + (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime)); +} + +/* Digests a reference suite of strings and prints the results. + */ +static void MDTestSuite () +{ + printf ("MD%d test suite:\n", MD); + + MDString (""); + MDString ("a"); + MDString ("abc"); + MDString ("message digest"); + MDString ("abcdefghijklmnopqrstuvwxyz"); + MDString + ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); + MDString + ("1234567890123456789012345678901234567890\ +1234567890123456789012345678901234567890"); +} + +/* Digests a file and prints the result. + + + +Rivest [Page 19] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + + */ +static void MDFile (filename) +char *filename; +{ + FILE *file; + MD_CTX context; + int len; + unsigned char buffer[1024], digest[16]; + + if ((file = fopen (filename, "rb")) == NULL) + printf ("%s can't be opened\n", filename); + + else { + MDInit (&context); + while (len = fread (buffer, 1, 1024, file)) + MDUpdate (&context, buffer, len); + MDFinal (digest, &context); + + fclose (file); + + printf ("MD%d (%s) = ", MD, filename); + MDPrint (digest); + printf ("\n"); + } +} + +/* Digests the standard input and prints the result. + */ +static void MDFilter () +{ + MD_CTX context; + int len; + unsigned char buffer[16], digest[16]; + + MDInit (&context); + while (len = fread (buffer, 1, 16, stdin)) + MDUpdate (&context, buffer, len); + MDFinal (digest, &context); + + MDPrint (digest); + printf ("\n"); +} + +/* Prints a message digest in hexadecimal. + */ +static void MDPrint (digest) +unsigned char digest[16]; +{ + + + +Rivest [Page 20] + +RFC 1321 MD5 Message-Digest Algorithm April 1992 + + + unsigned int i; + + for (i = 0; i < 16; i++) + printf ("%02x", digest[i]); +} + +A.5 Test suite + + The MD5 test suite (driver option "-x") should print the following + results: + +MD5 test suite: +MD5 ("") = d41d8cd98f00b204e9800998ecf8427e +MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661 +MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72 +MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0 +MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b +MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = +d174ab98d277d9f5a5611c2c9f419d9f +MD5 ("123456789012345678901234567890123456789012345678901234567890123456 +78901234567890") = 57edf4a22be3c955ac49da2e2107b67a + +Security Considerations + + The level of security discussed in this memo is considered to be + sufficient for implementing very high security hybrid digital- + signature schemes based on MD5 and a public-key cryptosystem. + +Author's Address + + Ronald L. Rivest + Massachusetts Institute of Technology + Laboratory for Computer Science + NE43-324 + 545 Technology Square + Cambridge, MA 02139-1986 + + Phone: (617) 253-5880 + EMail: rivest@theory.lcs.mit.edu + + + + + + + + + + + + +Rivest [Page 21] + \ No newline at end of file diff --git a/2015/howe/spoiler/err.h b/2015/howe/spoiler/err.h index 839c76ac4..1a6ba9346 100644 --- a/2015/howe/spoiler/err.h +++ b/2015/howe/spoiler/err.h @@ -1,5 +1,5 @@ /* - * Trival err.h + * Trivial err.h */ #ifndef __err_h__ @@ -43,4 +43,4 @@ extern "C" { } #endif -#endif /* __err_h__ */ \ No newline at end of file +#endif /* __err_h__ */ diff --git a/2015/muth/machine_beaver_4_2.h b/2015/muth/machine_beaver_4_2.h index 13ad467c4..f0fac1373 100644 --- a/2015/muth/machine_beaver_4_2.h +++ b/2015/muth/machine_beaver_4_2.h @@ -1,5 +1,5 @@ /* - * 4 state, 2 symbol busy beaver, http://www.logique.jussieu.fr/~michel/ha.html#tm42 + * 4 state, 2 symbol busy beaver, https://web.archive.org/web/20150926094245/http://www.logique.jussieu.fr/~michel/ha.html#tm42 * * halts after 107 steps */ diff --git a/2015/muth/machine_champ_2_4.h b/2015/muth/machine_champ_2_4.h index 77d437d8e..24a8533d3 100644 --- a/2015/muth/machine_champ_2_4.h +++ b/2015/muth/machine_champ_2_4.h @@ -1,5 +1,5 @@ /* - * 2 state, 4 symbol current champion, http://www.logique.jussieu.fr/~michel/ha.html#tm24 + * 2 state, 4 symbol current champion, https://web.archive.org/web/20150926094245/http://www.logique.jussieu.fr/~michel/ha.html#tm24 * * halts after 3932964 steps */ diff --git a/2015/muth/machine_chaos_5_2.h b/2015/muth/machine_chaos_5_2.h index d16b9b4d4..1180a4e0a 100644 --- a/2015/muth/machine_chaos_5_2.h +++ b/2015/muth/machine_chaos_5_2.h @@ -1,7 +1,7 @@ /* - * chaos machine, http://www.drb.insel.de/~heiner/BB/mabu90.html + * chaos machine, https://web.archive.org/web/20131104160623/http://www.drb.insel.de/~heiner/BB/mabu90.html * - * does not halt (http://www.drb.insel.de/~heiner/BB/TM4-proof.txt) + * does not halt (https://web.archive.org/web/20131104203330/http://www.drb.insel.de/~heiner/BB/TM4-proof.txt) */ #define sym_1(sym, _1) sym diff --git a/2015/muth/machine_cmplx_5_2.h b/2015/muth/machine_cmplx_5_2.h index 27908da4b..7874f3248 100644 --- a/2015/muth/machine_cmplx_5_2.h +++ b/2015/muth/machine_cmplx_5_2.h @@ -1,5 +1,5 @@ /* - * complex machine, http://www.drb.insel.de/~heiner/BB/mabu90.html + * complex machine, https://web.archive.org/web/20131104160623/http://www.drb.insel.de/~heiner/BB/mabu90.html */ #define sym_1(sym, _1) sym diff --git a/2015/muth/machine_count_5_2.h b/2015/muth/machine_count_5_2.h index ee9b9a3ce..e006207d5 100644 --- a/2015/muth/machine_count_5_2.h +++ b/2015/muth/machine_count_5_2.h @@ -1,5 +1,5 @@ /* - * counting machine, http://www.drb.insel.de/~heiner/BB/mabu90.html + * counting machine, https://web.archive.org/web/20131104160623/http://www.drb.insel.de/~heiner/BB/mabu90.html * * does not halt */ diff --git a/2015/muth/machine_great_3_2.h b/2015/muth/machine_great_3_2.h index f4ffbe797..07596f5a3 100644 --- a/2015/muth/machine_great_3_2.h +++ b/2015/muth/machine_great_3_2.h @@ -1,5 +1,5 @@ /* - * greater machine, http://www.drb.insel.de/~heiner/BB/mabu90.html + * greater machine, https://web.archive.org/web/20131104160623/http://www.drb.insel.de/~heiner/BB/mabu90.html * * does not halt */ diff --git a/2015/muth/machine_ru_2_4.h b/2015/muth/machine_ru_2_4.h index e9523be82..3dd5768f8 100644 --- a/2015/muth/machine_ru_2_4.h +++ b/2015/muth/machine_ru_2_4.h @@ -1,5 +1,5 @@ /* - * 2 state, 4 symbol current runner-up, http://www.logique.jussieu.fr/~michel/ha.html#tm24 + * 2 state, 4 symbol current runner-up, https://web.archive.org/web/20150926094245/http://www.logique.jussieu.fr/~michel/ha.html#tm24 * * halts after 7195 steps */ diff --git a/thanks-for-help.md b/thanks-for-help.md index 800efe4d1..fe7456444 100644 --- a/thanks-for-help.md +++ b/thanks-for-help.md @@ -3788,6 +3788,9 @@ output. ## [2015/endoh3](/2015/endoh3/prog.c) ([README.md](/2015/endoh3/README.md])) +[Cody](#cody) added the [try.sh](/2015/duble/try.sh) script. +>>>>>>> xexyl-duble15-try + [Cody](#cody) fixed this to compile with Linux which was having a problem with duplicate symbols of `main()`. The fix is through the compiler option `-fcommon` which will let it compile like it does with macOS. @@ -3802,6 +3805,7 @@ simply typing `make back_to` or `make mullender`. [Cody](#cody) added explicit linking of libm (`-lm`) for systems that do not do this (Linux doesn't seem to but macOS does). +<<<<<<< HEAD ## [2015/howe](/2015/howe/prog.c) ([README.md](/2015/howe/README.md)) @@ -3810,11 +3814,46 @@ and Peace text file, fixed the [avgtime.sh](/2015/howe/avgtime.sh) script (it resulted in standard input errors in piping to `bc(/1)`) and added the [cc.1](/2015/howe/cc.1) man page as not all systems have it (in fact it's `gcc(/1)` from Rocky Linux). +||||||| 6a936532 + +## [2015/howe](2015/howe/prog.c) ([README.md](2015/howe/README.md)) + +[Cody](#cody) added the [try.sh](2015/howe/try.sh) script, downloaded the War +and Peace text file, fixed the [avgtime.sh](2015/howe/avgtime.sh) script (it +resulted in standard input errors in piping to `bc(1)`) and added the +[cc.1](2015/howe/cc.1) man page as not all systems have it (in fact it's +`gcc(1)` from Rocky Linux). +======= +Cody also added the RFC 1321 text file, [rfc1321.txt](2015/hou/rfc1321.txt) to +the directory, to make it so one need not download it, and which the README.md +file now links to. +>>>>>>> xexyl-duble15-try + + +<<<<<<< HEAD +## [2015/mills1](/2015/mills1/prog.c) ([README.md](/2015/mills1/README.md)) +||||||| 6a936532 +## [2015/mills1](2015/mills1/prog.c) ([README.md](2015/mills1/README.md)) +======= +## [2015/howe](/2015/howe/prog.c) ([README.md](/2015/howe/README.md)) +>>>>>>> xexyl-duble15-try + +<<<<<<< HEAD +[Cody](#cody) added the [try.sh](/2015/mills1/try.sh) script which changes the +||||||| 6a936532 +[Cody](#cody) added the [try.sh](2015/mills1/try.sh) script which changes the +======= +[Cody](#cody) added the [try.sh](/2015/howe/try.sh) script, downloaded the War +and Peace text file, fixed the [avgtime.sh](/2015/howe/avgtime.sh) script (it +resulted in standard input errors in piping to `bc(/1)`) and added the +[cc.1](/2015/howe/cc.1) man page as not all systems have it (in fact it's +`gcc(/1)` from Rocky Linux). ## [2015/mills1](/2015/mills1/prog.c) ([README.md](/2015/mills1/README.md)) [Cody](#cody) added the [try.sh](/2015/mills1/try.sh) script which changes the +>>>>>>> xexyl-duble15-try parameters to what we had in the judges' remarks to make it easier (he only died when he tried to mark a reminder complete on the other side of the screen at the same time and he almost survived that, scoring at that point over 90 - but this diff --git a/tmp/things-todo.md b/tmp/things-todo.md index 94a5dad0a..8df6dafbd 100644 --- a/tmp/things-todo.md +++ b/tmp/things-todo.md @@ -1,5 +1,5 @@ # A todo list of known things to check and/or do -*Last updated: Wed 06 Dec 2023 13:24:33 UTC* +*Last updated: Thu 07 Dec 2023 19:12:36 UTC* This document is primarily for [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) as he (that is I :-) ) wanted a way @@ -169,3 +169,32 @@ the rest of the entries are done, assuming that it's possible. - Although I will have to do this when another issue is opened up I am aware of some issues in 2020/ferguson1/.winner.json. I do not want to forget this, however, so I am noting it here. + +- Finish going through entries (Makefile and README.md files) that have the +ability to redefine macros but only in an awkward way like `make clobber +CDEFINE="-D.."`. To find entries that were done by me: `git grep -c 'CDEFINE' +'*README.md'` but the `2000/thadgavin` is already done. The reference to +`CDEFINE` might want to be removed but that can be decided when this is done +too. The entries done as of 7 Dec 2023 are: + - 2006/sloane + - 2006/monge + - 2004/jdalbec + - 2004/gavare + - 2001/kev + - 2000/thadgavin + - 1998/schweikh3 + - 1998/banks + - 1994/dodsond2 + - 1993/rince + - 1993/plummer + - 1993/cmills + - 1992/kivinen + - 1991/rince + - 1985/shapiro + - 1985/lycklama + ... and at least one of them needs to have the thanks file updated as it + helps with the original entry itself. This one is 1998/banks but there might + be more (and there is at least one not done yet that this will apply I + believe). + +