diff -urpN john-1.7.8/src/Makefile john-1.7.8-trip/src/Makefile
--- john-1.7.8/src/Makefile	2011-05-04 18:52:31 +0000
+++ john-1.7.8-trip/src/Makefile	2011-08-16 13:28:33 +0000
@@ -32,6 +32,7 @@ JOHN_OBJS = \
 	BF_fmt.o BF_std.o \
 	AFS_fmt.o \
 	LM_fmt.o \
+	trip_fmt.o \
 	dummy.o \
 	batch.o bench.o charset.o common.o compiler.o config.o cracker.o \
 	crc32.o external.o formats.o getopt.o idle.o inc.o john.o list.o \
diff -urpN john-1.7.8/src/john.c john-1.7.8-trip/src/john.c
--- john-1.7.8/src/john.c	2011-02-27 12:31:36 +0000
+++ john-1.7.8-trip/src/john.c	2011-08-16 13:28:13 +0000
@@ -42,6 +42,7 @@ extern struct fmt_main fmt_AFS, fmt_LM;
 #ifdef HAVE_CRYPT
 extern struct fmt_main fmt_crypt;
 #endif
+extern struct fmt_main fmt_trip;
 extern struct fmt_main fmt_dummy;
 
 extern int unshadow(int argc, char **argv);
@@ -74,6 +75,7 @@ static void john_register_all(void)
 #ifdef HAVE_CRYPT
 	john_register_one(&fmt_crypt);
 #endif
+	john_register_one(&fmt_trip);
 	john_register_one(&fmt_dummy);
 
 	if (!fmt_list) {
diff -urpN john-1.7.8/src/trip_fmt.c john-1.7.8-trip/src/trip_fmt.c
--- john-1.7.8/src/trip_fmt.c	1970-01-01 00:00:00 +0000
+++ john-1.7.8-trip/src/trip_fmt.c	2011-08-16 16:07:30 +0000
@@ -0,0 +1,303 @@
+/*
+ * This file is part of John the Ripper password cracker,
+ * Copyright (c) 2011 by Solar Designer
+ *
+ * (loosely based on portions of DES_fmt.c)
+ */
+
+#include <string.h>
+
+#include "arch.h"
+#include "DES_std.h"
+#include "common.h"
+#include "formats.h"
+
+#define FORMAT_LABEL			"trip"
+#define FORMAT_NAME			"Tripcode DES"
+
+#define BENCHMARK_COMMENT		""
+#define BENCHMARK_LENGTH		-1
+
+#define PLAINTEXT_LENGTH		8
+#define CIPHERTEXT_LENGTH		10
+
+static struct fmt_tests tests[] = {
+	{"Rk7VUsDT2U", "simpson"},
+	{"3GqYIJ3Obs", "tripcode"},
+	{NULL}
+};
+
+#define ALGORITHM_NAME			DES_STD_ALGORITHM_NAME
+
+#define BINARY_SIZE			ARCH_SIZE
+#define SALT_SIZE			0
+
+#define MIN_KEYS_PER_CRYPT		0x40
+#if DES_128K
+#define MAX_KEYS_PER_CRYPT		0x100
+#else
+#define MAX_KEYS_PER_CRYPT		0x80
+#endif
+
+static struct {
+	union {
+		double dummy;
+		DES_binary binary;
+	} aligned;
+	char key[PLAINTEXT_LENGTH];
+} buffer[MAX_KEYS_PER_CRYPT];
+
+static DES_binary binary_mask;
+static unsigned char salt_map[0x100];
+
+static void init(void)
+{
+	char fake_crypt[14];
+	ARCH_WORD *alt_binary;
+	int i;
+
+	DES_std_init();
+
+	memset(fake_crypt, '.', 13);
+	fake_crypt[13] = 0;
+	memcpy(binary_mask, DES_std_get_binary(fake_crypt),
+	    sizeof(binary_mask));
+
+	fake_crypt[2] = 'z';
+	alt_binary = DES_std_get_binary(fake_crypt);
+
+	for (i = 0; i < 16 / DES_SIZE; i++) {
+		binary_mask[i] ^= ~alt_binary[i];
+		binary_mask[i] &= DES_BINARY_MASK;
+	}
+
+	for (i = 0; i < 0x100; i++) {
+		char *from = ":;<=>?@[\\]^_`";
+		char *to = "ABCDEFGabcdef";
+		char *p;
+		if (atoi64[i] != 0x7F)
+			salt_map[i] = i;
+		else if ((p = strchr(from, i)))
+			salt_map[i] = to[p - from];
+		else
+			salt_map[i] = '.';
+	}
+}
+
+static int valid(char *ciphertext)
+{
+	char *pos;
+
+	for (pos = ciphertext; atoi64[ARCH_INDEX(*pos)] != 0x7F; pos++)
+		;
+	if (*pos || pos - ciphertext != CIPHERTEXT_LENGTH)
+		return 0;
+
+	if (atoi64[ARCH_INDEX(*(pos - 1))] & 3)
+		return 0;
+
+	return 1;
+}
+
+static void *get_binary(char *ciphertext)
+{
+	char fake_crypt[14];
+
+	fake_crypt[0] = '.';
+	fake_crypt[1] = '.';
+	fake_crypt[2] = '.';
+	memcpy(&fake_crypt[3], ciphertext, 11);
+
+	return DES_std_get_binary(fake_crypt);
+}
+
+static int binary_hash_0(void *binary)
+{
+	return DES_STD_HASH_0(*(ARCH_WORD *)binary);
+}
+
+static int binary_hash_1(void *binary)
+{
+	return DES_STD_HASH_1(*(ARCH_WORD *)binary);
+}
+
+static int binary_hash_2(void *binary)
+{
+	return DES_STD_HASH_2(*(ARCH_WORD *)binary);
+}
+
+#define binary_hash_3 NULL
+#define binary_hash_4 NULL
+
+static int get_hash_0(int index)
+{
+	return DES_STD_HASH_0(buffer[index].aligned.binary[0]);
+}
+
+static int get_hash_1(int index)
+{
+	ARCH_WORD binary;
+
+	binary = buffer[index].aligned.binary[0];
+	return DES_STD_HASH_1(binary);
+}
+
+static int get_hash_2(int index)
+{
+	ARCH_WORD binary;
+
+	binary = buffer[index].aligned.binary[0];
+	return DES_STD_HASH_2(binary);
+}
+
+#define get_hash_3 NULL
+#define get_hash_4 NULL
+
+static void crypt_all(int count)
+{
+	int index;
+
+	for (index = 0; index < count; index++) {
+		static ARCH_WORD prev_salt = -1;
+		ARCH_WORD salt, *out;
+		char fake_crypt[14];
+
+		if (!buffer[index].key[0]) {
+			fake_crypt[0] = '.';
+			fake_crypt[1] = '.';
+		} else
+		if (!buffer[index].key[1]) {
+			fake_crypt[0] = 'H';
+			fake_crypt[1] = '.';
+		} else
+		if (!buffer[index].key[2]) {
+			fake_crypt[0] =
+			    salt_map[ARCH_INDEX(buffer[index].key[1])];
+			fake_crypt[1] = 'H';
+		} else {
+			fake_crypt[0] =
+			    salt_map[ARCH_INDEX(buffer[index].key[1])];
+			fake_crypt[1] =
+			    salt_map[ARCH_INDEX(buffer[index].key[2])];
+		}
+		fake_crypt[13] = 0;
+		salt = DES_std_get_salt(fake_crypt);
+		if (salt != prev_salt)
+			DES_std_set_salt(prev_salt = salt);
+
+		DES_std_set_key(buffer[index].key);
+
+		DES_std_crypt(DES_KS_current,
+		    out = buffer[index].aligned.binary);
+
+		{
+			ARCH_WORD mask;
+#if ARCH_BITS < 64
+			mask = (out[0] ^ out[1]) & salt;
+			out[0] ^= mask;
+			out[1] ^= mask;
+			mask = (out[2] ^ out[3]) & salt;
+			out[2] ^= mask;
+			out[3] ^= mask;
+#else
+			mask = (out[0] ^ (out[0] >> 32)) & salt;
+			out[0] ^= mask ^ (mask << 32);
+			mask = (out[1] ^ (out[1] >> 32)) & salt;
+			out[1] ^= mask ^ (mask << 32);
+#endif
+		}
+		out[0] &= binary_mask[0];
+	}
+}
+
+static int cmp_all(void *binary, int count)
+{
+	int index;
+
+	for (index = 0; index < count; index++)
+	if (*(unsigned ARCH_WORD *)binary == buffer[index].aligned.binary[0])
+		return 1;
+
+	return 0;
+}
+
+static int cmp_one(void *binary, int index)
+{
+	return *(unsigned ARCH_WORD *)binary == buffer[index].aligned.binary[0];
+}
+
+static int cmp_exact(char *source, int index)
+{
+	ARCH_WORD *binary;
+	int word;
+
+	binary = get_binary(source);
+
+	for (word = 0; word < 16 / DES_SIZE; word++)
+	if ((unsigned ARCH_WORD)binary[word] !=
+	    (buffer[index].aligned.binary[word] & binary_mask[word]))
+		return 0;
+
+	return 1;
+}
+
+static void set_key(char *key, int index)
+{
+	memcpy(buffer[index].key, key, PLAINTEXT_LENGTH);
+}
+
+static char *get_key(int index)
+{
+	static char out[PLAINTEXT_LENGTH + 1];
+
+	memcpy(out, buffer[index].key, PLAINTEXT_LENGTH);
+	out[PLAINTEXT_LENGTH] = 0;
+
+	return out;
+}
+
+struct fmt_main fmt_trip = {
+	{
+		FORMAT_LABEL,
+		FORMAT_NAME,
+		ALGORITHM_NAME,
+		BENCHMARK_COMMENT,
+		BENCHMARK_LENGTH,
+		PLAINTEXT_LENGTH,
+		BINARY_SIZE,
+		SALT_SIZE,
+		MIN_KEYS_PER_CRYPT,
+		MAX_KEYS_PER_CRYPT,
+		FMT_CASE,
+		tests
+	}, {
+		init,
+		valid,
+		fmt_default_split,
+		get_binary,
+		fmt_default_salt,
+		{
+			binary_hash_0,
+			binary_hash_1,
+			binary_hash_2,
+			binary_hash_3,
+			binary_hash_4
+		},
+		fmt_default_salt_hash,
+		fmt_default_set_salt,
+		set_key,
+		get_key,
+		fmt_default_clear_keys,
+		crypt_all,
+		{
+			get_hash_0,
+			get_hash_1,
+			get_hash_2,
+			get_hash_3,
+			get_hash_4
+		},
+		cmp_all,
+		cmp_one,
+		cmp_exact
+	}
+};
