Lovers Not Toreadors Tempranillo 2011

There are many great Spanish wines and we get so few of them here in Australia. Most of the Spanish wines we do get here really should have been tipped down the drain in Spain (I am looking at you Aldi), but on occasion we get a Spanish wine that is both great value and very drinkable. The Lovers Not Toreadors 2011 Tempranillo is one such wine. Flavoursome and easy drinking it makes a great change from the common garden variety Australian shiraz. At under $16 dollars a bottle it is really worth buying – just ignore the stupid label.

LNT_2011

Cost $15.90
Value $25.00+

Base32 implementation of the Damm error detection algorithm in C

The Damm algorithm is a fantastic check digit algorithm that detects all single-digit errors and all adjacent transposition errors. It detects all occurrences of altering one single digit and all occurrences of transposing two adjacent digits, the two most frequent transcription errors. The Damm algorithm also has the benefit that prepending leading base encoding zeros does not affect the check digit so you can use it on fixed size strings. All in all it is a great algorithm for checking if there have been any user errors when entering a number.

The only problem with the Damm algorithm is that all the current implementations are base 10 (0-9) only. I wanted to be able to use it to check alpha-numerical strings (passwords) so I wrote a base32 implementation of the Damm algorithm in C/C++. With the commonly confused characters (0/o and 1/l/i) avoided in the base32 encoding you can make a rather nice password checker. Any desired encoding scheme with 32 characters (or less) can be used.

I use the damn32 program in a bash one-liner to generate 10 (9 + the damn check) character password strings. You can make longer or shorter strings by changing the head -c switch.

# openssl rand -base64 50 | tr -dc '23456789abcdefghjkmnpqrstuvwxyz' | head -c9 | xargs damn32

Here is the code for damn32.c. It can be compiled with gcc using:

# gcc damn32.c -o damn32

I will to port this to javascript and php when I get the chance, but if someone wants to do it now I am happy to link to your code or post it here.

Edit.Thanks Michael for pointing out that due to some stupidity on my behalf the code got called damn.c not damm.c – I have updated the post title, but I will leave the code as is as a reminder to be more careful next time :)


#include <stdio.h>

/*
    Base32 implementation of the Damm error detection algorithm in C

    Copyright (c) 2014, Daniel Tillett
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
    ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    BACKGROUND
    The Damm algorithm is a check digit algorithm that detects all single-digit errors 
    and all adjacent transposition errors.
 
    It detects all occurrences of altering one single digit and all occurrences of 
    transposing two adjacent digits, the two most frequent transcription errors.
 
    The Damm algorithm has the benefit that it makes do without the dedicatedly 
    constructed permutations and its position specific powers being inherent in the 
    Verhoeff scheme. Prepending leading base encoding zeros does not affect the check digit.
    https://en.wikipedia.org/wiki/Damm_algorithm
*/

/*
    A base32 (or less) encoding.
 
    With this example encoding the base 0 is '2' and contains 31 characters that avoids 
    using characters that could be confused with each other (i.e. 0/o or 1/i/l).
 
    The encoding can be any scheme with 32 or less characters. To change the encoding
    update encodeLen and base32 to the desired values. In this example on 31 characters 
    are used
*/
const int encodeLen = 31;
const char base32[encodeLen] = "23456789abcdefghjkmnpqrstuvwxyz";

/*
    Returns index position of the base32 digit if the digit exists in the base32 string
    or encodeLen if not.
*/
int base32Index(char p) {
	int i;

	for (i = 0; i < encodeLen; i++) {
		if (p == base32[i]) {
			break;
			}
		}

	return i;
	}

/*
    Damn algorithm base32 check digit calculator.
 
    Returns the base32 check digit defined by the base32 string or '-' if the base32
    number contains a character that is not defined in the base32 string.
    
    Input must be a null terminated C string.
*/
char damm32Encode(char *code) {
	int i, interim = 0;
	char *p;
	/*
	    WTA quasigroup matrix of order 32
	    http://stackoverflow.com/questions/23431621/extending-the-damm-algorithm-to-base-32
	    This was constructed according to Damm Lemma 5.2 by Michael 
	    (http://stackoverflow.com/users/3625116/michael)
	    I suspect this Michael is the Michael Damm, but I really don't know :)
	*/
	char damm32Matrix[32][32] = {
			{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 3, 1, 7, 5, 11, 9, 15, 13, 19, 17, 23, 21, 27, 25, 31, 29},
			{ 2, 0, 6, 4, 10, 8, 14, 12, 18, 16, 22, 20, 26, 24, 30, 28, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31},
			{ 4, 6, 0, 2, 12, 14, 8, 10, 20, 22, 16, 18, 28, 30, 24, 26, 7, 5, 3, 1, 15, 13, 11, 9, 23, 21, 19, 17, 31, 29, 27, 25},
			{ 6, 4, 2, 0, 14, 12, 10, 8, 22, 20, 18, 16, 30, 28, 26, 24, 5, 7, 1, 3, 13, 15, 9, 11, 21, 23, 17, 19, 29, 31, 25, 27},
			{ 8, 10, 12, 14, 0, 2, 4, 6, 24, 26, 28, 30, 16, 18, 20, 22, 11, 9, 15, 13, 3, 1, 7, 5, 27, 25, 31, 29, 19, 17, 23, 21},
			{10, 8, 14, 12, 2, 0, 6, 4, 26, 24, 30, 28, 18, 16, 22, 20, 9, 11, 13, 15, 1, 3, 5, 7, 25, 27, 29, 31, 17, 19, 21, 23},
			{12, 14, 8, 10, 4, 6, 0, 2, 28, 30, 24, 26, 20, 22, 16, 18, 15, 13, 11, 9, 7, 5, 3, 1, 31, 29, 27, 25, 23, 21, 19, 17},
			{14, 12, 10, 8, 6, 4, 2, 0, 30, 28, 26, 24, 22, 20, 18, 16, 13, 15, 9, 11, 5, 7, 1, 3, 29, 31, 25, 27, 21, 23, 17, 19},
			{16, 18, 20, 22, 24, 26, 28, 30, 0, 2, 4, 6, 8, 10, 12, 14, 19, 17, 23, 21, 27, 25, 31, 29, 3, 1, 7, 5, 11, 9, 15, 13},
			{18, 16, 22, 20, 26, 24, 30, 28, 2, 0, 6, 4, 10, 8, 14, 12, 17, 19, 21, 23, 25, 27, 29, 31, 1, 3, 5, 7, 9, 11, 13, 15},
			{20, 22, 16, 18, 28, 30, 24, 26, 4, 6, 0, 2, 12, 14, 8, 10, 23, 21, 19, 17, 31, 29, 27, 25, 7, 5, 3, 1, 15, 13, 11, 9},
			{22, 20, 18, 16, 30, 28, 26, 24, 6, 4, 2, 0, 14, 12, 10, 8, 21, 23, 17, 19, 29, 31, 25, 27, 5, 7, 1, 3, 13, 15, 9, 11},
			{24, 26, 28, 30, 16, 18, 20, 22, 8, 10, 12, 14, 0, 2, 4, 6, 27, 25, 31, 29, 19, 17, 23, 21, 11, 9, 15, 13, 3, 1, 7, 5},
			{26, 24, 30, 28, 18, 16, 22, 20, 10, 8, 14, 12, 2, 0, 6, 4, 25, 27, 29, 31, 17, 19, 21, 23, 9, 11, 13, 15, 1, 3, 5, 7},
			{28, 30, 24, 26, 20, 22, 16, 18, 12, 14, 8, 10, 4, 6, 0, 2, 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1},
			{30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 29, 31, 25, 27, 21, 23, 17, 19, 13, 15, 9, 11, 5, 7, 1, 3},
			{ 3, 1, 7, 5, 11, 9, 15, 13, 19, 17, 23, 21, 27, 25, 31, 29, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30},
			{ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 2, 0, 6, 4, 10, 8, 14, 12, 18, 16, 22, 20, 26, 24, 30, 28},
			{ 7, 5, 3, 1, 15, 13, 11, 9, 23, 21, 19, 17, 31, 29, 27, 25, 4, 6, 0, 2, 12, 14, 8, 10, 20, 22, 16, 18, 28, 30, 24, 26},
			{ 5, 7, 1, 3, 13, 15, 9, 11, 21, 23, 17, 19, 29, 31, 25, 27, 6, 4, 2, 0, 14, 12, 10, 8, 22, 20, 18, 16, 30, 28, 26, 24},
			{11, 9, 15, 13, 3, 1, 7, 5, 27, 25, 31, 29, 19, 17, 23, 21, 8, 10, 12, 14, 0, 2, 4, 6, 24, 26, 28, 30, 16, 18, 20, 22},
			{ 9, 11, 13, 15, 1, 3, 5, 7, 25, 27, 29, 31, 17, 19, 21, 23, 10, 8, 14, 12, 2, 0, 6, 4, 26, 24, 30, 28, 18, 16, 22, 20},
			{15, 13, 11, 9, 7, 5, 3, 1, 31, 29, 27, 25, 23, 21, 19, 17, 12, 14, 8, 10, 4, 6, 0, 2, 28, 30, 24, 26, 20, 22, 16, 18},
			{13, 15, 9, 11, 5, 7, 1, 3, 29, 31, 25, 27, 21, 23, 17, 19, 14, 12, 10, 8, 6, 4, 2, 0, 30, 28, 26, 24, 22, 20, 18, 16},
			{19, 17, 23, 21, 27, 25, 31, 29, 3, 1, 7, 5, 11, 9, 15, 13, 16, 18, 20, 22, 24, 26, 28, 30, 0, 2, 4, 6, 8, 10, 12, 14},
			{17, 19, 21, 23, 25, 27, 29, 31, 1, 3, 5, 7, 9, 11, 13, 15, 18, 16, 22, 20, 26, 24, 30, 28, 2, 0, 6, 4, 10, 8, 14, 12},
			{23, 21, 19, 17, 31, 29, 27, 25, 7, 5, 3, 1, 15, 13, 11, 9, 20, 22, 16, 18, 28, 30, 24, 26, 4, 6, 0, 2, 12, 14, 8, 10},
			{21, 23, 17, 19, 29, 31, 25, 27, 5, 7, 1, 3, 13, 15, 9, 11, 22, 20, 18, 16, 30, 28, 26, 24, 6, 4, 2, 0, 14, 12, 10, 8},
			{27, 25, 31, 29, 19, 17, 23, 21, 11, 9, 15, 13, 3, 1, 7, 5, 24, 26, 28, 30, 16, 18, 20, 22, 8, 10, 12, 14, 0, 2, 4, 6},
			{25, 27, 29, 31, 17, 19, 21, 23, 9, 11, 13, 15, 1, 3, 5, 7, 26, 24, 30, 28, 18, 16, 22, 20, 10, 8, 14, 12, 2, 0, 6, 4},
			{31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1, 28, 30, 24, 26, 20, 22, 16, 18, 12, 14, 8, 10, 4, 6, 0, 2},
			{29, 31, 25, 27, 21, 23, 17, 19, 13, 15, 9, 11, 5, 7, 1, 3, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0}
		};

	for (p = code; *p != '\0'; ++p) {
		i = base32Index(*p);

		if (i == encodeLen) {
			return '-';
			}

		interim = damm32Matrix[interim][i];
		}

	return base32[interim];
	}

/*
    Damm32 Check
 
    Returns 1 if the base32 number is error free and 0 if it contains an error
    or the last digit is not equal to the error check digit.
*/
int damm32Check(char *code) {
	return (damm32Encode(code) == base32[0]) ? 1 : 0;
	}

/*
    Prints to stdout the input base32 number, the base32 check digit, and the damm32 check result.
*/
int main(int argc, char **argv) {
	if (argc == 2 && argv[1]) {
		printf("Input: %s\nCheck Digit: %c\nChecked: %d\n", argv[1], damm32Encode(argv[1]), damm32Check(argv[1]));
		return 1;
		}

	else {
		printf("Usage: damm32 [base32 number]\n");
		return 0;
		}
	}

Taltarni Pyrenees Shiraz 2010

Wow what a wine. 2010 was a great year in the Victorian Pyrenees wine region and Taltarni have made an absolutely fabulous shiraz. I loved the 2009, but the 2010 is even better. The only downsides is it costs $30 a bottle and Taltarni are still using corks which means I have to waste 15 seconds rummaging around my kitchen for my corkscrew to open it. Buy as much as you can when you see it.

 

 

 

 

 

Cost: $30
Value: $60+

(104)Connection reset by peer: mod_fcgid: error reading data from FastCGI server

This error (104)Connection reset by peer: mod_fcgid: error reading data from FastCGI server started to appear in my apache error log whenever I tried to upload a file. Apache seemed to be working fine with static html pages, it was only when I tried to upload files that I had problems.

Searching for a solution suggested a whole series of possible causes all revolving around permission problems. Since I had not changed anything on the server for a few weeks, and everything looked fine permission wise, this did not look to be the cause. After checking everything I could think of I noticed that the disk quota allocated by Virtualmin was only 1 GB and that I had used nearly all of it. I upped the disk quota to 10 GB and the problem was fixed. I hope this helps someone.

setrlimit not raising a signal with SIGXCPU

I ran into a unusual linux bug of late using RLIMIT_CPU to kill zombie processes that ran for longer than 15 seconds. The basic code I was using was:

struct rlimit rl;
memset(&rl, 0, sizeof(rl));
/* Set a CPU limit of 15 second. */
rl.rlim_cur = 15;
setrlimit(RLIMIT_CPU, &rl);
/* CPU Time exceeded */
signal(SIGXCPU, catchSignal);

This worked fine when I original wrote it a few years ago, but I noticed of late that I was spawning a large number of zombie processes that were not being trapped by SIGXCPU. After tearing my hair out all day trying to work out why, I noticed that this was only occurring on my CentOS 6.5 development box (Linux version 2.6.32). It turns out that there was a bug in the implementation of setrlimit before 2.6.17 that led a RLIMIT_CPU limit of 0 to be wrongly treated as “no limit” (like RLIM_INFINITY). Since 2.6.17 this is now treated as a limit of 1 second. Since I was setting rlim_max to 0 via memset meant that I was now effectively setting rlim_max to less than rlim_cur.

The solution is really simple – just ensure that you set rlim_max (hard limit) as well as rlim_cur (soft limit).

struct rlimit rl;
/* Set a CPU soft limit of 15 second and hard limit of 20 seconds */
rl.rlim_cur = 15;
rl.rlim_max = 20;
setrlimit(RLIMIT_CPU, &rl);
/* CPU Time exceeded */
signal(SIGXCPU, catchSignal);

pear.php.net is using a unsupported protocol – This should never happen.

I ran into the error “pear.php.net is using a unsupported protocol – This should never happen.” when I tried to upgrade my pecl packages. I have to say errors like “this should never happen” shouldn’t happen, but since it obviously did what is the cause and more importantly the solution. Apparently this error is caused because PHP 5.2.9 and 5.2.10 were broken and it corrupted the .record folder. The solution to fix this is to upgrade pear first then pecl.

pear upgrade
pecl upgrade

So simple :)

Mount Langi Ghiran Cliff Edge Shiraz 2010

It has been a while since I have had a chance to post about a good value wine, but finally I have one. The 2010 Mount Langi Ghiran Cliff Edge Shiraz is certainly a nice secondary wine from a great winery. It has the typical cool climate peppery shiraz flavours without being washed out. This wine is a really elegant food wine and at $22 a bottle a total bargain. A wine that is well worth the price!

cliff_edge

Price $22
Value $40+

Update. I was able to get a couple of cases for under $20 a bottle from Winestar – even better value.

How to set cookies using PHP and get them via JavaScript

I had an application where I wanted to set a cookie value using the php setcookie function and then later pull out the value using JS. The problem is the php setcookie function url encodes the cookie values with ‘+’ symbols for any whitespace. When you later pull out the cookie value using the JS decodeURIComponent function the ‘+’ symbols remain, converting a string to like ‘abc cdf’ to ‘abc+cdf’. If you want to the cookie values to have ” ” rather than “+” then you need to str_replace all the “+” with “%20” after calling the php urlencode function and then save the encode string using setrawcookie. The basic call to do something this is:

setrawcookie("cookie", str_replace('+','%20',urlencode($string)), time() + 3600*24*7, "/path","www.yourwebsite.com");

Hopefully this will save someone some time. If you want to do the reverse it is very simple – just calling the php urldecode function on the server $_COOKIE variable.

$string = urldecode($_COOKIE['string']);

Of course all the usual warnings about not trusting user supplied data remain. Just because your script created the data does not mean you can trust what is actually there.

Letters to avoid in creating passwords for non-english keyboard layouts

I had an interesting issue arise where I sent a computer to a customer located in Germany. I had created a password for them, but they had problems logging in with it. It turns out that the password I had created contained the letters Z and Y. These two keys are swapped on German keyboards so when they plugged in their own German keyboard they ended up entering the wrong password as the computer was still set to the English keyboard layout.

I have looked into the most common keyboard layouts used in Europe (QWERTY, QWERTZ & AZERTY) and you can avoid key swapping problems like mine if you avoid using the letters Z, Y, A, Q, M & L in any password or user name.

Update. Here is a simple one liner to generate a random alpha numerical password of 8 characters that avoids these letters. You can of course change the password length by changing the -c switch on the head call. This should work on any *nix based system (including MacOS X) that has openssl installed. One warning is the password will visible at generation time to other local users on shared systems if the other users are watching for process list changes. This doesn’t matter to me too much as I generate the passwords on my Mac laptop, but it is something to keep in mind if you are on an shared system.

 openssl rand -base64 25 | tr -dc 'BCDEFGHIJKNOPRSTUVWXbcdefghijknoprstuvwx0123456789' | head -c8; echo ""