fernjager $cat /dev/urandom

Go v1.2.1 ARM Builds

These builds include godoc as well. The debs are are 35 MB in size and 135 MB when installed.

Raspberry Pi (ARMv6)

# Direct Link
wget http://fernjager.net/files/go1.2.1-multiarch-armv6.deb

# SHA1 http://fernjager.net/files/go1.2.1-multiarch-armv6.deb.sha1
# Filelist http://fernjager.net/files/go1.2.1-multiarch-armv6.deb.lst

# To Install
sudo dpkg -i go1.2.1-multiarch-armv6.deb

# To Uninstall
sudo dpkg -r go1.2.1

Chromebook (ARMv7)

# Direct Link
wget http://fernjager.net/files/go1.2.1-multiarch-armv7.deb

# SHA1 http://fernjager.net/files/go1.2.1-multiarch-armv7.deb.sha1
# Filelist http://fernjager.net/files/go1.2.1-multiarch-armv7.deb.lst

# To Install
sudo dpkg -i go1.2.1-multiarch-armv7.deb

# To Uninstall
sudo dpkg -r go1.2.1

Robert's Journal System (RJS)

In my latest attempt to learn Russian, I have tasked myself to keep an organized notebook as a learning aid. Note that the system described here simply serves as an additional tool to a comprehensive suite- not a substitute for full-spectrum language instruction.

In fact, prerequisites for use of this system include the use of a proper grammar book, as well as the ability to have a native speaker review written entries.

What You'll Need

Any notebook will do, divided into four sections:

Topics / Index - 2 pages

Reference Section - 5-10%

Written Entries - 60-75%

Scratchpad / Notes - 20-30%

For example, I'll be keeping a monthly notebook with 80 pages:

2 pages for topics/index

4 pages of reference material

60 pages of vocab/writing pages, with 30 pages actually dedicated to written entries

14 pages for notes

Topics / Index

The first two facing pages should be left blank as an index/table of contents for all the sections. These pages are to be filled out as the notebook grows. Groups of ideas, similar vocabulary tracks can be categorized in this section.

Reference Section

This section is pre-planned and may be penned in ink, or contain notes glued/stapled to the pages. It should also be as short as possible, as it serves solely as a quick reference with the least amount of information that is needed to write whole sentences in the target language.

Suggestions for reference content:

  • Conjugation charts
  • Numbers, number rules
  • Irregular spelling/grammar rules
  • Pronunciation rules
  • Short phrases, connective words
  • General rules of thumb
  • Key Vocabulary

To come up with the reference pages, simply write a composition or conversation from scratch, and record down what information you reference while doing so.

Reference material can even consist of temporary topics that you are trying to learn. By the time you have finished with the notebook and moved on to a new one, you will have become quite familiar with those topics.

On the other hand, if the notebook is large and will last for a while, then it is prudent to have the section contain reference material that is as general as possible.

Written Entries

Each journal entry will take up two pages, which make up a spread, or a pair of facing pages.

Left Page: Vocab and Phrases Section

This section contains a list of vocabulary, rules, or phrases that you are trying to learn/become acquainted with

  • General vocabulary: Verbs, nouns, adjectives, adverbs, subjects, etc.
  • Phrases, idioms
  • Grammar patterns

Such entries can come with:

  • Usage examples
  • Definitions
  • Mnemonics, memory aids
  • Pronunciation markers/aids

Right Page: Writing Entry

  • Writing practice in pencil: The goal is to utilize the vocabulary from the left page.

The entries could consist of short stories, essays, poems, conversations, or continuation of entries from before.

It's always good to switch between different writing styles- from a formal letter to a mock conversation. It certainly helps to build on previous vocabulary from earlier pages.

Some sources of ideas include:

  • Cues from environment - write about everyday, mundane things. Expand on that using imagination, write a story.
  • If you're traveling, it could serve as a travel journal, documenting life abroad in the target language
  • Tap into your imagination and write a story

Now what?

Now that the entry is written to the best of your ability, the next thing to do is to post the journal entries on language exchange/penpals sites to get multiple opinions.

This also provides the opportunity to practice typing skills.

Then, collate all the feedback, go back, review, and fix the entry by making corrections or re-writing it altogether.

Scratchpad / Notes

You may choose to fill this section backwards, from the end of the notebook to the front, to guarantee the greatest possible space for journal entries.

Anything goes here, from penmanship practice to a temporary place to organize thoughts and observations.

What to take notes of:

If you're traveling the country, keep the scratchpad section as large as possible to keep track of conversations, signage, and cultural observations. Notebooks with pockets on the back cover are especially useful in keeping small items. The receipt or train ticket that you just picked up could be fitted it in the pocket for later perusal. Look up the vocabulary and incorporate it into your writing entries

  • Slang you see and hear in movies, TV-shows, literature, radio
  • Notes from conversations with tutors, everyday conversation, penpals, etc.

Final Thoughts

  • Remember to index related content-notes, writing entries for future reference.
  • Include dates in entries keep track of progress.
  • Practice reading aloud, type, etc.
  • On the size of the journal: This system is flexible in that the notebook works for both the short term and long term. It is not timed, you can do an entry a day, an entry a week, and so on.

ncGKS - A PGP Keyserver written in Bash shell script


A PGP Keyserver written in Bash shell script. "Netcat GnuPG Key Server", or commonly known as "Bash GKS"

Why write this?

The PGP Key server scene (admittedly, a small scene) is alarmingly homogenous with the dominant SKS running everywhere.

It's good to have other options too! In this case, we are different/advantageous on the following points:

  • Low System Requirements - Runs on minimal hardware/OS setups (i.e. wireless SD cards, routers) without the need to install Ocaml and Berkeley DB (in the case of SKS).
  • Dependencies: None, really. Perl and awk free! [GnuPG, netcat, bash, tr, grep, GNU Coreutils: mkfifo, rm, sed, echo, printf]
  • Fast Adhoc Deployments - This is perfect for setting up something small for an offline group of people to share, manage, and easily exchange keys.

What it is not?

I pity the fool who runs this as a public facing service.

  • Insecure - Runs gpg directly on raw input with minor sanitization.
  • No database, no caching - Backed by GPG's flat file keystore, which certainly has not won any distinctions in industry.
  • Netcat - To ensure wide compatibility, netcat is used such that it can only handle one connection at a time.
  • Service Easily DOS'd - Following the previous point, the service can be easily locked up with requests even with connection timeouts.
  • No replication - For all the reasons above, it doesn't have fancy reconciliation and replication of data to other instances of the keyserver.

How do I use it?

bash ncGKS.sh

The keyserver listens on port 11371 for incoming requests. Pull up http://localhost:11371/ to take a look.

Point your GnuPG client to this keyserver. In ~/.gnupg/config, simply add "keyserver hkp://this-server-address"

How do I search for a key from the keyserver from GnuPG?

gpg --search-key <keywords>

How do I send a key to the keyserver from GnuPG?

gpg --send-key <951EE9FB>

How do I retrieve a key from the keyserver from GnuPG?

gpg --recv-key <951EE9FB>


  • Works with GNU bash, version 4.2.42(2)-release (i386-apple-darwin12.2.1), netcat version unknown, and gpg (GnuPG/MacGPG2) 2.0.19

Chinese/Japanese/Korean Typesetting Tool

Here's a cool utility that renders Chinese/Japanese/Korean text in the traditional, vertical, right-to-left format without the need for a fancy word processor. http://type.fernjager.net/

Main Editing Screen

Main Screen

Portrait or Landscape Mode when Printing

Print Screen

How to Use:

Type or paste your text into the top right textbox

Play around! Add spaces and text so that everything lines up. Fiddle with the sliders under the canvas/font size boxes.

After you are done editing to your satisfaction, you can choose to finalize the document, which makes it permanently uneditable by anyone.

Then, simply print, copy as text & html, or share the link! People are able to view and print your document if they visit this URL


Vertical Wrap - Adjusts the number of vertical characters allowed in each column. Characters start again from the top of the next column, right-to-left.

Canvas Width - Adjusts how close together the columns of text should be.

Canvas Position - Adjusts the position where the text in the box should be centered.

Vertical Character Spacing - Adjust how much spacing is above and below each character.


Language instruction - Quickly create lessons and homework by omitting characters or by toggling the grid, so that students can print the assignment and fill in the characters.

Signage - Quickly format and print out text in this traditional format for decoration and information.

Composition - Quickly create and share poetry or essays in this traditional format. The short link can be easily shared and be printed out by others.

... and much more! - Whether you want to simply generate the formatted HTML to give some text on your website a traditional feel, or use this as your personal blog, the possibilities are endless, enjoy!

Upcoming Features:

  1. Fix small plaintext generation bug
  2. Redo unwieldy menus on the right, improve UI
  3. Make it mobile friendly
  4. Translate UI
  5. Be able to format individual characters
  6. Commenting
  7. Keyboard shortcuts
  8. Social media links?

Please feel free to send all questions, comments, and suggestions to me@fernjager.net

Modifying Transcend WiFi SD Card Firmware

As someone who has always been fascinated by small-scale embedded computing, I can hardly describe my excitement when I happened across this post on HackerNews: http://haxit.blogspot.com.es/2013/08/hacking-transcend-wifi-sd-cards.html

In short, the author, Pablo, was able to take advantage of vulnerabilities of the poorly coded CGI scripts of the Transcend WiFi SD card's web interface, to examine the filesystem, and ultimately upload his own binaries and modified files.

I, along with many others, were inspired: Wouldn't it be awesome to be able to customize our own Linux system on that device?

It could serve as...

  1. A small portable fileserver that can be powered by batteries and hidden in your wallet.
  2. A network application server run indefinitely off of batteries (and solar panel) without all the power-consuming doodads of a full blown Raspberry Pi.
  3. A discreet portable webserver/router with wiki/forum software to allow political dissidents to organize
  4. It could serve as a remote proxy connected to some free Starbucks Wifi and taped behind some toilet in the restroom... A spy device? etc.
  5. For me, it could serve as a cheap WiFi shield for an Arduino/AVR. The micro-controller could dump text files into the SD card. A script on the card would monitor, parse, and send the data to wherever it needs to go... and vice versa! When range isn't key, this solution is much cheaper than buying this: https://www.sparkfun.com/products/11287

As a 400 MHz Linux system with 32 MB of RAM, using only ~100 mA @ 3.3 V, the possibilities are endless!

Standing on the Shoulders of Giants

EDIT: Scroll down for scripts and program by another author who had came to the same result

As I don't have one of those cards on hand (~$40), I decided to download the firmware and see how far I can get with modifying it.

In the Firmware_V1.7 folder, we see the following:

$ ls -al
total 6524
drwxrwxr-x 2 robert robert    4096 May 15 14:48 .
drwxrwxr-x 7 robert robert    4096 May 22 11:43 ..
-rw-rw-r-- 1 robert robert 2664833 Apr 17 18:03 image3
-rw-rw-r-- 1 robert robert 2807347 May 15 10:33 initramfs3.gz
-rw-rw-r-- 1 robert robert 1048576 May 15 10:33 mtd_jffs2.bin
-rw-rw-r-- 1 robert robert  110660 Apr 17 18:03 program.bin

Cool, some familiar names here... let's see if we can open some of these files:

$ file *
image3:             data
initramfs3.gz:      data
mtd_jffs2.bin:      Linux jffs2 filesystem data little endian
program.bin:        data

Hmm... despite the intuitive filenames, it looks like some of the files may be encrypted or obfuscated in some way. However, the real fruit is in getting access to the contents of initramfs3.gz

After Googling around, I happened across a Japanese blog detailing the hacking of the firmware for various other brands of WiFi SD cards: http://blog.osakana.net/archives/category/minor/flucard

The content looked applicable, so I followed the instructions there. The new insight from the blog was that for whatever arbitrary reason, I had to take off the first 8 bytes of the initramfs3.gz file in order to get the real initramfs3.gz file

$ expr 2807347 - 8

$ cat initramfs3.gz | tail -c 2807339 > initramfs3-real.gz

$ file initramfs3-real.gz
initramfs3-real.gz: gzip compressed data, from Unix, last modified: Tue May 14 19:33:08 2013

Woah, magic! We have a real gzip file now, this should be familiar territory- let's unzip and get the cpio archive.

$ gzip -dc initramfs3-real.gz > initramfs.cpio
$ file initramfs.cpio
initramfs.cpio: ASCII cpio archive (SVR4 with no CRC)

Cool! Unfortunately, the post on the Japanese blog leaves it at that... Let's keep going further:

$ mkdir root; cd root
$ sudo cpio -i -d -H newc --no-absolute-filenames < ../initramfs.cpio
11783 blocks

... and voila!

$ ls
bin  dev  etc  home  init  lib  linuxrc  lost+found  mnt  proc  root  sbin  sys  tmp  ts_version.inc  usr  var  www

$ cd www; ls
back.gif    blank.html  dir.gif      frame1.html  index.html  multi_download_decode.jar  page       page.jpg  sd        uploadto.html
banner.jpg  cgi-bin     favicon.ico  frame2.html  mtd         nothumb.jpg                page.html  script    text.gif

$ cat ../etc/version.txt
Product Name     : KeyASIC WIFI-SD
Firmware Version : V150
Build Date       : 17 APR 2013
Revision         : V150
WiFi Model       : Atheros AR6003 11n
Linux Kernel     :
Busybox          : 1.18.5

Forging New Ground

Can I build my own binaries for this?

I was on my ARMv5 Chromebook running Ubuntu (using crouton) with your standard set of build tools... linking against uClibc would be trivial. The author of the original article was able to upload an ARMv5 busybox binary. I took a quick look at the existing busybox binary.

$ cd ../bin; file busybox
busybox: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, stripped

$ ./busybox
BusyBox v1.18.5 (2013-04-17 18:28:03 CST) multi-call binary.
Copyright (C) 1998-2009 Erik Andersen, Rob Landley, Denys Vlasenko
and others. Licensed under GPLv2.
See source distribution for full notice.

Looks almost certain, but for a resounding yes, I would have to test my own binaries on a real device.

Can I put it back together again?

$ sudo find . | cpio -H newc -o > ../initramfs-real
$ cd ..
$ gzip -9 initramfs-real

However, recall that to obtain a working gzip file, we had to cut out the first 8 bytes.

Did these first eight bytes specify a checksum, the size of the file, or was it simply padding to prevent prying eyes?

Getting the "original" gzip may not be as simple as pre-pending those 8 bytes again.

To find out, I got an older version of the firmware to compare...

On the version 1.6 firmware:

$ hexdump -n 8 -C initramfs3.gz
00000000 4b 41 47 5a 00 28 a1 98 |KAGZ.(..|

On the version 1.7 firmware:

$ hexdump -n 8 -C initramfs3.gz
00000000 4b 41 47 5a 00 2a d6 2b |KAGZ.*.+|

At this point, we see that out of the 8 byte header padding, the difference is in the last four bytes. Let's see if these last four bytes represent the size of the file.

I printed the 4 bytes as a 32 bit int for the version 1.7 firmware:

$ printf "%i\n" 0x002ad62b

$ ls -al initramfs3-real.gz
-rw-rw-r-- 1 robert robert 2807339 Aug 11 23:15 initramfs3-real.gz

Sweet! Now we know how to construct the header: "KAGZ" + 32bit size of gz


We come to a stop to our journey here... After a bit more Googling around, I happened upon a French blog, where the author, mars, came to the same conclusions with the PQI Aircard (WiFi microSD->SD Adapter Card) (A different product, but with similar hardware/software, and awesome in that you can put in your own microSD). http://lemoidului.wordpress.com/2013/03/18/linux-is-everywhere_pqi-aircard-partie-iv-flash-it/

Huge props to mars, as his/her solution is much more thorough, complete with two scripts to extract and build the initramfs. There is even a small C program to generate and append the header for you little-endian people. (The 4 bytes in the header representing the size of the gzip file is in big-endian format).

The author had the added benefit of having a serial console with which to test and debug his/her findings- the interesting discovery was that the size of the initramfs must remain below 3 MB. (If you have big files to add, do so in the JFFS2 program.bin)

All in all, it was an amazing experience of drawing together information form various sources- initial inspiration from Pablo's blog, insights from a Japanese blog, only to find that this has been fully covered in a French blog. International collaboration FTW!

Transcend WiFi Card Manual:


Firmware Links



I've bought one on Amazon and will update with new discoveries and custom builds!

The Rational Zhuyin Input Method


注音符號, Zhùyīn fúhào, ㄓㄨˋ ㄧㄣ ㄈㄨˊ ㄏㄠˋ, or bopomofo

Is a phonetic "alphabet" that assists in the pronunciation of Chinese characters. It is nearly identical in purpose to Pinyin in that it assists pronunciation by phonetically "spelling out" Chinese characters. The only difference is that it uses 37 unique symbols, rather than the 26 symbols of the English alphabet.

While haven fallen out of favor with the Mainland, it is still widely used as an input method in Taiwan and other places.

It is my opinion that it should be widely re-adopted. With 37 unique characters, it captures sounds that the 26 characters of the English alphabet and combinations thereof cannot. By doing so, it avoids an issue with Pinyin, where those learning Chinese with the English alphabet, fall victim to using pre-conditioned pronunciation of English letters- inevitably resulting in an accent.

The Problem

The layout of Zhuyin on the modern keyboard seemed have been added as an after-thought. As seen below, the alphabet is placed in sequential order, from top to bottom, left to right, with no regards to frequency of occurrence or any other considerations. There is no apparent rhyme or reason for this layout, and it certainly does not assist in typing speeds or adoption.

Zhuyin Keyboard

Granted, this situation is mitigated by the very order of the alphabet, where all the consonants are located at the beginning, with vowels at the end. When laid out in sequential order on the keyboard, it conveniently concentrates the consonants on the left, with the vowels on the right. However, there is no denying that speed bonuses can be garnered by having frequently appearing consonants and connective vowels placed under the default assumed position of fingers on a QWERTY keyboard: "ASDF JKL:"

The Solution

I hereby propose improving this input method by injecting a bit of common sense in terms of key placement.

Design Considerations

  1. Effort will be made minimize changes- to prevent burdening users from having to learn an entirely new keyboard format altogether.
  2. Number keys 1,2,3,4,5 are to be vacated of any characters to allow logical input of tonal numbers.
  3. Consideration will also be given to the use of extended pinyin characters to allow the input of Chinese characters by other dialects.


  1. The Collection - In this initial stage, the text from a large body of modern and classic Chinese literature will be retrieved and collected- with equal weight given to all Chinese-speaking regions and with a 70/30 split between modern vernacular and Literary Chinese.
  2. The Converter - Next, with all the text on hand, a simple script will be written to look up all the Chinese characters in the Unicode Unihan Database. As the database has Hanyu Pinyin data for all the characters, but none for Zhuyin, the Pinyin will be extracted and converted into Zhuyin.
  3. The Frequency Analysis - With all the characters now represented in Zhuyin, a script will simply bin and draw a histogram of all Zhuyin characters. This information will roughly reveal the frequency of occurrence of each Zhuyin character in the Chinese language.
  4. The Keyboard - Armed with the frequency information, a new keyboard layout will be devised such that those symbols that are used more often, are placed under the default finger placement on a keyboard. Obviously, there will be much leeway as to where certain characters are placed (say, if they had the same frequency of occurrence)... these will have to be left up to discretionary arbitration.
  5. The Frontend - Next, a web-based IME will be created as a demonstration. This will simply consist of a JS library. When activated, this IME will perform like any other Chinese IME. It will also include a soft keyboard for reference as to character placement, similar to the image above.
  6. The Backend - The Go-based service will handle WebSocket requests from The Frontend. In addition to returning the actual character represented by the keyed-in Zhuyin, it will also build character frequency profiles for better autocomplete, serve a light dictionary, and much more. Such data will be pulled from a pre-constructed sqlite database using the data garnered from the previous steps.

Everthing- All the components, material sources, notes, rationalizations, will be open source for examination, criticism, and academic review. I am open to all suggestions and input, as it is crucial that all things are considered when establishing a standard.

The project repository will be found here: https://github.com/fernjager/rational-ime

Pinyin -> Zhuyin Conversion

I hereby put forth the claim that following parsing rules which should accurately convert Standard Hanyu Pinyin into Zhuyin. ( Going the opposite way is quite straightforward, and well documented: http://www.eng.umd.edu/~nsw/chinese/pinyin.htm )

This is a greedy algorithm that converts the longest patterns first without the need for complicated regex rules-a simple find and replace in the following order will suffice. Comments and corrections welcome.

// Pass #1 Standalone vowel pairs
yang - ㄧㄤ
ying - ㄧㄥ
yao  - ㄧㄠ    
yan  - ㄧㄢ
yin  - ㄧㄣ
you  - ㄧㄡ
ya   - ㄧㄚ
ye   - ㄧㄝ

wang - ㄨㄤ   
weng - ㄨㄥ   
wai  - ㄨㄞ   
wei  - ㄨㄟ
wan  - ㄨㄢ   
wen  - ㄨㄣ   
wa   - ㄨㄚ   
wo   - ㄨㄛ

yuan - ㄩㄢ
yong - ㄩㄥ
yue  - ㄩㄝ   
yun  - ㄩㄣ

// Pass #2: Vowel pairs that may be be prefaced with a consonant
iang - ㄧㄤ
ian  - ㄧㄢ   
iao  - ㄧㄠ 
ing  - ㄧㄥ 
ia   - ㄧㄚ 
ie   - ㄧㄝ 
in   - ㄧㄣ
iu   - ㄧㄡ 

uan  - ㄩㄢ
ue   - ㄩㄝ 
un   - ㄩㄣ

uang - ㄨㄤ 
uai  - ㄨㄞ
uan  - ㄨㄢ
ong  - ㄨㄥ
ui   - ㄨㄟ 
un   - ㄨㄣ 
ua   - ㄨㄚ 
uo   - ㄨㄛ 

// Pass #3: Standalone/Initial consonants
zh   - ㄓ 
ch   - ㄔ
sh   - ㄕ 
ri   - ㄖ
er   - ㄦ

// Pass #4: Standalone vowels
ang  - ㄤ 
eng  - ㄥ 

ai   - ㄞ 
an   - ㄢ 
ao   - ㄠ 
ei   - ㄟ 
en   - ㄣ 
ou   - ㄡ 
ye   - ㄝ 

i    - ㄧ
u    - ㄨ
v    - ㄩ
a    - ㄚ
o    - ㄛ
e    - ㄜ

// Pass #5: Initial constants
b    - ㄅ
p    - ㄆ
m    - ㄇ
f    - ㄈ
d    - ㄉ
t    - ㄊ
n    - ㄋ
l    - ㄌ
g    - ㄍ
k    - ㄎ
h    - ㄏ
j    - ㄐ
q    - ㄑ
x    - ㄒ
z    - ㄗ
c    - ㄘ
s    - ㄙ
r    - ㄖ

Truecrypt-7.1a on the ARM Chromebook

Assumes a Ubuntu chroot setup on the ARM Chromebook via crouton


sudo apt-get install libwxgtk2.8-dev libwxgtk2.8-dbg libc6-dev gcc g++ gdb libtag1-dev uuid-dev pkg-config make libfuse-dev

Download the latest Truecrypt source: http://www.truecrypt.org/downloads2

Get the latest RSA headers

wget ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/*.h

For convenience, here's a copy of the RSA headers retrieved on May 11th, 2013.

RSA Headers - May 11th, 2013

RSA Headers - PGP Signature

Set up env vars

export PKCS11_INC=/path/to/rsaheaders

Then, run make in the source directory of truecrypt



Truecrypt 7.1a Binary (ARMv7)

Truecrypt 7.1a Binary - PGP Signature


This is not a build against static wxWidgets, so you will probably need at least libwxgtk2.8-dbg installed.

In the GUI, you may need to check "Do not use kernel cryptographic service" in Settings > Preferences. On the command line, you may need to specify -m=nokernelcrypto --filesystem=none if you encounter any issues mounting.

As with all such security software, please check the signatures to ensure you have a non-compromised copy. My public key can be found here: PGP Public Key

Home ← Older posts