Merge pull request #252 from xexyl/1994-shapiro
Updates to 1994/shapiro including possible bug
This commit is contained in:
5 files changed
+297
-157
No files matched your search
@@ -109,7 +109,7 @@ ENTRY= shapiro
|
||||
PROG= ${ENTRY}
|
||||
#
|
||||
OBJ= ${PROG}.o
|
||||
DATA= shapiro.info
|
||||
DATA= shapiro.md
|
||||
TARGET= ${PROG}
|
||||
#
|
||||
ALT_OBJ=
|
||||
|
||||
+78
-44
@@ -1,62 +1,96 @@
|
||||
# Most Well Rounded Obfuscation:
|
||||
|
||||
Andrew T. Shapiro
|
||||
CSES/CIRES University of Colorado
|
||||
Campus Box 216
|
||||
Boulder, CO 80309-0216
|
||||
USA
|
||||
Andrew T. Shapiro
|
||||
CSES/CIRES University of Colorado
|
||||
Campus Box 216
|
||||
Boulder, CO 80309-0216
|
||||
USA
|
||||
|
||||
## To build:
|
||||
|
||||
make all
|
||||
|
||||
## To run
|
||||
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) pointed out a potential
|
||||
bug on systems where `EOF != -1`. The problem is that `getc()` and the related
|
||||
functions do not return `-1` on EOF or error but rather `EOF` but the program
|
||||
assumes `-1` (conversely when using the `getopt()` functions one should not
|
||||
check for EOF but -1 as the functions return -1 not EOF but the standard does
|
||||
not require `EOF` to be -1, just a negative number. However changing it to check
|
||||
for `!=EOF` caused a problem due to the clever encoding of the code. See
|
||||
[bugs.md](/bugs.md) for more details if you wish to try and fix this (Cody is
|
||||
here and there working on it along with other things and will change this
|
||||
message when it's fixed assuming it's feasible).
|
||||
|
||||
|
||||
## To run:
|
||||
|
||||
./shapiro &
|
||||
|
||||
## Judges' comments
|
||||
## Try:
|
||||
|
||||
This entry has many different levels of obfuscation, and yet the
|
||||
source file is self documenting. :-)
|
||||
```sh
|
||||
./shapiro
|
||||
^Z
|
||||
bg
|
||||
ps x
|
||||
^C
|
||||
|
||||
From time to time, run ps and look at the new processes.
|
||||
./shapiro_t1
|
||||
```
|
||||
|
||||
See shapiro.info for more information in the internals of this program.
|
||||
The file shapiro.alt contains a non-obfuscated version of this program.
|
||||
Notice what you see in the output of `ps`!
|
||||
|
||||
## Author's comments
|
||||
|
||||
The basic theme (pun) of this program is:
|
||||
|
||||
"This time (everything) is not where it should be."
|
||||
~~~~
|
||||
My entry (shapiro.c) is mostly comment, formatted in the shape of a
|
||||
clock. If you strip out the comments and look at the code you will
|
||||
quickly realize that the comments were the important part and that
|
||||
the code does very little (see pun above). It writes (to stdout)
|
||||
another C program (shapiro_t2.c). This is the first level of
|
||||
obfuscation.
|
||||
|
||||
The second program (shapiro_t2.c if you use the build/make file)
|
||||
prints a clock in the upper right hand corner of your VTxxx/ANSI
|
||||
display.
|
||||
|
||||
Most of the surface obfuscation in the second program (shapiro_t2.c)
|
||||
was an attempt to make it as small as possible. You should be able to
|
||||
see around this with cb(1) and some more intelligent variable names.
|
||||
Once you get past this you will realize that the third level of
|
||||
obfuscation is a six member client/server hierarchy.
|
||||
(See the second info file for a detailed description of the algorithm.)
|
||||
|
||||
Lint complains about: precedence confusion, K may be used before set,
|
||||
main() returns random value to invocation environment, value type used
|
||||
inconsistently, value type declared inconsistently, function argument
|
||||
( number ) used inconsistently, function returns value which is always
|
||||
ignored, function returns value which is sometimes ignored
|
||||
All of which are harmless (famous last words).
|
||||
|
||||
This may or may not work on non ASCII systems (I could not find one to
|
||||
test it on.)
|
||||
## Judges' comments:
|
||||
|
||||
This entry has many different levels of obfuscation, and yet the
|
||||
source file is self documenting. :-)
|
||||
|
||||
From time to time, run ps and look at the new processes.
|
||||
|
||||
See [shapiro.md](shapiro.md) for more information in the internals of this program.
|
||||
The file [shapiro.alt.c](shapiro.alt.c) contains a non-obfuscated version of
|
||||
this program. Note that this alt file is currently missing. See
|
||||
[bugs.md](/bugs.md) for details.
|
||||
|
||||
|
||||
## Author's comments:
|
||||
|
||||
The basic theme (pun) of this program is:
|
||||
|
||||
|
||||
> "This time (everything) is not where it should be."
|
||||
> ~~~~
|
||||
|
||||
|
||||
My entry ([shapiro.c](shapiro.c)) is mostly comment, formatted in the shape of a
|
||||
clock. If you strip out the comments and look at the code you will
|
||||
quickly realize that the comments were the important part and that
|
||||
the code does very little (see pun above). It writes (to stdout)
|
||||
another C program ([shapiro_t2.c](shapiro_t2.c)). This is the first level of
|
||||
obfuscation.
|
||||
|
||||
The second program ([shapiro_t2.c](shapiro_t2.c) if you use the Makefile
|
||||
prints a clock in the upper right hand corner of your VTxxx/ANSI display.
|
||||
|
||||
Most of the surface obfuscation in the second program
|
||||
([shapiro_t2.c](shapiro_t2.c))
|
||||
was an attempt to make it as small as possible. You should be able to
|
||||
see around this with cb(1) and some more intelligent variable names.
|
||||
Once you get past this you will realize that the third level of
|
||||
obfuscation is a six member client/server hierarchy.
|
||||
(See the [shapiro.md](shapiro.md) file for a detailed description of the
|
||||
algorithm.)
|
||||
|
||||
Lint complains about: precedence confusion, `K` may be used before set,
|
||||
main() returns random value to invocation environment, value type used
|
||||
inconsistently, value type declared inconsistently, function argument
|
||||
(number) used inconsistently, function returns value which is always
|
||||
ignored, function returns value which is sometimes ignored.
|
||||
All of which are harmless (famous last words).
|
||||
|
||||
This may or may not work on non ASCII systems (I could not find one to
|
||||
test it on.)
|
||||
|
||||
## Copyright and CC BY-SA 4.0 License:
|
||||
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
HINTS
|
||||
~~~~~
|
||||
For the first program (prog.c):
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
This is a very simple program:
|
||||
|
||||
1. #include <stdio.h>
|
||||
2. main()
|
||||
3. {
|
||||
4. int K,L,M=0;
|
||||
5. FILE *J;
|
||||
6. J=fopen(__FILE__,"r");
|
||||
7. for(;
|
||||
8. (L=getc(J))!=-1;
|
||||
9. L>='J'&&L<='J'+15 &&
|
||||
10. ((M=!M)?K=L:putchar(K-'J'|(L-'J'<<4)))
|
||||
11. );
|
||||
12. exit(0)}
|
||||
|
||||
Lines 1-5 are basic stuff. Line 6 opens the source code for input. Line 7
|
||||
is the loop. Line 8 is read in each character in the file (placed in L)
|
||||
while not EOF(-1). Line 9 is an if expression which filters out all
|
||||
characters not between J and J + 15. Line 10 uses M to execute two different
|
||||
paths the first just stores the character in K. The second path combines
|
||||
the last two characters read in as high and low nibbles of a byte and
|
||||
outputs them. In effect this is a very poor ASCII to binary decoder.
|
||||
The last line is necessary so that make will not stop when it executes
|
||||
this program.
|
||||
|
||||
The second program is encoded into this format and then included (mostly)
|
||||
as a comment.
|
||||
|
||||
Notice that it is impossible to write this program while leaving 16
|
||||
contiguous ASCII characters free for the encoding. Because of this the
|
||||
second program is mostly included as a comment. However, some of the
|
||||
characters of the encoded program are also source code for the decoder.
|
||||
|
||||
For the second program (time.c):
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
1 #include <stdio.h>
|
||||
2 #include <time.h>
|
||||
3 #define o(j,k,m,n,l) {fprintf(j,a[k],m,n,a[l]);fflush(j);}
|
||||
4 char *a[]={"%c+------------+\n","%c+%3d %-8s+\n","seconds","minutes",
|
||||
5 "hours","%s\n","\0337\033[%d;65;H%s\0338"};
|
||||
6 int b[]={0,0,17,14,11,0};
|
||||
7 main(v,c)
|
||||
8 int v;
|
||||
9 char ** c;
|
||||
10 {
|
||||
11 char d[40],*e,f=6;
|
||||
12 time_t g;
|
||||
13 FILE *h,*i;
|
||||
14 while (--f && !pipe(d) && !fork());
|
||||
15 h=fdopen(6-f<<1,"a");
|
||||
16 i=fdopen((6-f<<1)+1,"r");
|
||||
17 for(;;){
|
||||
18 if(f){
|
||||
19 fgets(d,40,i);
|
||||
20 d[strlen(d)-1]='\0';
|
||||
21 if(*d=='0'+f){ sprintf(*c,"%s\n",d+1); o(stdout,6,6-f,d+1,0) }
|
||||
22 if(*d>'0'+f) o(h,5,d,0,0)
|
||||
23 }else{
|
||||
24 time(&g);
|
||||
25 e=asctime(localtime(&g));
|
||||
26 for(v=1;v<6;v++) o(h,v!=1&&v!=6-1,v+'0',atoi(e+b[v]),v)
|
||||
27 sleep(1);
|
||||
28 }}}
|
||||
|
||||
Lines 1 and 2 have to be. Think of 'o' in line 3 as send message with
|
||||
j,k and m as where, format and what. Lines 4 and 5 are all the text
|
||||
strings. Line 6 is the offsets into the time string for the hours,
|
||||
minutes and seconds. Lines 7-13 are basic stuff. Line 14 is the crux of
|
||||
the biscuit. 14 forks off 'f'(6) processes each of which is connected to
|
||||
the ones above and below it with a Unix pipe. It was too difficult to
|
||||
recover the actual fd numbers for the pipe ends in line 14 so I regenerate
|
||||
them and fdopen them (for use with the standard C library functions) on lines
|
||||
15 and 16. Now we have six almost identical processes. Each of which has
|
||||
two files open h and i (up and down). The only difference in each process
|
||||
is the value of f (0 <= f < 6). The five processes where f !=0 are the
|
||||
slave processes and f == 0 is the master. Line 17 says we are going to do
|
||||
this forever. Lines 18 and 23 differentiate between the master and the
|
||||
slaves.
|
||||
|
||||
Lines 19 to 22 are the slave code. Here we read in a line of text from
|
||||
i (down)(line 19) and remove the end of line char (line 20). On line
|
||||
21 if this message is for us (if the first character is our number, f,
|
||||
in ASCII) we do two things:
|
||||
1. We copy the text of the message to *c which is really argv[0].
|
||||
If you are on the correct flavor of Unix this will change the output of
|
||||
the ps(1) command to the string we just put there.
|
||||
2. We send the message (not including the number) to stdout with
|
||||
format number 6 ("\0337\033[%d;65;H%s\0338") If you can read VTxxx
|
||||
(and I read books printed as ANSI/VTxxx codes for fun :-) you know this
|
||||
is the sequence for: remember where we are,
|
||||
go somewhere else,
|
||||
print the message,
|
||||
and return to where we started.
|
||||
Line 22 says if this message is not for us (the number is bigger than ours)
|
||||
send it to h (up).
|
||||
|
||||
Lines 24 to 27 are the master code. Here we get the time and convert it
|
||||
to an ASCII format (lines 24 and 25). Then on line 26 we build and send
|
||||
each of the messages for the slaves. The message uses a different control
|
||||
string for the different slaves. For the first and last slave the message
|
||||
text is just "%c+------------+\n" (slave number, text, newline.) For the
|
||||
other slaves it is "%c+%3d %-8s+\n" (slave number, number, units, newline).
|
||||
The slave number is v+'0'. The number (if used) is atoi(e+b[v]) and the
|
||||
units are just the string in the slave number position.
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
# HINTS
|
||||
|
||||
For the first program (prog.c):
|
||||
|
||||
|
||||
This is a very simple program:
|
||||
|
||||
```
|
||||
1. #include <stdio.h>
|
||||
2. main()
|
||||
3. {
|
||||
4. int K,L,M=0;
|
||||
5. FILE *J;
|
||||
6. J=fopen(__FILE__,"r");
|
||||
7. for(;
|
||||
8. (L=getc(J))!=EOF;
|
||||
9. L>='J'&&L<='J'+15 &&
|
||||
10. ((M=!M)?K=L:putchar(K-'J'|(L-'J'<<4)))
|
||||
11. );
|
||||
12. exit(0);}
|
||||
```
|
||||
|
||||
Lines 1-5 are basic stuff. Line 6 opens the source code for input. Line 7
|
||||
is the loop. Line 8 is read in each character in the file (placed in `L`)
|
||||
while not `EOF` (usually `-1`). Line 9 is an if expression which filters out all
|
||||
characters not between `J` and `J + 15`. Line 10 uses `M` to execute two different
|
||||
paths the first just stores the character in `K`. The second path combines
|
||||
the last two characters read in as high and low nibbles of a byte and
|
||||
outputs them. In effect this is a very poor ASCII to binary decoder.
|
||||
The last line is necessary so that make will not stop when it executes
|
||||
this program.
|
||||
|
||||
The second program is encoded into this format and then included (mostly)
|
||||
as a comment.
|
||||
|
||||
Notice that it is impossible to write this program while leaving 16
|
||||
contiguous ASCII characters free for the encoding. Because of this the
|
||||
second program is mostly included as a comment. However, some of the
|
||||
characters of the encoded program are also source code for the decoder.
|
||||
|
||||
### For the second program (with time.h):
|
||||
|
||||
```
|
||||
1 #include <stdio.h>
|
||||
2 #include <time.h>
|
||||
3 #define o(j,k,m,n,l) {fprintf(j,a[k],m,n,a[l]);fflush(j);}
|
||||
4 char *a[]={"%c+------------+\n","%c+%3d %-8s+\n","seconds","minutes",
|
||||
5 "hours","%s\n","\0337\033[%d;65;H%s\0338"};
|
||||
6 int b[]={0,0,17,14,11,0};
|
||||
7 main(v,c)
|
||||
8 int v;
|
||||
9 char ** c;
|
||||
10 {
|
||||
11 char d[40],*e,f=6;
|
||||
12 time_t g;
|
||||
13 FILE *h,*i;
|
||||
14 while (--f && !pipe(d) && !fork());
|
||||
15 h=fdopen(6-f<<1,"a");
|
||||
16 i=fdopen((6-f<<1)+1,"r");
|
||||
17 for(;;){
|
||||
18 if(f){
|
||||
19 fgets(d,40,i);
|
||||
20 d[strlen(d)-1]='\0';
|
||||
21 if(*d=='0'+f){ sprintf(*c,"%s\n",d+1); o(stdout,6,6-f,d+1,0) }
|
||||
22 if(*d>'0'+f) o(h,5,d,0,0)
|
||||
23 }else{
|
||||
24 time(&g);
|
||||
25 e=asctime(localtime(&g));
|
||||
26 for(v=1;v<6;v++) o(h,v!=1&&v!=6-1,v+'0',atoi(e+b[v]),v)
|
||||
27 sleep(1);
|
||||
28 }}}
|
||||
|
||||
```
|
||||
|
||||
Lines 1 and 2 have to be. Think of `o` in line 3 as send message with
|
||||
`j`,`k` and `m` as where, format and what. Lines 4 and 5 are all the text
|
||||
strings. Line 6 is the offsets into the time string for the hours,
|
||||
minutes and seconds. Lines 7-13 are basic stuff. Line 14 is the crux of
|
||||
the biscuit. 14 forks off `f` (6) processes each of which is connected to
|
||||
the ones above and below it with a Unix pipe. It was too difficult to
|
||||
recover the actual FD numbers for the pipe ends in line 14 so I regenerate
|
||||
them and `fdopen()` them (for use with the standard C library functions) on lines
|
||||
15 and 16. Now we have six almost identical processes. Each of which has
|
||||
two files open `h` and `i` (up and down). The only difference in each process
|
||||
is the value of `f` (`0 <= f < 6`). The five processes where `f !=0` are the
|
||||
slave processes and `f == 0` is the master. Line 17 says we are going to do
|
||||
this forever. Lines 18 and 23 differentiate between the master and the
|
||||
slaves.
|
||||
|
||||
Lines 19 to 22 are the slave code. Here we read in a line of text from
|
||||
`i` (down)(line 19) and remove the end of line char (line 20). On line
|
||||
21 if this message is for us (if the first character is our number, `f`,
|
||||
in ASCII) we do two things:
|
||||
|
||||
1. We copy the text of the message to `*c` which is really argv[0]. If you are
|
||||
on the correct flavor of Unix this will change the output of the `ps(1)` command
|
||||
to the string we just put there.
|
||||
2. We send the message (not including the number) to stdout with format number 6
|
||||
(`"\0337\033[%d;65;H%s\0338"`) If you can read VTxxx (and I read books printed
|
||||
as ANSI/VTxxx codes for fun :-) ) you know this is the sequence for:
|
||||
|
||||
remember where we are,
|
||||
go somewhere else,
|
||||
print the message,
|
||||
and return to where we started.
|
||||
|
||||
Line 22 says if this message is not for us (the number is bigger than ours)
|
||||
send it to `h` (up).
|
||||
|
||||
Lines 24 to 27 are the master code. Here we get the time and convert it
|
||||
to an ASCII format (lines 24 and 25). Then on line 26 we build and send
|
||||
each of the messages for the slaves. The message uses a different control
|
||||
string for the different slaves. For the first and last slave the message
|
||||
text is just `"%c+------------+\n"` (slave number, text, newline.) For the
|
||||
other slaves it is `"%c+%3d %-8s+\n"` (slave number, number, units, newline).
|
||||
The slave number is `v+'0'`. The number (if used) is `atoi(e+b[v])` and the
|
||||
units are just the string in the slave number position.
|
||||
|
||||
@@ -522,13 +522,13 @@ If you join the lines you end up with:
|
||||
|
||||
If you look at column 25 which is the end of the word 'mh111' and you go down to
|
||||
the next row you'll see a 0 and if you go one row down another 0. This is the
|
||||
buffer size, 100, for `u`. The column to the left is the same for the `t`
|
||||
buffer size, 100, for `u`! The column to the left is the same for the `t`
|
||||
variable.
|
||||
|
||||
Thus it seems that in order to get the generated output correct one needs to
|
||||
provide the correct input in comments or possibly by rearranging some of the
|
||||
code (this was required to make the generated code compile at all when changing
|
||||
the buffer size).
|
||||
code (this was actually required to make the generated code compile at all when
|
||||
changing the buffer size, see below).
|
||||
|
||||
### Important points:
|
||||
|
||||
@@ -550,6 +550,103 @@ can cause a compilation error! Make sure that the output of:
|
||||
can be compiled and the output of that new program when fed itself can also be
|
||||
compiled!
|
||||
|
||||
## [1994/shapiro](1994/shapiro/shapiro.c) ([README.md](1994/shapiro/README.md))
|
||||
## STATUS: missing file - please provide it
|
||||
|
||||
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) noted that the
|
||||
README.md file refers to an alternative version of the code that is not
|
||||
obfuscated but it is missing from the entry directory and the archive. Do you
|
||||
have this file?
|
||||
|
||||
We would be grateful if you could provide it to us. If you can provide this
|
||||
file you might consider removing this entry from this file as well but if not
|
||||
we'll take care of it.
|
||||
|
||||
### Important reminder to fix the `-1` value check for `getc()`:
|
||||
|
||||
Cody wants to remind you that he fixed the code to not use `-1` for the return
|
||||
value of `getc()`; this is important because `EOF` is **NOT** guaranteed to be
|
||||
`-1` but rather any negative value. On systems where `EOF != -1` the program
|
||||
would enter an infinite loop until the program crashed, by chance reads a `-1`
|
||||
or was killed. See the README.md for more details. If you don't feel comfortable
|
||||
changing it to `EOF` Cody will happily do it for you but otherwise go right
|
||||
ahead. We'll credit you in the README.md file regardless.
|
||||
|
||||
|
||||
## STATUS: doesn't work with some platforms - please help us fix
|
||||
|
||||
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) pointed out a potential
|
||||
bug in [1994/shapiro](1994/shapiro/shapiro.c) on systems where `EOF != -1` as
|
||||
the code assumes that `EOF` will always be `-1`. As the standard says (see `7.21
|
||||
Input/output<stdio.h>` subsection 1) it only has to be a negative int, not
|
||||
necessarily `-1`. The problem is that the source file's last character is a
|
||||
newline (10 in decimal) and so on systems where `EOF != -1` the `getc()`
|
||||
functions would not terminate the loop (but see below). This would cause a
|
||||
breakage in the entry.
|
||||
|
||||
However due to clever encoding of the code it is not a simple matter of applying
|
||||
the following patch:
|
||||
|
||||
```diff
|
||||
diff --git i/1994/shapiro/shapiro.c w/1994/shapiro/shapiro.c
|
||||
index d2da120c7bc4e251b7624859e48f47f188d398e9..e054a1ceb067b82bf37c07e5ce75e82be7a03b85 100644
|
||||
--- i/1994/shapiro/shapiro.c
|
||||
+++ w/1994/shapiro/shapiro.c
|
||||
@@ -9,11 +9,11 @@
|
||||
/*PPPPVPOQMQRPR*/=0;FILE/*TPSLUMWQT*/ *
|
||||
J/*MPRPKPLQ*/; J= fopen(__FILE__
|
||||
/*T*/,"r");for (;( L/*KPUOWOWMUQ
|
||||
LLOLMPULWLWL WLW LWLWLWLWLWLW
|
||||
LWLWLULVOXP LLV LLLOLMPULOL
|
||||
- MMNP*/=getc (J) )!= -1;L/*
|
||||
+ MMNP*/=getc (J) )!=EOF;L/*
|
||||
OLWLRMMQUL VOX PLLVLLLMQO
|
||||
PMPYPXPNP MQL LVLLLWPSP
|
||||
XPOQNQOPMQ LLV LTj*/>='J'
|
||||
&&L/*LRPYP OQL QMQLLVLLL
|
||||
OLMQVOXPL LVL LLVOe*/<=
|
||||
|
||||
```
|
||||
|
||||
as doing so will cause `warning: illegal character encoding in string
|
||||
literal` and the error `error: source file is not valid UTF-8`. Looking at the
|
||||
file you'll see on line 4 of `shapiro_t2.c`:
|
||||
|
||||
|
||||
```
|
||||
char *a[]={"%c+------------+\n","%c+%3dPRÒ<82>3·Âå&Â"2W6öæF6'Â"Ò<96>æVGW6'¢ <82>öV'7'Â"R2Çå&Â"Â^E33sÃ^E33³UB¶cS³<83>T2Ç^E33<83>#Ò·£<90>æF^G"¶ÕÕ³^GÃ^BÃ^RsÃ^RCÃ^R^SÃ^BÓ·£Ð^V<96>æ<86>bÇ2<96><92>æF^Gb·3<86>^V&^G¢¢^B2¶£°7<86>^V&^GB¶E^CÓÅ¢RÆbÖc³£@<97>ÖVöE^Gr¶£`<94>ÄT^D¢<82>Æ¢<92>¶£p<87><96>ÆV^F<82>ÒÒb^Fbb^B^R^B<97>^FW<86>B<96>^Bbb^B^Rbö&·<86><92><92>²£<80>ÖcFö^FWæ<86>bÓbÆÃ^SÃ"^R&<92>²<93>ÖcFö^FWæ<86><82>bÓbÆÃ^S<93>²^RÃ""'<92>²£`ö&<87>²³<93>²<97>f<86>b<96>²gvVF7<87>BÆB^CÃ<92><96>²C¶5G'ÇVæ<86>B<96>Ò^RÓÕsÂ^Es²£<90>f<86>¢BÖÓs^Bs²b<96>²7^G'<97>æFg<86>¢2Æ"R2Çå&ÂB¶^R<93>²ó<86>2GGöVGÇbÃbÓbÆB¶^RÃ^B<93>Ò§<90>f<86>¢Bæs^Bs²b<96>ò<86><82>ÆRÃBÆ^BÃ^B<93>ÒWÆ6W¶G<97>ÖV<86>br<96>²SÖ^S67F<97>ÖV<86>Âö6^VÆF<97>ÖV<86>br<96><92>²£`ö&<87>b×^S³cÇc³c·²<92>ò<86><82>Æb^WÒ^Scbb^WÒcÓ^RÃb·r^BsÂ^RF÷<96><86>R¶"¶e×<95>Âb<97>2ÇVV^F<87>^R<93>²Ó××§
|
||||
```
|
||||
|
||||
when it should be something entirely different. For what it should be try
|
||||
running `make clobber all ; cat shapiro_t2.c` or else look at the second program
|
||||
in the spoilers file [shapiro.md](1994/shapiro/shapiro.md]).
|
||||
|
||||
Cody is working will be working on this here and there but if you have a fix or
|
||||
any suggestions you're welcome to provide it or them.
|
||||
|
||||
Cody points you to the README.md file for what should happen when the entry is
|
||||
successfully compiled (including no compilation errors when running `make
|
||||
clobber all`).
|
||||
|
||||
Another problem is that in the [shapiro.md](shapiro.md) file the first program
|
||||
does not work.
|
||||
|
||||
### Tips on this entry:
|
||||
|
||||
Cody provides some tips on this entry:
|
||||
|
||||
First: the comments are the important part of this entry. Remove them and the
|
||||
program breaks.
|
||||
|
||||
Second and perhaps part of the problem with changing the code to `EOF` instead
|
||||
of `-1` is the `for` loop particularly to do with the bitwise operations,
|
||||
perhaps also made worse by the seemingly gibberish comments.
|
||||
|
||||
Another important point is that the Makefile compiles the program as
|
||||
`shapiro_t1` so that the source code that corresponds with it is actually
|
||||
[shapiro.c](1994/shapiro/shapiro.c). But notice how running `shapiro_t1` results
|
||||
in different functionality than `shapiro` itself? The source code that
|
||||
`shapiro_t1` generates, `shapiro_t2.c`, is what is compiled into `shapiro`.
|
||||
|
||||
# 1995
|
||||
|
||||
|
||||
Reference in new issue
Block a user