Sunday, June 9, 2013
Best book review - Elements of Electromagnetics
Two stars because the book functions nicely as a club and projectile.
Friday, November 9, 2012
Who's a good programmer?
A smart accountant once told me that the answer to "How much money did you make?" is always, "Who wants to know?" If it's an investor, the answer is "A lot." If it's a customer, the answer is "A little." If it's the IRS, the answer is "None."
Same thing here. The answer to "Who is a good programmer?" is always, "Who wants to know?"Read the rest of the post. Interesting discussion as always
Tuesday, October 2, 2012
Cross-compile nginx 1.3.6
Wednesday, September 26, 2012
On exceptions
Cleaner, more elegant, and harder to recognize
The argument put forward is that yes, using exceptions does make for cleaner code, but
- It's easier to write bad code that uses exceptions
- It's harder to recognize good code from bad code when using exceptions
Monday, September 10, 2012
Disks lie
The behavior of hard drives is like decaying atoms. You can't make accurate predictions about what any one of them will do. Only in aggregate can you say something like "the half life of this pile of hardware is 12 years" or "if we write this data N times we can reasonably expect to read it it again."
Monday, August 13, 2012
The Art of Computer Programming, Volume 5
Syntactic Algorithms, in preparation.
9. Lexical scanning (includes also string search and data compression)
10. Parsing techniques
Estimated to be ready in 2020.What a schedule.
Wednesday, July 25, 2012
Modifying gzip to only do huffman coding
Recently I needed to compress certain types of files on a system with very limited memory. After looking at LZ77, LZ78, and derivatives I chose simple huffman coding as it gave me ~50% savings on the file, with limited resources.
The first possible candidate was http://entropyware.info/shcodec/index.html
In the end, I modified gzip to output only huffman compressed data. I modified puff.c (included with zlib) to only care about these types of blocks.
Patch to zlib
--- ../gzip-1.4-orig/deflate.c 2010-01-03 12:26:02.000000000 -0500 +++ deflate.c 2012-07-25 11:47:30.000000000 -0400 @@ -673,8 +673,11 @@ off_t deflate() int flush; /* set if current block must be flushed */ int match_available = 0; /* set if previous match exists */ register unsigned match_length = MIN_MATCH-1; /* length of best match */ + extern int huffonly; /* gzip.c */ + if (huffonly == 0) { if (compr_level <= 3) return deflate_fast(); /* optimized for speed */ + } /* Process the input block. */ while (lookahead != 0) { @@ -690,7 +693,8 @@ off_t deflate() if (hash_head != NIL && prev_length < max_lazy_match && strstart - hash_head <= MAX_DIST && - strstart <= window_size - MIN_LOOKAHEAD) { + strstart <= window_size - MIN_LOOKAHEAD && + huffonly==0) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). @@ -710,7 +714,8 @@ off_t deflate() /* If there was a match at the previous step and the current * match is not better, output the previous match: */ - if (prev_length >= MIN_MATCH && match_length <= prev_length) { + if (prev_length >= MIN_MATCH && match_length <= prev_length + && huffonly==0) { check_match(strstart-1, prev_match, prev_length); --- ../gzip-1.4-orig/gzip.c 2010-01-03 12:26:02.000000000 -0500 +++ gzip.c 2012-07-25 11:53:29.000000000 -0400 @@ -194,6 +194,7 @@ char *env; /* contents of GZI char **args = NULL; /* argv pointer if GZIP env variable defined */ char const *z_suffix; /* default suffix (can be set with --suffix) */ size_t z_len; /* strlen(z_suffix) */ +int huffonly = 0; /* only use huffman codes, no LZ77 */ /* The set of signals that are caught. */ static sigset_t caught_signals; @@ -271,6 +272,7 @@ struct option longopts[] = {"best", 0, 0, '9'}, /* compress better */ {"lzw", 0, 0, 'Z'}, /* make output compatible with old compress */ {"bits", 1, 0, 'b'}, /* max number of bits per code (implies -Z) */ + {"huffonly", 0, 0, 'O'}, /* ascii text mode */ { 0, 0, 0, 0 } }; @@ -352,6 +354,7 @@ local void help() " -Z, --lzw produce output compatible with old compress", " -b, --bits=BITS max number of bits per code (implies -Z)", #endif + " -O, --huffonly only compress using dynamic huffman codes (block type 2)", "", "With no FILE, or when FILE is -, read standard input.", "", @@ -502,6 +505,9 @@ int main (int argc, char **argv) try_help (); break; #endif + case 'O': + huffonly = 1; + break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': level = optc - '0';
Changes to puff.c
--- puff.orig.c 2010-04-25 05:04:16.000000000 -0400 +++ puff.new.c 2012-07-25 13:33:16.000000000 -0400 @@ -160,6 +160,7 @@ local int bits(struct state *s, int need * - A stored block can have zero length. This is sometimes used to byte-align * subsets of the compressed data for random access or partial recovery. */ +#ifndef CONFIG_ONLY_BLOCK_2 local int stored(struct state *s) { unsigned len; /* length of stored block */ @@ -194,6 +195,7 @@ local int stored(struct state *s) /* done with a valid stored block */ return 0; } +#endif /* * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of @@ -437,6 +439,7 @@ local int codes(struct state *s, const struct huffman *distcode) { int symbol; /* decoded symbol */ +#ifndef CONFIG_ONLY_BLOCK_2 int len; /* length for copy */ unsigned dist; /* distance for copy */ static const short lens[29] = { /* Size base for length codes 257..285 */ @@ -453,6 +456,7 @@ local int codes(struct state *s, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; +#endif /* decode literals and length/distance pairs */ do { @@ -469,6 +473,10 @@ local int codes(struct state *s, s->outcnt++; } else if (symbol > 256) { /* length */ +#ifdef CONFIG_ONLY_BLOCK_2 + /* I never put out anything but literals */ + return -11; +#else /* CONFIG_ONLY_BLOCK_2 */ /* get and compute length */ symbol -= 257; if (symbol >= 29) @@ -501,6 +509,7 @@ local int codes(struct state *s, } else s->outcnt += len; +#endif /* CONFIG_ONLY_BLOCK_2 */ } } while (symbol != 256); /* end of block symbol */ @@ -532,6 +541,7 @@ local int codes(struct state *s, * length, this can be implemented as an incomplete code. Then the invalid * codes are detected while decoding. */ +#ifndef CONFIG_ONLY_BLOCK_2 local int fixed(struct state *s) { static int virgin = 1; @@ -573,6 +583,7 @@ local int fixed(struct state *s) /* decode data until end-of-block code */ return codes(s, &lencode, &distcode); } +#endif /* * Process a dynamic codes block. @@ -668,7 +679,9 @@ local int dynamic(struct state *s) int err; /* construct() return value */ short lengths[MAXCODES]; /* descriptor code lengths */ short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */ +#ifndef CONFIG_ONLY_BLOCK_2 short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */ +#endif struct huffman lencode, distcode; /* length and distance codes */ static const short order[19] = /* permutation of code length codes */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; @@ -676,8 +689,10 @@ local int dynamic(struct state *s) /* construct lencode and distcode */ lencode.count = lencnt; lencode.symbol = lensym; +#ifndef CONFIG_ONLY_BLOCK_2 distcode.count = distcnt; distcode.symbol = distsym; +#endif /* get number of lengths in each table, check lengths */ nlen = bits(s, 5) + 257; @@ -735,9 +750,11 @@ local int dynamic(struct state *s) return -7; /* incomplete code ok only for single length 1 code */ /* build huffman table for distance codes */ +#ifndef CONFIG_ONLY_BLOCK_2 err = construct(&distcode, lengths + nlen, ndist); if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1])) return -8; /* incomplete code ok only for single length 1 code */ +#endif /* decode data until end-of-block code */ return codes(s, &lencode, &distcode); @@ -816,6 +833,7 @@ int puff(unsigned char *dest, do { last = bits(&s, 1); /* one if last block */ type = bits(&s, 2); /* block type 0..3 */ +#ifndef CONFIG_ONLY_BLOCK_2 err = type == 0 ? stored(&s) : (type == 1 ? @@ -823,6 +841,10 @@ int puff(unsigned char *dest, (type == 2 ? dynamic(&s) : -1)); /* type == 3, invalid */ +#else + /* only support block type 2 */ + err = type == 2 ? dynamic(&s) : -1; +#endif if (err != 0) break; /* return with error */ } while (!last);
Wednesday, July 18, 2012
A second look at probability theory
Here are my notes when reading about σ-algebras (sigma-algebra).
Thursday, July 5, 2012
Tuesday, July 3, 2012
Notes on pluggable optical I/O modules
Why have pluggable I/O interfaces
- Users can pick transceiver & cable for specific application
- Copper vs optical
- Active vs passive cable
SFP
- SFP (small form-factor pluggable)
- Conforms to the SFP multi-source agreement
- Up to 4 Gb/s
SFP+
- Enhancement of SFP
- Up to 10 Gbit/s
XFP
- XFP (10 gigabit small form factor pluggable)
- Conforms to the XFP multi-source agreement (also see INF-8077)
- Up to 10 Gb/s
- Electrical interface is XFI
XFP vs SFP+
- 10GbE can use both XFP & SFP+
- TBD
Overview of different standards
(Originally from The IEEE Std 802.3ba-2010 40Gb/s and 100Gb/s Architecture)
(Originally from The IEEE Std 802.3ba-2010 40Gb/s and 100Gb/s Architecture)
QSFP
- QSFP (quad small form-factor pluggable)
- For 40 Gb/s Ethernet etc.
- 4 channels in one interface
- Each channel up to 10 Gb/s, total 40 Gb/s
- NO CDR for re-timing
- Electrical interface XLPPI?
CFP
- CFP (C form factor pluggable) [C = latin centum = 100]
- Conforms to the CFP multi-source agreement
- For 40 Gb/s and 100 Gb/s Ethernet
- For long-haul Ethernet?
- Electrical interface XLAUI?
- CDR for re-timing
CXP
- CXP
- Active optical cable
- TBD
Monday, July 2, 2012
Can I use this embedded processor?
When selecting processors for medium-sized embedded systems, I ask:
Is it a well-known architecture? For our applications, we stick with ARM, MIPS. We evaluated Intel, but they didn't meet our I/O requirements.
Linux support? I check Wikipedia and the Linux repository.
GCC support? I check the GCC repository.
ICE/JTAG support? I check Mentor Graphics and Macraigor.
Thursday, March 29, 2012
RFC 6090: Fundamental Elliptic Curve Cryptography Algorithms
This note describes the fundamental algorithms of Elliptic Curve Cryptography (ECC) as they were defined in some seminal references from 1994 and earlier. These descriptions may be useful for implementing the fundamental algorithms without using any of the specialized methods that were developed in following years. Only elliptic curves defined over fields of characteristic greater than three are in scope; these curves are those used in Suite B.
Why I don't like using Java
| Slimy Java installer bundling ad-ware |
My reasons for not liking Java (on the desktop, especially applets):
- Can't install it without Administrator privileges
- The installer is huge
- Java applets feel sluggish, and most of them don't look nice
- Java applets breaks my normal web viewing experience: odd widgets, captures mouse, can't go back etc.
- Need to update it every few months because of security concerns
- They bundle ad-ware, or what I assume is ad-ware because it's checked by default (to trick me into installing), and isn't something I would every install myself
Tuesday, March 27, 2012
Shell programming: pipefail
So now all of my Bash scripts will begin with "set -e; set -o pipefail;"
Friday, March 23, 2012
Two current divider rules
Wikipedia has the following current divider rule
$$I_X = \frac{R_T}{R_X + R_T} \times I_T$$
where as certain websites have the following rule:
$$I_X = \frac{R_{total}}{R_X} \times I_T$$
where
$$\frac{1}{R_{total}} = \frac{1}{R_X} + \frac{1}{R_T}$$
for two resistors, this simplifies to
$$R_{total} = \frac{R_X \times R_T}{R_X + R_T}$$
These two rules are equal:
\begin{align}
I_X &= I_T \times \frac{R_{total}}{R_X} \\
&= I_T \times R_{total} \times \frac{1}{R_X} \\
&= I_T \times \frac{R_X \times R_T}{R_X + R_T} \times \frac{1}{R_X} \\
&= I_T \times \frac{R_T}{R_X + R_T}
\end{align}
Thursday, March 22, 2012
ViewVC error parsing rlog output
An Exception Has Occurred
Python Traceback
Traceback (most recent call last):
File "/usr/share/viewvc/lib/viewvc.py", line 4537, in main
request.run_viewvc()
File "/usr/share/viewvc/lib/viewvc.py", line 394, in run_viewvc
self.view_func(self)
File "/usr/share/viewvc/lib/viewvc.py", line 2049, in view_directory
file_data, options)
File "/usr/share/viewvc/lib/vclib/ccvs/bincvs.py", line 261, in dirlogs
alltags = _get_logs(self, path_parts, entries_to_fetch, rev, subdirs)
File "/usr/share/viewvc/lib/vclib/ccvs/bincvs.py", line 1030, in _get_logs
raise vclib.Error('Error parsing rlog output. Expected RCS file %s'
Error: Error parsing rlog output. Expected RCS file /cvs/project/some/path/somefile.sh,v, found
After tracking this down, turns out that if the last line of your commit is:
=============================================================================
then you will get two back-to-back lines of all "=" in the rlog output, and ViewVC parsing will fail.
So, until this is fixed in ViewVC, you can edit the *,v files, and change the first character of the line from a "=" to something else.
Tuesday, March 13, 2012
"Is copyright infringement theft?" is the wrong question
This particular trained lawyer wishes that we could never talk about whether cop... | Hacker News: There are laws against stealing physical property. Copyright infringement doesn't violate them. There are laws against copyright infringement. Copyright infringement does violate them. The question of whether "stealing" is good shorthand for "copyright infringement" is a total waste of time. The real point is whether the copyright infringement laws are good laws. ... So when we talk stealing and infringement, we're talking about violations of someone else's alienable rights. When you take away all of my alienable rights over my bike, that's called stealing. When you take them temporarily, it's "wrongful appropriation." When you take my right to exclude people from my property, that's called trespass. When you take my right to decide who rents my bike, it's theft of services. When you take my right to decide where this comment gets published, it's copyright infringement.Fantastic
Friday, March 9, 2012
A Princess of Mars
A Princess of Mars - Wikipedia, the free encyclopedia: Dejah Thoris: A red Martian princess of Helium, she is courageous, resolute, and frequently in mortal danger or under threat of dishonor by the lustful designs of a succession of villains.Best description of a Disney princess I've read.
Wednesday, February 29, 2012
How to run with JRE 1.4.2 on Linux
I needed to test an old applet against Java 1.4.2, so I went on the question of running Firefox on Linux with JRE 1.4.2.
First of all, Oracle requires registering:
The first page led me to this download page which required that I register, so I did, and was finally able to download the file j2re-1_4_2_19-linux-i586.bin
I put the file on a Fedora 32-bit virtual machine and extracted it by running
chmod +x j2re-1_4_2_19-linux-i586.bin ./j2re-1_4_2_19-linux-i586.bin
After clicking through the license agreement, the directory j2re1.4.2_19 was created.
I used this page to determine the plugin directory on Linux:
$HOME/.mozilla/plugins program_directory/plugins /usr/lib/mozilla/plugins /usr/lib/xulrunner/plugins
So I started by
cd ~/.mozilla/plugins ln -s /home/javasux/j2re1.4.2_19/plugin/i386/ns4/libjavaplugin.so .
But when I ran Firefox, and browsed to about:plugins, it gave me the following error:
LoadPlugin: failed to initialize shared library /home/javasux/j2re1.4.2_19/plugin/i386/ns4/libjavaplugin.so [/home/javasux/j2re1.4.2_19/plugin/i386/ns4/libjavaplugin.so: cannot restore segment prot after reloc: Permission denied] LoadPlugin: failed to initialize shared library /home/javasux/j2re1.4.2_19/plugin/i386/ns4/libjavaplugin.so [/home/javasux/j2re1.4.2_19/plugin/i386/ns4/libjavaplugin.so: cannot restore segment prot after reloc: Permission denied] [WARN 10071] polkit-session.c:144:polkit_session_set_uid(): session != NULL Not built with -rdynamic so unable to print a backtrace
I could not figure out what the problem was. There are other posts linking to this problem, but none of them have a solution that worked for me. What did work for me was following the directions in this post and running:
/usr/sbin/setenforce 0
Now when Firefox ran, it showed me two Java plugins! The system Java plugin, and the 1.4.2 plugin I had installed. Going to this and this website confirmed that I was running Java 1.6, when I wanted 1.4.2.
So, I temporarily disabled the Java version on my system by running the following commands:
sudo mv /usr/lib/mozilla/plugins/libjavaplugin.so /usr/lib/mozilla/plugins/libjavaplugin.so.bak sudo mv /etc/alternatives/libjavaplugin.so /etc/alternatives/libjavaplugin.so.bak
Now when I run Firefox, about:plugins shows me the 1.4.2 plugin loaded, but the test websites tell me that I don't have Java installed!
The java.com website says that I need Java 6 Update 10 and above for Firefox 3.6 and later versions. Well, I'm running Firefox 3.5b4, but maybe they're on to something, so upon searching, I find the Mozilla download for Firefox 3.0.19.
wget ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real-real/linux-i686/en-US/firefox-3.0.19.tar.bz2 tar xfj firefox-3.0.19.tar.bz2 cd firefox ./firefox
It's still not working! So I'm giving up and finding a machine that already has an old Firefox installed with an old Java version.
Friday, February 17, 2012
Password Check - NYTimes.com
Password Check - NYTimes.com: That’s right, a deputized LOLcat is about to haz a warrant for your arrest.Oh nytimes you


