Add 2019/diels-grabsch2/try.sh script

The try.sh script looks for sha512sum and shasum. If either of these are
found it will use the one found (in the order of sha512sum first and
shasum -a 512 second) and prog. If neither can be found it uses just
prog. If one of them can be found, however, it shows how the output is
the same.

The prog.c was restored from prog.orig.c. Like 2019/diels-grabsch1 the
purpose is no longer valid and even more problematic is the fact that
the checksum value obviously would not be correct otherwise. Makefile
updated instead.

The README.md file has been format/typo checked.

.gitignore updated - added files that try.sh script uses (though it does
delete them after use).
This commit is contained in:
Cody Boone Ferguson committed 2023-12-15 13:44:53 -08:00
1 parent 4fc1683dc0
commit 51707205e9
6 files changed
+83 -16

No files matched your search

+2
View File
@@ -6,3 +6,5 @@ indent.c
indent.o indent.o
prog prog
prog.orig prog.orig
prog.txt
sha512sum.txt
+1 -1
View File
@@ -38,7 +38,7 @@ include ../../var.mk
# Common C compiler warnings to silence # Common C compiler warnings to silence
# #
CSILENCE= CSILENCE= -Wno-strict-prototypes
# Common C compiler warning flags # Common C compiler warning flags
# #
+10 -10
View File
@@ -15,7 +15,7 @@ make
### Try: ### Try:
```sh ```sh
sha512sum prog.c || shasum -a 512 prog.c ./try.sh
``` ```
@@ -52,11 +52,11 @@ No crypto was broken in the making of this program!
The trick is that under the hood, this program is a quine! That is, it is aware The trick is that under the hood, this program is a quine! That is, it is aware
of its own source code in string representation. But instead of printing that of its own source code in string representation. But instead of printing that
string, its SHA-512 hash is computed and printed. So two major steps were string (its own source), its SHA-512 hash is computed and printed. So two major
needed to obfuscate this program: steps were needed to obfuscate this program:
1. Hide the quine 1. Hide the quine.
2. Hide the SHA-512 computation 2. Hide the SHA-512 computation.
Note that both steps were achieved mostly algorithmically. The code Note that both steps were achieved mostly algorithmically. The code
is otherwise as short and as clean as possible. The implementation is is otherwise as short and as clean as possible. The implementation is
@@ -110,11 +110,11 @@ the cube roots of the first 80 primes. So the round constants are
calculated at runtime, which makes the program shorter and adds calculated at runtime, which makes the program shorter and adds
another layer of obfuscation. another layer of obfuscation.
While this sounds like just iterating primes and executing pow(), this While this sounds like just iterating primes and executing `pow(3)`, this
turned out to be harder than expected. If we were computing SHA-256, turned out to be harder than expected. If we were computing SHA-256,
it would have been as simple as that, because the round constants it would have been as simple as that, because the round constants
would have been 32-bit values. However, SHA-512 needs the cube roots would have been 32-bit values. However, SHA-512 needs the cube roots
at 64-bit precision, while double has only 53-bit mantissa precision. at 64-bit precision, while `double` has only 53-bit mantissa precision.
Using higher-precision floating point is no option here, because the Using higher-precision floating point is no option here, because the
program is meant to be portable C99. And implementing arbitrary-precision program is meant to be portable C99. And implementing arbitrary-precision
@@ -145,7 +145,7 @@ around 7, so we need to compute with 3 bits for the integral part and
The reason for challenge 3 is that the cube of a 67-bit number is The reason for challenge 3 is that the cube of a 67-bit number is
`3*67=201` bits, but fortunately we only need to check if it is close `3*67=201` bits, but fortunately we only need to check if it is close
enough to the actual prime. It won't be exactly e.g. `409.0000...` enough to the actual prime. It won't be exactly `409.0000...`
anyway, but must be accurate enough to distinguish the correct cube anyway, but must be accurate enough to distinguish the correct cube
root from its neighbours, e.g. the same number with the 64th root from its neighbours, e.g. the same number with the 64th
fractional digit increased. fractional digit increased.
@@ -167,8 +167,8 @@ That's it.
Well, I could continue with details about the encoding of the internal Well, I could continue with details about the encoding of the internal
state values into the string, how to avoid escaping issues, how to state values into the string, how to avoid escaping issues, how to
find short notations for various loops, how to get rid of if(), where find short notations for various loops, how to get rid of `if()`, where
the final "\";\n" is stored, how to eliminate intermediate values and the final `"\";\n"` is stored, how to eliminate intermediate values and
arrays by reordering of operations, and so on. But those were all arrays by reordering of operations, and so on. But those were all
minor issues compared to the challenges described above. What's minor issues compared to the challenges described above. What's
documented here is all you need to know to write your own version of documented here is all you need to know to write your own version of
+1 -1
View File
@@ -10,6 +10,6 @@ b*c>>32))*a>>21)+(3*a*a*b>>6)+((b>>4)*(b>>4)*b>>46))>>18)+a*a*a)h(m,t((b<<16)|(c
^(~a&c))i(r,b(a,1)^b(a,8)^(a>>7))g(o,0,0,c<8;c++,a*256+w[b*8+c])g(d,0,0,c<13;c++,a*31+w[b*13+c]-96)g(p,0,4,c;c/=2,a|c*m(b,a|c,a) ^(~a&c))i(r,b(a,1)^b(a,8)^(a>>7))g(o,0,0,c<8;c++,a*256+w[b*8+c])g(d,0,0,c<13;c++,a*31+w[b*13+c]-96)g(p,0,4,c;c/=2,a|c*m(b,a|c,a)
)g(q,0,1ull<<63,c;c/=2,a|c*m(b,p(b),a|c))g(v,b>1,2,c<b;c++,a&&b%c)g(l,b?l(b-1)+1:2,a,!v(c);c++,c+1)j(n,z d=a[7]+u(a[4])+s(a[4],a )g(q,0,1ull<<63,c;c/=2,a|c*m(b,p(b),a|c))g(v,b>1,2,c<b;c++,a&&b%c)g(l,b?l(b-1)+1:2,a,!v(c);c++,c+1)j(n,z d=a[7]+u(a[4])+s(a[4],a
[5],a[6])+q(l(*b))+c[*b%16];f(8,a[7-e]=e-3?e-7?a[6-e]:d+_a(a[0])+x(a[1],a[2],a[3]):d+a[3])f(16*(*b%16>14),c[e]+=c[(e+9)%16]+r(c[ [5],a[6])+q(l(*b))+c[*b%16];f(8,a[7-e]=e-3?e-7?a[6-e]:d+_a(a[0])+x(a[1],a[2],a[3]):d+a[3])f(16*(*b%16>14),c[e]+=c[(e+9)%16]+r(c[
(e+1)%16])+_(c[(e+14)%16])))j(k,f(8,b[e]=a[e])f(80,n(a,&e,c))f(8,a[e]+=b[e]))int main(void){z a[8],b[8],c[16];f(8,a[e]=d(e))f(16,c[e (e+1)%16])+_(c[(e+14)%16])))j(k,f(8,b[e]=a[e])f(80,n(a,&e,c))f(8,a[e]+=b[e]))int main(){z a[8],b[8],c[16];f(8,a[e]=d(e))f(16,c[e
]=e-15?o(e):d(8))k(a,b,c);f(16,c[e]=e?e-15?0:11264:1ull<<63)k(a,b,c);f(8,printf("%016llx%s",a[e],e-7?"":"\n"))return!w;}y*w=(y*) ]=e-15?o(e):d(8))k(a,b,c);f(16,c[e]=e?e-15?0:11264:1ull<<63)k(a,b,c);f(8,printf("%016llx%s",a[e],e-7?"":"\n"))return!w;}y*w=(y*)
"crsmyiajqhwy{unwa|hjoi`hlxhpxrzb~edko~rtr~ileqyjk`znqgsuitvgqnfdfa||wedvnmhozkpokootqzcexeld~oibqzpcsuw{ib{x`m`hsa`jmn}wcfzpb"; "crsmyiajqhwy{unwa|hjoi`hlxhpxrzb~edko~rtr~ileqyjk`znqgsuitvgqnfdfa||wedvnmhozkpokootqzcexeld~oibqzpcsuw{ib{x`m`hsa`jmn}wcfzpb";
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env bash
#
# try.sh - demonstrate IOCCC winner 2019/diels-grabsch2
#
# 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
SHA512SUM="$(type -P sha512sum)"
SHASUM="$(type -P shasum)"
if [[ -z "$SHA512SUM" && -z "$SHASUM" ]]; then
echo "$ ./prog" 1>&2
./prog
elif [[ -n "$SHA512SUM" ]]; then
echo "$ $SHA512SUM prog.c" 1>&2
"$SHA512SUM" prog.c
echo 1>&2
echo "$ ./prog" 1>&2
./prog
echo 1>&2
echo "$ $SHA512SUM prog.c | cut -f 1 -d' ' > sha512sum.txt" 1>&2
"$SHA512SUM" prog.c | cut -f 1 -d' ' > sha512sum.txt
echo "$ ./prog > prog.txt" 1>&2
./prog > prog.txt
echo 1>&2
echo "$ diff -s sha512sum.txt prog.txt" 1>&2
diff -s sha512sum.txt prog.txt
rm -f sha512sum prog.txt
elif [[ -n "$SHASUM" ]]; then
# Be extra careful and don't use 'else'
echo "$ $SHASUM -a 512 prog.c" 1>&2
"$SHASUM" -a 512 prog.c
echo 1>&2
echo "$ ./prog" 1>&2
./prog
echo 1>&2
echo "$ $SHASUM -a 512 prog.c | cut -f 1 -d' ' > sha512sum.txt" 1>&2
"$SHASUM" -a 512 prog.c | cut -f 1 -d' ' > sha512sum.txt
echo "$ ./prog > prog.txt" 1>&2
./prog > prog.txt
echo 1>&2
echo "$ diff -s sha512sum.txt prog.txt" 1>&2
diff -s sha512sum.txt prog.txt
rm -f sha512sum prog.txt
fi
+5 -4
View File
@@ -4154,10 +4154,11 @@ having tarballs for each individual entry as a convenience.
## <a name="2019_diels-grabsch2"></a>[2019/diels-grabsch2](/2019/diels-grabsch2/prog.c) ([README.md](/2019/diels-grabsch2/README.md])) ## <a name="2019_diels-grabsch2"></a>[2019/diels-grabsch2](/2019/diels-grabsch2/prog.c) ([README.md](/2019/diels-grabsch2/README.md]))
[Cody](#cody) made the author's statement that the entry compiles cleanly true by fixing [Cody](#cody) added the [try.sh](/2019/diels-grabsch2/try.sh) script. This
`warning: a function declaration without a prototype is deprecated in all script will try and show the difference (i.e. the same output) between the
versions of C` (in main()). Not strictly necessary but if he's making fixes he program and the result of `sha512sum` or `shasum -a 512` if either of those
might as well. tools can be found but otherwise it'll just run the program itself, showing its
own sha512sum value.
## <a name="2019_dogon"></a>[2019/dogon](/2019/dogon/prog.c) ([README.md](/2019/dogon/README.md)) ## <a name="2019_dogon"></a>[2019/dogon](/2019/dogon/prog.c) ([README.md](/2019/dogon/README.md))