Merge pull request #203 from xexyl/1992-buzzard.1

Format and typo fixes in 1992/buzzard.1/README.md
This commit is contained in:
Landon Curt Noll authored and GitHub committed 2023-03-29 13:47:50 -07:00
commit 5b2e01a42a
1 file changed
+68 -64
+68 -64
View File
@@ -21,80 +21,86 @@ Most Obfuscated Algorithm:
To see good C Preprocessor buzzard.1, try: To see good C Preprocessor buzzard.1, try:
make buzzard.1.cppcb make babble.cppcb
cat buzzard.1.cppcb cat babble.cppcb
Notice how many statements it takes to do anything useful? Notice how many statements it takes to do anything useful?
## Author's comments ## Author's comments;
What you shouldn't think about buzzard.1: What you shouldn't think about buzzard.1:
buzzard.1 doesn't just do a mass of #defines as its obfuscation. `buzzard.1` doesn't just do a mass of #defines as its obfuscation.
What you should be glad about: ### What you should be glad about:
I didn't just submit the post-C-preprocessed output as an entry. I didn't just submit the post-C-preprocessed output as an entry.
#### Cute trick warning:
Cute trick warning: `buzzard.1` contains only a numeric printf, yet sometimes it prints out
buzzard.1 contains only a numeric printf, yet sometimes it prints out
short strings. short strings.
What it does: ### What it does:
buzzard.1 is a simple mathematical program. It expects two numeric `buzzard.1` is a simple mathematical program. It expects two numeric
arguments. arguments.
% buzzard.1 0 <num> ```sh
will print out the factorial of <num>. % ./buzzard.1 0 <num>
```
% buzzard.1 <num1> <num2> will print out the factorial of `<num>`.
will print out the largest common factor of num1 and num2.
% buzzard.1 1 <num2> ```
will print out a factor of num2 if it's composite, or else % ./buzzard.1 <num1> <num2>
it will print a string informing you that num2 is prime. ```
will print out the largest common factor of `num1` and `num2`.
```sh
% ./buzzard.1 1 <num2>
```
will print out a factor of `num2` if it's composite, or else
it will print a string informing you that `num2` is prime.
If the first argument is less than 0, it prints out an If the first argument is less than 0, it prints out an
error message. error message.
What it is: ### What it is:
buzzard.1 is a translator from a pseudo-assembly language into a `buzzard.1` is a translator from a pseudo-assembly language into a subset of C
subset of C suitable for execution on Charles Babbage's suitable for execution on Charles Babbage's Analytical Engine. Or rather, the
Analytical Engine. Or rather, the #defines in buzzard.1 are that `#define`s in `buzzard.1` are that translator. The rest of buzzard.1 is a
translator. The rest of buzzard.1 is a buzzard.1 program. If you run the buzzard.1 program. If you run the whole mess through CPP and a beautifier, you
whole mess through CPP and a beautifier, you will see that will see that all you have is a loop that runs until a variable is not 0, and a
all you have is a loop that runs until a variable is not 0, and sequence of assignment statements. The assignment statements are all of the
a sequence of assignment statements. The assignment statements form `a op= b` or `a = b`. The Engine actually allowed 'a = b op c'. Only `+`,
are all of the form 'a op= b' or 'a = b'. The Engine actually `-`, `/`, and `*` are used--no boolean or bitwise operators. The infinite loop
allowed 'a = b op c'. Only +, -, /, and * are used--no boolean could have been simulated on the AE by connecting the already-processed card
or bitwise operators. The infinite loop could have been stack to the input card stack.
simulated on the AE by connecting the already-processed
card stack to the input card stack.
How to try to understand it: ### How to try to understand it:
*Don't* expand the #defines! Rather, decipher what they do. *Don't* expand the `#define`s! Rather, decipher what they do.
Some of them are mere obfuscational fodder, put in to encourage Some of them are mere obfuscation fodder, put in to encourage
you to run it through CPP. you to run it through CPP.
What it doesn't quite do right as an emulator: ### What it doesn't quite do right as an emulator:
Because of the definitional constraints, calls to atoi(argv[#]) Because of the definitional constraints, calls to `atoi(argv[#])` also appear
also appear inside the loop. These could be put outside-- inside the loop. These could be put outside-- the initial values of the
the initial values of the "registers" on the AE--but the "registers" on the AE--but the macro conventions being used didn't lend
macro conventions being used didn't lend themselves to it. themselves to it.
Theoretical observations: ### Theoretical observations:
The simulated comparison operations only work with a certain The simulated comparison operations only work with a certain
range of numbers; numbers that are too large will cause the range of numbers; numbers that are too large will cause the
@@ -113,13 +119,13 @@ Most Obfuscated Algorithm:
have any. have any.
Definition of the input language to buzzard.1: ### Definition of the input language to buzzard.1 (OR What Exactly Do All The Macros Do?):
(OR What Exactly Do All The Macros Do?)
[Don't read this unless you're stumped!] [Don't read this unless you're stumped!]
MACRO FUNCTION MNEMONIC MACRO FUNCTION MNEMONIC
V begin variable declarations Variable V begin variable declarations Variable
C begin program Code C begin program Code
@@ -149,14 +155,13 @@ Most Obfuscated Algorithm:
X(y) print out hexadecimal value of y heXadecimal X(y) print out hexadecimal value of y heXadecimal
T end of output section and program Terminate T end of output section and program Terminate
You can figure out the other macros yourself. In the sample You can figure out the other macros yourself. In the sample program, I've
program, I've actually implemented subroutines by saving actually implemented subroutines by saving a return address in a variable and
a return address in a variable and then jumping to a routine-- then jumping to a routine-- specifically, a routine that converts a number into
specifically, a routine that converts a number into bcd, so bcd, so it can be output by the hexadecimal output statement.
it can be output by the hexadecimal output statement.
How it works, i.e., how to get useful programs from a op= b ### How it works, i.e., how to get useful programs from a op= b
The essential statement to be able to do to do interesting The essential statement to be able to do to do interesting
programs is the conditional (given that we have loops). programs is the conditional (given that we have loops).
@@ -188,32 +193,31 @@ Most Obfuscated Algorithm:
if (pc == some_constant) y = z; if (pc == some_constant) y = z;
To combine this with other operations, we simply multiply by our To combine this with other operations, we simply multiply by our
(pc == some_constant) flag right after the above 'temp *= x'. (`pc == some_constant`) flag right after the above 'temp `*= x'`.
To evaluate pc == some_constant requires one more trick. We assume To evaluate `pc == some_constant` requires one more trick. We assume that
that numbers can only be in some limited range. Then we use successive numbers can only be in some limited range. Then we use successive additions and
additions and divisions to reduce that number down to -1, 0, or 1. divisions to reduce that number down to `-1`, `0`, or `1`. You could, for
You could, for instance, do this by using mod by 2 and div by 2 to instance, do this by using mod by `2` and div by `2` to count bits, stopping
count bits, stopping after, say, 32 iterations. The number you get after, say, `32` iterations. The number you get is between `0..32`, so another
is between 0..32, so another 6 iterations on it reduces it to 0..6. `6` iterations on it reduces it to 0..6. Three iterations on this produces
Three iterations on this produces 0..2 (3 would be '7'), and then `0..2` (`3` would be `7`), and then two iterations on this produces 0 or 1.
two iterations on this produces 0 or 1. Instead I use a shorter Instead I use a shorter two-divide approach that assumes I'm allowed to use
two-divide approach that assumes I'm allowed to use numbers slightly numbers slightly larger than the numbers I'm operating on.
larger than the numbers I'm operating on.
A similar approach is used to detect positive numbers. A similar approach is used to detect positive numbers.
Note that the obvious code to compute y/x will not work correctly, Note that the obvious code to compute `y/x` will not work correctly,
because every value is computed, even if the pc is not set correctly; because every value is computed, even if the pc is not set correctly;
if x is ever 0 when the real C code reaches this computation the if `x` is ever `0` when the real C code reaches this computation the
program will die. (This was discovered the hard way.) The solution program will die. (This was discovered the hard way.) The solution
is to stick x in a temporary, and if the current code is not about is to stick `x` in a temporary, and if the current code is not about
to be executed, set the temporary to 1. to be executed, set the temporary to `1`.
Thanks to Bill Pugh for bringing the loopability of the AE to Thanks to Bill Pugh for bringing the loop-ability of the AE to
my attention. my attention.
buzzard.1 was originally named 'cb', for obvious reasons, and is `buzzard.1` was originally named 'cb', for obvious reasons, and is
dedicated to the memory of Charles Barrett. dedicated to the memory of Charles Barrett.
## Copyright and CC BY-SA 4.0 License: ## Copyright and CC BY-SA 4.0 License: