### A C implementation of my simple GPS code

Reader Chris Kuethe wrote in with a version of my simple code for entering latitude and longitude to GPS devices written in C (my demonstration code was in Perl).

Seems Chris is a bit of a GPS fanatic and maintains a page on GPS hackery.

He ported my Perl code to C and is releasing the code freely. He gave me the choice of releasing under two clause BSD license or making it public domain. I think the most generous is public domain (especially since the Perl code was public domain).

Here's the code to compute a SOC:
`#include <sys/types.h>#include <stdio.>intmain(int argc, char **argv){ int i, j; unsigned long long lat, lon, c, p, soc_num; char soc, *alpha = "ABCDEFGHJKLMNPQRTUVWXY0123456789"; int primes[] = { 2, 3, 5, 7, 11, 13, 17, 23, 29, 31, 37 }; float f; if (argc != 3){  printf("Usage: %s <lat> <lon>\n", argv);  exit(1); } sscanf(argv, "%f", &f); lat = (int)((f + 90.0) * 10000.0); sscanf(argv, "%f", &f); lon = (int)((f +180.0) * 10000.0); p = lat * 3600000 + lon; soc_num = p * 128; c = 0; for(i = 0; i < (sizeof(primes)/sizeof(primes)); i++){  c += ((p % 32) * primes[i]);  p /= 32; } c %= 127; soc_num += c; for(i = 9; i >= 0; i--){  j = soc_num % 32;  soc[i] = alpha[j];  soc_num /= 32; } soc = '\0'; printf("%s\n", soc);}`

And to compute latitude and longitude from a SOC:
`#include <sys/types.h>#include <stdio.h>intmain(int argc, char **argv){ int i, j, c, k; unsigned long long x, y, p, soc_num; char soc, *alpha = "ABCDEFGHJKLMNPQRTUVWXY0123456789"; int primes[] = { 2, 3, 5, 7, 11, 13, 17, 23, 29, 31, 37 }; float lat, lon; if ((argc != 2 )|| (strlen(argv) != 10)){  printf("Usage: %s <10-digit-SOC>\n", argv);  exit(1); } soc_num = 0; for (i = 0; i < 10; i++){  c = (char)argv[i];  c = c & 0xff;  c = toupper(c);  switch(c){   case 'I': c = '1'; break;   case 'O': c = '0'; break;   case 'S': c = '5'; break;   case 'Z': c = '2'; break;   default: ;  }  for (j = 0; j < strlen(alpha); j++)   if (c == alpha[j]){    soc_num = (soc_num * 32 + j);   } } p = soc_num / 128; k = soc_num % 128; lon = ((p % 3600000) / 10000.0) -180.0; lat = ((p / 3600000) / 10000.0) - 90.0; c = 0; for (i = 0; i < (sizeof(primes)/sizeof(primes)); i++){  c += ((p % 32) * primes[i]);  p /= 32; } c %= 127; if (c != k)  printf("warning: checksum mismatch - %d %d\n", c, k); printf("%0.4f %0.4f\n", lat, lon);}`

Thanks Chris!

Update: Chris writes to say that B1NLADEN02 can be found in Antarctica: -76.7847/-106.0187 and JIMMYHOFFA is here: -23.3433/-61.6087. Anonymous said…
Hi John,

guess the C code needs a little bit of html escaping. At least the #include statements look a little odd.

### Making an old USB printer support Apple AirPrint using a Raspberry Pi

There are longer tutorials on how to connect a USB printer to a Raspberry Pi and make it accessible via AirPrint but here's the minimal one that's just a list of commands and simple instructions. 1. Install Raspbian on a SD card 2. Mount SD card on some machine and navigate to / . Add a file called ssh and set up wpa_supplicant.conf for WiFi access. Now you have headless and don't need a keyboard or monitor. 3. Boot. Login. sudo raspi-config . Change password. 4. Connect printer via USB cable 5. Then execute the following sequence of commands to set up CUPS and make it accessible on the network. sudo apt-get update sudo apt-get full-upgrade sudo apt-get install cups sudo usermod -a -G lpadmin pi sudo cupsctl --remote-any sudo systemctl restart cups 6. Visit http://raspberrypi:631/admin and add the local printer. Make sure "sharing" is enabled on the printer. 7. Then make sure AirPrint is set up sudo apt-get install avahi-daemon sudo reboot Printer should work