| ▲ | sixhobbits 4 days ago |
| I did something similar a while back but using all the invisible characters to encode extra data into telegram messages for metadata storage https://github.com/sixhobbits/unisteg |
|
| ▲ | velcrovan 4 days ago | parent | next [-] |
| I had fun writing a Racket version: #lang racket/base
(require net/base64
threading)
(define FIRST-INVISIBLE-CHAR 917760)
(define (invis-encode str)
(list->string
(for/list ([c (in-list (string->list str))]
#:do [(define cnum (char->integer c))]
#:when (<= cnum 127))
(integer->char (+ cnum FIRST-INVISIBLE-CHAR)))))
(define (invis-decode str)
(list->string
(for/list ([c (in-list (string->list str))]
#:do [(define plaintxt-c (- (char->integer c) FIRST-INVISIBLE-CHAR))]
#:when (> plaintxt-c 0))
(integer->char plaintxt-c))))
(define (hide secret plain)
(~> (string->bytes/utf-8 secret)
(base64-encode #"") ; use #"" vs #"\r\n" to prevent line-wrapping
(bytes->string/utf-8)
(invis-encode)
(string-append plain _)))
(define (unhide ciphertext)
(~> (invis-decode ciphertext)
(string->bytes/utf-8)
(base64-decode)
(bytes->string/utf-8)))
(module+ test
(require rackunit)
(define secret "this is a s3cret message. ssh")
(define plaintext "Hey you, nothing to see here.")
(define to-share (hide secret plaintext))
(check-equal? (string-length to-share) 69) ; count of bytes
(check-equal? (string-grapheme-count to-share) 29) ; 29 actually-visible graphemes
(check-equal? secret (unhide to-share)))
|
| |
| ▲ | askonomm 4 days ago | parent [-] | | Threading is done with the wave character ~ in Racket? I can't decide if I hate it or not (am used to Clojure's ->). I think my pinky finger doesn't like ~. | | |
|
|
| ▲ | franga2000 4 days ago | parent | prev [-] |
| I was very confused why this would be useful for Telegram messages, but the Why? part of the readme makes perfect sense. Great workaround for a stupid limitation! |