0

I visited this website, https://xcode.darkbyte.ru/

enter image description here

Basically the website takes a text as Input and generates an Image. It also takes an image as input and decodes it back to text. I really wish to know what this is called and how it is done I'd like to know the algorithm [preferably in Java] Please help, Thanks in advance

Aravind Balaji
  • 57
  • 2
  • 10
  • http://stackoverflow.com/questions/1813881/java-ocr-implementation Text to image is fairly easy,however for the reverse you will need some kind of OCR (Optical character recognition) tool – pokeybit May 20 '17 at 16:41
  • I am guessing that they are generating bytes from text using a made up algorithm and then using those bytes to generate color in an image. – SedJ601 May 20 '17 at 16:41
  • 2
    You have 3 (or 4) bytes per pixel to store text information, there is absolutely nothing fancy about it. Take each char and store it into one channel of a pixel. If you want onely use one channel and the resulting channels can be used to make the image "pretty". – luk2302 May 20 '17 at 16:42
  • 1
    @pokeybit it has absolutely nothing to do with ocr, 0%. – luk2302 May 20 '17 at 16:42
  • 1
    This is called "[steganography](https://en.wikipedia.org/wiki/Steganography)". Usually information is hidden in an existing image like a photography, but of course you can artificially create the image where the information will be hidden in. – zett42 May 20 '17 at 16:52
  • @zett42 This doesn't appear to be related to **hiding** text in images (which is what steganography is), but rather just generating any old image for a piece of text (which makes it fairly trivial to do, since you have the entire range of colours to work with, instead of being limited to making generally non-visible changes). – Bernhard Barker May 20 '17 at 21:12
  • Each pixel has a range of colours and each character has a range of values. So the basic approach is literally just converting a number from one base to another, which is trivial. As for different approaches to do this (e.g. if you want it to look "pretty"), there are countless ways, making this question hopelessly too broad for [so]. It's unclear whether you want help with the actual API calls and such to generate the image (as opposed to the logic), but that should be a different question (although there's probably already enough resources covering that). – Bernhard Barker May 20 '17 at 21:24

1 Answers1

3

There are many ways to encode a text (series of bytes) as an image, but the site you quoted does it in a pretty simple and straightforward way. And you can reverse-engineer it easily:

  • Up to 3 chars are coded as 1 pixel; 4 chars as 2 pixels -- we learn from this that only R(ed), G(reen) and B(lue) channels for each pixel are used (and not alpha/transparency channel).

  • We know PNG supports 8 bits per channel, and each ASCII char is 8 bits wide. Let's test if first char (first 8 bits) are stored in red channel.

    • Let's try z... Since z is relatively high in ASCII table (122) and . is relatively low (46) -- we expect to get a redish 1x1 PNG. And we do.
    • Let's try .z.. Is should be greenesh.. And it is.
    • Similarly for ..z we get a bluish pixel.
  • Now let's see what happens with a non-ASCII input. Try entering: (unicode char \u2460). The site html-encodes the string into ① and then encodes that ASCII text into the image as before.

  • Compression. When entering a larger amount of text, we notice the output is shorter then expected. It means the back-end is running some compression algorithm on raw input before (or after?) encoding it as image. By noticing the resolution of the image and maximum information content (HxWx3x8 bits) being smaller than input, we can conclude the compression is done before encoding to image, and not after (thus not relying to PNG compression). We could go further in detecting which compression algorithm is used by encoding the raw input with the common culprits like Huffman coding, Lempel-Zip, LZW, DEFLATE, even Brotli, and comparing the output with bytes from image pixels. (Note we can't detect it directly by inspecting a magic prefix, chances being author stripped anything but the raw compressed data.)

randomir
  • 17,989
  • 1
  • 40
  • 55
  • Thankyou so much! This helped me analyze and observe properly, – Aravind Balaji May 20 '17 at 17:58
  • I also implemented my own algorithm, divided a string into 3 characters each, converted each character to ASCII and stored it in another array. I took those integers, three at a time and assigned it to RGB for each pixel. Thankyou so much. It works. Its not the same as the one in website [the ouput], but this is exactly what Im looking for. – Aravind Balaji May 20 '17 at 18:00
  • 1
    You are welcome, @AravindBalaji. You might also try encoding your unicode text with UTF-8 (a bit shorter coding than html-escape), then running it through LZW, and then encoding it as a 4 bytes per pixel (using alpha channel). – randomir May 20 '17 at 18:10
  • Thankyou, ill look into that too ^_^ – Aravind Balaji May 20 '17 at 18:10