Brainhash
- The title of this article is not correct because of technical limitations. The correct title is actually Brain#.
Brain# is just a cool encoding of brain**** by User:Esolangist
Encoding
First, you convert BF to binary using this table:
| First encoding of Brain# | brainfuck |
|---|---|
0 |
+
|
1 |
-
|
2 |
<
|
3 |
>
|
4 |
,
|
5 |
.
|
6 |
[
|
7 |
]
|
Next, convert the number to ASCII numbers (its value) and convert it back.
4 > 52 > 53 50
There, you have Brain#.
Example.
We take the cat program ,[.,]
Now it's 46547.
How about some 52 54 53 52 55?
Now what about 53 50 53 52 53 51 53 50 53 53?
(That last one was the cat in Brain#.)
Algorithm
A valorized species of formality anent the decoding algorithm shall constitute the following pseudocode's tmema's contribution:
function getFirstPassCipher (brainfuckToken)
Input:
brainfuckToken: One of the eight recognized brainfuck command
symbols.
Output:
firstPassCipher: The first-pass cipher corresponding to the
BRAINFUCK_TOKEN and representing a decimal
digit in the closed integer interval [0, 7].
Process:
let firstPassCipher ← nil
if brainfuckToken = "+" then
firstPassCipher ← 0
else if brainfuckToken = "-" then
firstPassCipher ← 1
else if brainfuckToken = "<" then
firstPassCipher ← 2
else if brainfuckToken = ">" then
firstPassCipher ← 3
else if brainfuckToken = "," then
firstPassCipher ← 4
else if brainfuckToken = "." then
firstPassCipher ← 5
else if brainfuckToken = "[" then
firstPassCipher ← 6
else if brainfuckToken = "]" then
firstPassCipher ← 7
else
error: no brainfuck token
end if
return firstPassCipher
end function
function getASCIICode (digit)
Input:
digit: The decimal digit, interpreted as a character
rather than a numeric object, whose ASCII code
shall be determined.
Output:
asciiCode: The ASCII code for the decimal digit considered as
a character.
Process:
let asciiCode ← 48 + digit
return asciiCode
end function
function encodeBrainfuckProgram (brainfuckProgram)
Input:
brainfuckProgram: The brainfuck program to encode according to
the Brainhash standard.
Output:
brainhashProgram: The encoded BRAINFUCK_PROGRAM as an ordered
list of integer number, each member an
incolant of the closed integral interval of
[48, 55].
Process:
let brainhashProgram ← empty ordered list
for character bfToken in brainfuckProgram do
let firstPassCipher ← getFirstPassCipher(bfToken)
let secondPassCipher ← getASCIICode(firstPassCipher)
let secondPassDigit1 ← first digit of secondPassCipher
let secondPassDigit2 ← second digit of secondPassCipher
let thirdPassCipher1 ← getASCIICode(secondPassDigit1)
let thirdPassCipher2 ← getASCIICode(secondPassDigit2)
append thirdPassCipher1 to brainhashProgram
append thirdPassCipher2 to brainhashProgram
end for
return brainhashProgram
end function
Examples
Truth-Machine
A truth-machine equivalent to the brainfuck code ,.[-->+[>>]<[.]<<] shall be adduced below:
53 50 53 51 53 52 52 57 52 57 53 49 52 56 53 52 53 49 53 49 53 53 53 48 53 52 53 51 53 53 53 48 53 48 53 53
Hello, World!
This program, tantamount to brainfuck's +[-->-[>>+>-----<<]<--<---]>-.>>>+.>>..+++[.>]<<<<.+++.------.<<-.>>>>+., issues the message “Hello, World!” to the standard output conduit:
52 56 53 52 52 57 52 57 53 49 52 57 53 52 53 49 53 49 52 56 53 49 52 57 52 57 52 57 52 57 52 57 53 48 53 48 53 53 53 48 52 57 52 57 53 48 52 57 52 57 52 57 53 53 53 49 52 57 53 51 53 49 53 49 53 49 52 56 53 51 53 49 53 49 53 51 53 51 52 56 52 56 52 56 53 52 53 51 53 49 53 53 53 48 53 48 53 48 53 48 53 51 52 56 52 56 52 56 53 51 52 57 52 57 52 57 52 57 52 57 52 57 53 51 53 48 53 48 52 57 53 51 53 49 53 49 53 49 53 49 52 56 53 51
Decoder and Encoder Implementation
Note from User:Esolangist: This isn't official, but you can use it I guess. It looks like Common Lisp to me so run it in a Common Lisp interpreter.
The following provides a decoder from Brain# to brainfuck, and vice versa, implemented in the Common Lisp programming language. Please heed that the incorporated nimiety ensues from the verbatim replication of the transcription algorithm, rather than a simple table-based solution, which would harness the inambiguous nature of the mappings betwixt the two languages' tokens:
(deftype first-pass-cipher ()
"The \"first-pass-cipher\" type defines the cipher associated with the
Brain# encoding's first stage as an integral number occupying the
closed interval [0, 7]."
'(integer 0 7))
;;; -------------------------------------------------------
(deftype decimal-digit ()
"A decimal digit as an integer in the range [0, 9]"
'(integer 0 9))
;;; -------------------------------------------------------
(deftype ascii-code-of-digit ()
"The ASCII code of a digit as an integer in the range [48, 57]."
'(integer 48 57))
;;; -------------------------------------------------------
(deftype destination ()
"Defines a sink for output operations."
'(or null (eql T) stream string))
;;; -------------------------------------------------------
(defun interpret-as-a-boolean-value (object)
"Converts the OBJECT into a \"boolean\" value."
(declare (type T object))
(the boolean (not (null object))))
;;; -------------------------------------------------------
(defun whitespace-character-p (candidate)
"Determines whether the CANDIDATE represents a whitespace character."
(declare (type character candidate))
(the boolean
(interpret-as-a-boolean-value
(member candidate '(9 10 11 12 13 32)
:key #'code-char :test #'char=))))
;;; -------------------------------------------------------
(defun locate-the-next-token (source start-index)
"Returns the next token and its exclusive end index into the SOURCE."
(declare (type string source))
(declare (type fixnum start-index))
(let* ((word-start-index
(or (position-if-not #'whitespace-character-p source
:start start-index)
(length source)))
(word-end-index
(or (position-if #'whitespace-character-p source
:start word-start-index)
(length source))))
(declare (type fixnum word-start-index word-end-index))
(the (values string fixnum)
(values (subseq source word-start-index word-end-index)
word-end-index))))
;;; -------------------------------------------------------
(defmacro with-token-iterator ((driver-name source) &body body)
"Evaluates the SOURCE, and evaluates the BODY forms, granting these
the adit to the SOURCE's ensconced tokens by adminiculum of a local
function of niladic signature, whose agnomination is communicated
with the DRIVER-NAME, returning upon its invocation the next token
as a fresh string, and finally returns the desinent BODY form's
results."
(let ((evaluated-source (gensym))
(search-start-index (gensym))
(next-token (gensym)))
(declare (type symbol evaluated-source))
(declare (type symbol search-start-index))
(declare (type symbol next-token))
`(let ((,evaluated-source ,source)
(,search-start-index 0)
(,next-token ""))
(declare (type string ,evaluated-source))
(declare (type fixnum ,search-start-index))
(declare (type string ,next-token))
(flet ((,driver-name ()
"Returns the next token from the SOURCE as a string."
(multiple-value-setq (,next-token ,search-start-index)
(locate-the-next-token
,evaluated-source ,search-start-index))
(the string ,next-token)))
,@body))))
;;; -------------------------------------------------------
(declaim (type (simple-base-string 8) +BRAINFUCK-INSTRUCTIONS+))
;;; -------------------------------------------------------
(defconstant +BRAINFUCK-INSTRUCTIONS+
(coerce "+-<>,.[]" 'simple-base-string)
"Maps the brainfuck instructions to their zero-based indices, which
conincide with the first-pass cipher in the range [0, 7].")
;;; -------------------------------------------------------
(defun brainfuck-instruction-p (candidate)
"Determines whether the CANDIDATE represents a brainfuck instruction."
(declare (type character candidate))
(the boolean
(interpret-as-a-boolean-value
(find candidate +BRAINFUCK-INSTRUCTIONS+ :test #'char=))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; -- Implementation of the brainfuck-to-Brain# encoder. -- ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; brainfuck token to integer in [0, 7].
(defun first-pass-encode-the-instruction (brainfuck-instruction)
"Encodes the BRAINFUCK-INSTRUCTION into the first-pass cipher as an
integer number from the closed interval [0, 7]."
(declare (type standard-char brainfuck-instruction))
(the first-pass-cipher
(or (position brainfuck-instruction +BRAINFUCK-INSTRUCTIONS+
:test #'char=)
(error "Cannot encode the brainfuck token \"~c\"."
brainfuck-instruction))))
;;; -------------------------------------------------------
;; Digit in [0, 9] to ASCII code in [48, 57].
(defun second-pass-encode-the-instruction (first-pass-cipher)
"Encodes the FIRST-PASS-CIPHER into its corresponding second-pass
cipher tantamount, that is, its ASCII code."
(declare (type decimal-digit first-pass-cipher))
(the ascii-code-of-digit
(+ 48 first-pass-cipher)))
;;; -------------------------------------------------------
;; ASCII code in [48, 57] to twissel of ASCII code in [48, 57].
(defun third-pass-encode-the-instruction (second-pass-cipher)
"Returns the ASCII code of the SECOND-PASS-CIPHER's first digit and
that of its second digit in this order."
(declare (type ascii-code-of-digit second-pass-cipher))
(multiple-value-bind (first-digit second-digit)
(floor second-pass-cipher 10)
(declare (type (integer 4 5) first-digit))
(declare (type (integer 0 9) second-digit))
(the (values ascii-code-of-digit ascii-code-of-digit)
(values
(second-pass-encode-the-instruction first-digit)
(second-pass-encode-the-instruction second-digit)))))
;;; -------------------------------------------------------
(defun encode-the-brainfuck-code (code &key (destination NIL))
"Converts the piece of brainfuck source CODE into its Brain# encoding
and writes the resul to the DESTINATION, returning for a non-\"NIL\"
DESTINATION the \"NIL\" value; otherwise, for a \"NIL\" DESTINATION,
responds with a fresh string comprehending the encoded content."
(declare (type string code) (type destination destination))
(the (or null string)
(if destination
(loop
with first-output-p of-type boolean = T
for current-token of-type character across code
when (brainfuck-instruction-p current-token) do
(multiple-value-bind (left-cipher right-cipher)
(third-pass-encode-the-instruction
(second-pass-encode-the-instruction
(first-pass-encode-the-instruction current-token)))
(declare (type ascii-code-of-digit left-cipher))
(declare (type ascii-code-of-digit right-cipher))
(format destination "~@[ ~*~]~d ~d"
(not first-output-p)
left-cipher
right-cipher)
(setf first-output-p NIL)))
(with-output-to-string (encoded-program)
(declare (type string-stream encoded-program))
(encode-the-brainfuck-code code
:destination encoded-program)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; -- Implementation of the Brain#-to-brainfuck decoder. -- ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun get-the-digit-by-its-ascii-code (character-code)
"Returns the integral value of the decimal digit represented by its
ASCII CHARACTER-CODE."
(declare (type ascii-code-of-digit character-code))
(the decimal-digit (digit-char-p (code-char character-code))))
;;; -------------------------------------------------------
;; Example: (53, 50) => 52
(defun decode-the-third-pass-cipher (third-pass-cipher-1
third-pass-cipher-2)
"Decodes the third-pass cipher moeities into the second-pass cipher
by replacing both inputs, construed as ASCII codes, by their decimal
digits and concatenating them."
(declare (type ascii-code-of-digit third-pass-cipher-1))
(declare (type ascii-code-of-digit third-pass-cipher-2))
(the ascii-code-of-digit
(+ (* (get-the-digit-by-its-ascii-code third-pass-cipher-1) 10)
(get-the-digit-by-its-ascii-code third-pass-cipher-2))))
;;; -------------------------------------------------------
;; Example: 52 => 4
(defun decode-the-second-pass-cipher (second-pass-cipher)
"Decodes the SECOND-PASS-CIPHER and returns the first-pass cipher
by interpreting the input as the ASCII code of a decimal digit from
the range [0, 7]."
(declare (type ascii-code-of-digit second-pass-cipher))
(the first-pass-cipher (get-the-digit-by-its-ascii-code second-pass-cipher)))
;;; -------------------------------------------------------
;; Example: 4 => ","
(defun decode-the-first-pass-cipher (first-pass-cipher)
"Decodes the FIRST-PASS-CIPHER into the corresponding brainfuck symbol."
(declare (type first-pass-cipher first-pass-cipher))
(the standard-char (schar +BRAINFUCK-INSTRUCTIONS+ first-pass-cipher)))
;;; -------------------------------------------------------
(defun parse-the-ascii-code-representing-a-digit (source)
"Parses the SOURCE as an ASCII code in the range [48, 57]."
(declare (type string source))
(let ((extracted-integer (parse-integer source)))
(declare (type integer extracted-integer))
(the ascii-code-of-digit
(if (<= 48 extracted-integer 57)
extracted-integer
(error "The number ~d does not represent a decimal digits ~
ASCII code." extracted-integer)))))
;;; -------------------------------------------------------
(defun decode-the-brainhash-code (code &key (destination NIL))
"Decodes the piece of Brainhash source CODE into its equivalent
brainfuck program, writes thilk to the DESTINATION, and returns for
a non-\"NIL\" DESTINATION the \"NIL\" value; otherwise produces a
fresh string comprehending the output."
(declare (type string code) (type destination destination))
(the (or null string)
(if destination
(with-token-iterator (request-the-next-token code)
(flet ((request-the-next-third-pass-cipher ()
"Reads the next token from the CODE, and, if a digit's
ASCII code, returns the same; otherwise produces NIL."
(the (or null ascii-code-of-digit)
(let ((next-token (request-the-next-token)))
(declare (type string next-token))
(unless (string= next-token "")
(parse-the-ascii-code-representing-a-digit next-token))))))
(loop
for third-pass-cipher-1
of-type (or null ascii-code-of-digit)
= (request-the-next-third-pass-cipher)
for third-pass-cipher-2
of-type (or null ascii-code-of-digit)
= (request-the-next-third-pass-cipher)
while third-pass-cipher-1 do
(format destination "~c"
(decode-the-first-pass-cipher
(decode-the-second-pass-cipher
(decode-the-third-pass-cipher
third-pass-cipher-1 third-pass-cipher-2)))))))
(with-output-to-string (brainfuck-code)
(declare (type string-stream brainfuck-code))
(decode-the-brainhash-code code :destination brainfuck-code)))))