<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mark Nelson &#187; Complaining</title>
	<atom:link href="http://marknelson.us/category/complaining/feed/" rel="self" type="application/rss+xml" />
	<link>http://marknelson.us</link>
	<description>Programming, mostly.</description>
	<lastBuildDate>Wed, 01 Feb 2012 16:36:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>VC++ 10 Hash Table Performance Problems</title>
		<link>http://marknelson.us/2011/11/28/vc-10-hash-table-performance-problems/</link>
		<comments>http://marknelson.us/2011/11/28/vc-10-hash-table-performance-problems/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 14:05:45 +0000</pubDate>
		<dc:creator>Mark Nelson</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Complaining]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://marknelson.us/?p=1347</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2011/11/28/vc-10-hash-table-performance-problems/' addthis:title='VC++ 10 Hash Table Performance Problems' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div>Microsoft's implementation of <code>unordered_map</code> in Visual Studio 10 has performance issues so severe it may be unusable in your projects.]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2011/11/28/vc-10-hash-table-performance-problems/' addthis:title='VC++ 10 Hash Table Performance Problems' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div><p>Microsoft has never been a slacker in the C++ department &#8211; they&#8217;ve always worked hard to provide a top-notch, compliant product. Visual Studio 10 supports their current incarnation, and for the most part it is up to their usual standards. It&#8217;s a great development environment, and I am a dedicated user, but I have to give Microsoft a demerit in one area: their C++11 hash containers have some serious performance problems &#8211; so much that the Debug versions of the containers may well be unusable in your application.<br />
<span id="more-1347"></span></p>
<h4>Background</h4>
<p>I first noticed the problem with <code>unordered_map</code> when I was working on the the code for my updated <a href="http://marknelson.us/2011/11/08/lzw-revisited/" class="newpage">LZW article</a>. I found that when running in the debugger, my program would hang after exiting the compression routine. A little debugging showed that the destructor for my hash table was taking a long time to run. And by a long time, I mean it was approaching an <i>hour</i>!.</p>
<p>This seemed pretty crazy. Destroying a hash table wouldn&#8217;t seem to be a complicated task. I decided to see if I could come up with a reasonable benchmark. I wrote a test program that does a simple word frequency count. As a starter data set, I used the first one million white space delimited words in the 2010 CIA factbook, as published by <a href="http://www.gutenberg.org/ebooks/35830.txt.utf8" class="newpage">Project Gutenberg</a>. This data set yields 74,208 unique tokens.</p>
<p>I wrote a simple test rig that I used to test the word count program using four different containers:</p>
<ul>
<li/><code>unordered_map</code> indexed by <code>std::string</code>
<li/><code>unordered_map</code> indexed by <code>std::string *</code>
<li/><code>map</code> indexed by <code>std::string</code>
<li/><code>map</code> indexed by <code>std::string *</code>
</ul>
<p>The reason for testing with <code>std::string *</code> was to reduce the cost of copying strings into the hash table as it was filled, and then to reduce the cost of destroying those strings when the table was destroyed.</p>
<p>I ran tests against <code>map</code> expecting to see a pretty big difference in performance. Because <code>map</code> is normally implemented using a balanced binary tree structure, it has O(log(N)) performance on insertions. A sparsely populated hash table can have O(1) performance. By using fairly large data sets, I expected to see a big difference between the two.</p>
<p>I tried to eliminate a few obvious sources for error in my test function &#8211; and I used a template function so that I could use the same code on all the different container types:</p>
<pre>
template&lt;class CONTAINER, class DATA&gt;
void test( const DATA &amp;data, const char *test_name )
{
  std::cout &lt;&lt; &quot;Testing container: &quot; &lt;&lt; test_name &lt;&lt; std::endl;

#ifdef _DEBUG
  const int passes = 2;
#else
  const int passes = 10;
#endif
  double fill_times = 0;
  double delete_times = 0;
  size_t entries;
  for ( int i = 0 ; i &lt; passes ; i++ ) {
    CONTAINER *container = new CONTAINER();
    std::cout &lt;&lt; &quot;Filling... &quot; &lt;&lt; std::flush;
    clock_t t0 = clock();
    for ( auto ii = data.begin() ; ii != data.end() ; ii++ )
      (*container)[*ii]++;
    double span = double(clock() - t0)/CLOCKS_PER_SEC;
    fill_times += span;
    entries = container-&gt;size();
    std::cout &lt;&lt; &quot; &quot; &lt;&lt; span &lt;&lt; &quot; Deleting... &quot; &lt;&lt; std::flush;
    t0 = clock();
    delete container;
    span = double(clock() - t0)/CLOCKS_PER_SEC;
    delete_times += span;
    std::cout &lt;&lt; span &lt;&lt; &quot; &quot; &lt;&lt; std::endl;
  }
  std::cout &lt;&lt; &quot;Entries: &quot; &lt;&lt; entries
            &lt;&lt; &quot;, Fill time: &quot; &lt;&lt; (fill_times/passes)
            &lt;&lt; &quot;, Delete time: &quot; &lt;&lt; (delete_times/passes)
            &lt;&lt; std::endl;
}
</pre>
<p>I didn&#8217;t go overboard when it came to instrumenting this problem, I just used the timing functions built into the C++ library. On my Windows and Linux test systems, the values of CLOCKS_PER_SEC are both high enough that I&#8217;m not worried about granularity issues.</p>
<h4>The First Results</h4>
<p>I ran my test program in Visual C++ Release mode, using all the standard settings for a console application. For purposes of comparison, I ran the same program using g++ 4.6.1 on the same computer, booted up under Linux. For the set of 1,000,000 tokens, the results are shown below:</p>
<table border="1" cellpadding="5">
<thead>
<tr>
<th>Task</th>
<th>VC++ 10 Release</th>
<th>g++ 4.6.1 -O3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Fill <code>unordered_map&lt;string&gt;</code></td>
<td>0.41s</td>
<td>.11s</td>
</tr>
<tr>
<td>Fill <code>unordered_map&lt;string const *&gt;</code></td>
<td>0.39s</td>
<td>0.14s</td>
</tr>
<tr>
<td>Destroy <code>unordered_map&lt;string&gt;</code></td>
<td>3.17s</td>
<td>0.01s</td>
</tr>
<tr>
<td>Destroy <code>unordered_map&lt;string const *&gt;</code></td>
<td>3.24s</td>
<td>0.004s</td>
</tr>
<tr>
<td>Fill <code>map&lt;string&gt;</code></td>
<td>0.83s</td>
<td>.53s</td>
</tr>
<tr>
<td>Fill <code>map&lt;string const *&gt;</code></td>
<td>0.88s</td>
<td>0.66s</td>
</tr>
<tr>
<td>Destroy <code>map&lt;string&gt;</code></td>
<td>.14s</td>
<td>0.01s</td>
</tr>
<tr>
<td>Destroy <code>map&lt;string const *&gt;</code></td>
<td>.07s</td>
<td>0.002s</td>
</tr>
</tbody>
</table>
<p>There are a few interesting points to take away from these tests:</p>
<ul>
<li/>Microsoft&#8217;s compiler is taking an exceptionally long time to destroy hashed containers &#8211; one order of magnitude greater than it took to create it, and two orders of magnitude greater than it takes g++ to do the same task.
<li/>It doesn&#8217;t look like constructing and destroying the strings is a big factor. Both compilers have roughly the same performance with both <code>std::string</code> and <code>std::string *</code>. Microsoft&#8217;s behavior is counterintuitive, as it takes longer to construct and destroy containers using the pointer.
<li/>The GNU compiler appears to be able to run through this exercise notably faster.
</ul>
<p>The time it takes to destroy the table is a concern &#8211; having a C++ program hang for over 3 seconds to destroy a modestly large data structure is a serious concern &#8211; particularly when the same task completes in a few milliseconds with g++.</p>
<h4>The Pathological Results</h4>
<p>These concerns are nothing compared to what I see when running in debug mode. Setting my Visual Studio project to Debug mode, then running the same test, yields the results shown here:</p>
<table border="1" cellpadding="5">
<thead>
<tr>
<th>Task</th>
<th>VC++ 10 Debug</th>
</tr>
</thead>
<tbody>
<tr>
<td>Fill <code>unordered_map&lt;string&gt;</code></td>
<td>17.41s</td>
</tr>
<tr>
<td>Fill <code>unordered_map&lt;string const *&gt;</code></td>
<td>17.08s</td>
</tr>
<tr>
<td>Destroy <code>unordered_map&lt;string&gt;</code></td>
<td>505.36s</td>
</tr>
<tr>
<td>Destroy <code>unordered_map&lt;string const *&gt;</code></td>
<td>505.99s</td>
</tr>
<tr>
<td>Fill <code>map&lt;string&gt;</code></td>
<td>13.29s</td>
</tr>
<tr>
<td>Fill <code>map&lt;string const *&gt;</code></td>
<td>13.15s</td>
</tr>
<tr>
<td>Destroy <code>map&lt;string&gt;</code></td>
<td>0.94s</td>
</tr>
<tr>
<td>Destroy <code>map&lt;string const *&gt;</code></td>
<td>0.18s</td>
</tr>
</tbody>
</table>
<p>Those numbers are hard to believe. Destroying a hash table takes one millisecond when using g++. In VC++ 10, it takes almost ten minutes!</p>
<p>Worse, we suddenly see that hashed containers are <i>slower</i> than the containers built on red-black trees. Again, this just doesn&#8217;t make sense.</p>
<p>The big problem with these numbers is that it means the debug mode of the compiler is effectively unusable for a lot of tasks. Regardless of how much testing it does, when it is this slow, it is just not useful.</p>
<h4>A Workaround</h4>
<p>I didn&#8217;t invest the time to try debugging Microsoft&#8217;s library, so I don&#8217;t really know where the time is being spent. I did try a few things to speed things up, and I found one technique that helps a lot. Before including any Microsoft header files, try entering this single line in your source:</p>
<pre>
#define ITERATOR_DEBUG_LEVEL 0
</pre>
<p>With this definition in place, the delete times return to ball park of the times seen when running in release mode. Of course, you give up some debugging. I believe that an explanation of what this macro does might be found <a href="http://blogs.msdn.com/b/vcblog/archive/2011/04/05/10150198.aspx" class="newpage">here</a>.</p>
<p>In the final analysis, I think Microsoft has some serious work to to do here. The performance of their hashed containers, and to some lesser extent, the pre-C++11 associative containers, needs some serious examination. If the library is going to run this much slower than the competition, I need a good explanation why.</p>
<h4>Source</h4>
<p><a href="/attachments/2011/msvc_hash/HashTest.cpp">HashTest.cpp</a></p>
]]></content:encoded>
			<wfw:commentRss>http://marknelson.us/2011/11/28/vc-10-hash-table-performance-problems/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Dell XPS</title>
		<link>http://marknelson.us/2011/07/21/dell-xps/</link>
		<comments>http://marknelson.us/2011/07/21/dell-xps/#comments</comments>
		<pubDate>Thu, 21 Jul 2011 16:14:47 +0000</pubDate>
		<dc:creator>Mark Nelson</dc:creator>
				<category><![CDATA[Complaining]]></category>

		<guid isPermaLink="false">http://marknelson.us/?p=566</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2011/07/21/dell-xps/' addthis:title='Dell XPS' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div>Getting a new computer can be interesting. My recent purchase of a Dell XPS notebook came with a few problems that I didn&#8217;t anticipate, including: The video hardware is not properly supported under Linux &#8211; my fault for not checking up on this. The backlit keyboard is an ergonomic catastrophe. When viewed under bright light, [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2011/07/21/dell-xps/' addthis:title='Dell XPS' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div><p>Getting a new computer can be interesting. My recent purchase of a Dell XPS notebook came with a few problems that I didn&#8217;t anticipate, including:</p>
<ul>
<li/>The video hardware is not properly supported under Linux &#8211; my fault for not checking up on this.
<li/>The backlit keyboard is an ergonomic catastrophe. When viewed under bright light, the translucent legends on light brown keycaps literally disappear. I got Dell to replace this with a non-backlit keyboard, problem solved.
<li/>The traditional numeric keypad control keys, including arrows, Page Up/Down, Delete, and Home, have all been reduced in size and moved to random new locations. Since the notebook I bought is the size of a small car there was really no good reason for this, and it will probably take six months for my fingers to get used to the new locations.
<li/>Under Windows, the Bluetooth driver has some sort of glitch that causes Word to crash &#8211; go figure that one out. This was resolved by disabling an addin that I wasn&#8217;t likely to ever use anyway.
<li/>Under Linux the Bluetooth driver makes my wireless mouse nearly unusable. However, turning off Bluetooth also turns off wireless networking. I feel like there is a solution to this out there somewhere, I just have to find it.
</ul>
<p>None of these problems are going to ruin my life, but they definitely contributed to a small feeling of buyer&#8217;s remorse which I am still trying to shake off.<br />
<span id="more-566"></span></p>
<table border="0"  width="100%">
<tr>
<td><center><img src="/attachments/2011/dell/keyboard.jpg" alt="Dell backlit keyboard legends washed out in direct lighting"/></center></td>
</tr>
<tr>
<td><center><strong>Phone capture of the backlit keyboard under direct overhead light &#8211; the key legends do a nice disappearing act</strong></center></td>
</tr>
</table>
<p>It&#8217;s not all glitches and pain though, there is some levity as well. Check out the message the BIOS produces on an attempt to start up on a non-bootable device:</p>
<table border="0" width="100%">
<tr >
<td><center><img src="/attachments/2011/dell/os_not_found.jpg" alt="Message from the XPS BIOS when boot fails"/></center></td>
</tr>
<tr>
<td><center><strong>The BIOS message seen on a boot failure</strong></center></td>
</tr>
</table>
<p>Yep, my Operation System was not found. </p>
]]></content:encoded>
			<wfw:commentRss>http://marknelson.us/2011/07/21/dell-xps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stranger In a Strange Land</title>
		<link>http://marknelson.us/2011/06/26/stranger-in-a-strange-land/</link>
		<comments>http://marknelson.us/2011/06/26/stranger-in-a-strange-land/#comments</comments>
		<pubDate>Sun, 26 Jun 2011 18:56:38 +0000</pubDate>
		<dc:creator>Mark Nelson</dc:creator>
				<category><![CDATA[Complaining]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://marknelson.us/?p=470</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2011/06/26/stranger-in-a-strange-land/' addthis:title='Stranger In a Strange Land' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div>For most of the thirty-some years that I&#8217;ve been paid to program, I&#8217;ve worked with Assembly language, C, or C++. There have been some diversions to Java, which is pretty painless for a C++ programmer, and always the odd short job or two in anything from Perl to Haskell. But for the last three months [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2011/06/26/stranger-in-a-strange-land/' addthis:title='Stranger In a Strange Land' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div><p>For most of the thirty-some years that I&#8217;ve been paid to program, I&#8217;ve worked with Assembly language, C, or C++. There have been some diversions to Java, which is pretty painless for a C++ programmer, and always the odd short job or two in anything from Perl to Haskell.</p>
<p>But for the last three months or so I&#8217;ve been working full time on a short-timeline project that is using PHP as a general-purpose scripting language. So I&#8217;ve been working in this unfamiliar language at a fairly frantic pace, and I have to say that PHP, like Perl, is a strange place for a C programmer.<br />
<span id="more-470"></span></p>
<h4>The Normal Problems</h4>
<p>Any tutorial in a scripting language like PHP or Perl always makes a big deal out of <a href="http://php.net/manual/en/language.types.type-juggling.php" class="newpage">Type Juggling</a>, meaning that the type of a variable is inferred from the context in which it is used. In a simple example, a string literal can behave like an integer without any fuss, and vice versa:</p>
<pre>
{appliance:~} php -r '
> $a = 25;
> printf( strlen($a) . " " );
> printf( 15 + $a );
> printf( "\n" );'
2 40
</pre>
<p>Maybe it&#8217;s just me, but this aspect of PHP doesn&#8217;t seem to cause too much trouble. It may be because C and C++ already do implicit data conversions in a lot of situations; PHP just turns the dial up a notch or two.</p>
<p>What does give me a lot of trouble (and this is not exactly news) is that PHP doesn&#8217;t require declaration of variables, being perfectly content to create them on first use.</p>
<p>There&#8217;s of course nothing wrong with this, but as a C programmer, I have not developed any defensive skills in this area. A PHP programmer is much less likely to enter the following code, because he or she will be a lot more careful about entering variable names:</p>
<pre>
{appliance:~} php -r '
>$first = "Mark";
>$last = "Nelson";
>$name = $fist . " " . $last;
>print( "$name\n" );'
 Nelson
</pre>
<p>The good news on variable declaration is that I can jack up PHP&#8217;s error reporting so that these mistakes are flagged at runtime. Increased error reporting will also catch another error that plagues C++ programmers:</p>
<pre>
{appliance:~}php -r '
>$version = "1.2.3";
>print( version . "\n" );'
version
</pre>
<p>Yes, string literals are just as good without quotes as they are with.</p>
<h4>This Week&#8217;s Puzzle</h4>
<p>After a few months I start feeling a bit of a false sense of confidence in my understanding of the language, and naturally, I got some serious comeuppance this week, demonstrated by the following code:</p>
<pre>
{cslinux1:~} php -r '
>class base {
>  private $secret="42";
>  public function print_secret() {
>    printf( "$this->secret\n" );
>  }
>};
>class derived extends base {};
>$foo = new derived();
>$foo->secret="43";
>printf( $foo->secret . " " );
>$foo->print_secret();'
43 42
</pre>
<p>As a C++ programmer, I fully expect the attempt to modify <code>$foo->secret</code> to generate a runtime error. <code>$secre</code>t is a private member, and as such I shouldn&#8217;t have access to it via the derived class. But the runtime happily makes the assignment.</p>
<p>When I actually print the value, I see that the base class and derived class print different values for $secret. What has happened here is that the assignment actually created a new data member in the derived class with the name <code>$secret</code>.</p>
<p>So what exactly is happening here? The reason for the difference in behavior is that PHP uses the private and protected modifiers to define not just <em>accessiblity</em>, but <em>visibility </em>as well. The <code>$secret</code> member in the base class is not only inaccessible outside of the base class, it is invisible as well.</p>
<p>That invisibility is the key to the behavior. When I try to assign a value to <code>$this->secret</code>, the runtime looks to see if the object of class <code>derived </code>already has a member called <code>$secret</code>. Since the member in the base class is invisible, the conclusion is that there is no member with that name, and as a result, a new variable is created on the fly: <code>derived::$secret</code>.</p>
<p>This can&#8217;t be fixed by simply amping up the error level, unfortunately, and it definitely is a problem for C++ or Java programmers. It doesn&#8217;t just cause me a lot of confusion, it just seems <I>wrong</i>. </p>
<p>Of course, there is plenty to like about developing in PHP, and it is definitely the right tool for this project. The speed bumps just make the process a lot more interesting. The concept of visibility set me back a few hours, but I&#8217;m ready to move on &#8211; until I hit the next bit conceptual roadblock.</p>
]]></content:encoded>
			<wfw:commentRss>http://marknelson.us/2011/06/26/stranger-in-a-strange-land/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gawker Considered Stupid &#8211; Criminally Stupid</title>
		<link>http://marknelson.us/2011/02/06/gawker-considered-stupid-criminally-stupid/</link>
		<comments>http://marknelson.us/2011/02/06/gawker-considered-stupid-criminally-stupid/#comments</comments>
		<pubDate>Sun, 06 Feb 2011 21:51:56 +0000</pubDate>
		<dc:creator>Mark Nelson</dc:creator>
				<category><![CDATA[Complaining]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Snarkiness]]></category>

		<guid isPermaLink="false">http://marknelson.us/?p=266</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2011/02/06/gawker-considered-stupid-criminally-stupid/' addthis:title='Gawker Considered Stupid &#8211; Criminally Stupid' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div>The storage of plaintext or encrypted passwords by any company that does business with the public is an act of stupidity. An act of stupidity so dangerous that it needs to be made illegal. Yes, we need federal law banning the storage of passwords on more or less all IT systems in the world. The recent break-in of the Gawker user database makes this point more clearly than anything I can say, but that won't stop me from trying.]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2011/02/06/gawker-considered-stupid-criminally-stupid/' addthis:title='Gawker Considered Stupid &#8211; Criminally Stupid' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div><table border="0" align="left" cellpadding="5">
<tr>
<td><img src="/attachments/2011/gawker/passwords.jpg"/></td>
<tr>
<tr>
<td><a href="http://www.flickr.com/photos/beleaveme/3988066230/" class="newpage">Photo</a> by Bob Brown</td>
</tr>
</table>
<p>One of the oldest rules in print journalism is to get the reader&#8217;s attention with the lead, and to make your whole point in the first paragraph. Here goes: The storage of plaintext or encrypted passwords by any company that does business with the public is an act of stupidity. An act of stupidity so dangerous that it needs to be made illegal. Yes, we need federal laws banning the storage of passwords on more or less all IT systems in the world. The recent break-in of the Gawker user database makes this point more clearly than anything I can say, but that won&#8217;t stop me from trying.<br />
<span id="more-266"></span></p>
<h4>Best Practices</h4>
<p>Long ago, in the pre-PC days, I was a neophyte learning my way around the UNIX system my employer used for software development. It didn&#8217;t take long before I bumped into one of the more interesting files on the system: <code>/etc/passwd</code>. To my young eyes, it appeared that this file contained the encrypted passwords for all the users in the company. All I had to do was get my hands on the system software that managed logins, and I could quickly print out a complete list of credentials. Awesome!</p>
<p>Soon enough I learned my lesson. One of those bearded UNIX gurus was kind enough to take me aside and point out the obvious: <code>/etc/passwd</code> doesn&#8217;t contain encrypted passwords. It contains hashed passwords. <a href="http://www.aspheute.com/english/20040105.asp" class="newpage">Hashed and salted</a>, in fact. Because of this, the original designers of UNIX were able to do what seemed like hubris to me: leave the password file with a mode value of 644 &#8211; available for anyone on the system to read.</p>
<p>Even though this was a best practice almost forty years ago, the Gawker debacle shows us that some people just don&#8217;t learn. Media empire Gakwer, host of dozens of popular web sites, had their internal database hacked. After much of the data was posted to public web sites, <a href="http://www.slate.com/id/2277768/" class="newpage">the truth came out</a>. Gawker had over 1.25 million passwords stored in their database. Encrypted passwords, which they felt were quite safe. Safe, that is, until they showed up on the Pirate Bay&#8217;s lists of torrents. </p>
<p>Gawker was stupid &#8211; that much is obvious. Anything that is encrypted can be decrypted. That&#8217;s the nature of the algorithm, and that is why the passwords were stored that way. And if a password can be decrypted, you are just one security breach away from a bad actor having a plaintext password for every user on your system. If your passwords are hashed and salted, the bad actor can still get that list &#8211; but it should take at least a few decades.</p>
<p>But this kind of stupidity has the power to do much more damage than letting a script kiddy post comments on Lifehacker using my name. In today&#8217;s web, the average citizen who creates an account on a Gawker property such as Lifehacker, Gizmodo, or Fleshbot uses a password that is identical to the one they use on Amazon, eBay, PayPal, and their bank. So it&#8217;s pretty obvious what a black hat can do with that list of email address/password combinations &#8211; the economic damage can be stupendous.</p>
<p>That&#8217;s why we need to make the storage of encrypted passwords illegal. </p>
<h4>Yes, Illegal</h4>
<p>If it was just a matter of education, we could attack this problem in a sensible way. But the truth is, <strong>when it comes to security</strong>, the average IT person is an idiot, and the average user is an idiot. Just for example, my hosting service, Dreamhost.com, stores user passwords in their database. I&#8217;ve argued with them to no end about how stupid this is. But they&#8217;re content &#8211; the passwords are encrypted, and hardly anyone has access to them. They&#8217;ll happily go on in this mode until a disgruntled employee mails out the list, or the inevitable security breach leads to a mini-Gawker episode. And this is a company hosting close to a million domains. Just imagine how many startups out there have your credentials stored with no more protection than an XORed string in a database, and nothing but some caffeine-fueled PHP code protecting you from a SQL injection hack.</p>
<p>No, I think it&#8217;s time to acknowledge that my credentials belong to me, and they need the legal protection that my other properties enjoy. We need to to develop a new <a href="http://www.itl.nist.gov/fipspubs/" class="newpage">FIPS</a> regulation regarding the storage of passwords, and then enact it as law &#8211; with hefty penalties.  A Gawker-size breach should result in an instant fine on the order of tens of millions of dollars. </p>
<h4>It&#8217;s Clear This is Needed</h4>
<p>Like millions of people, I received the Gawker email shortly after passwords were posted:</p>
<blockquote><p>
<b>Gawker Media</b> to markn<br />
12/13/10<br />
This weekend we discovered that Gawker Media&#8217;s servers were compromised, resulting in a security breach at Lifehacker, Gizmodo, Gawker, Jezebel, io9, Jalopnik, Kotaku, Deadspin, and Fleshbot. As a result, the user name and password associated with your comment account were released on the internet. If you&#8217;re a commenter on any of our sites, you probably have several questions.<br />
&#8230;
</p></blockquote>
<p>The site had a link to a <a href="http://lifehacker.com/5712785/faq-compromised-commenting-accounts-on-gawker-media" class="newpage">FAQ</a> which answered questions about the breach. The most important question thing to note about this FAQ is that months after the breakin, we still see a very bad entry:</p>
<blockquote><p>
<b>11) What are you doing to ensure this doesn&#8217;t happen in the future?</b><br />
We&#8217;re bringing in an independent security firm to improve security across our entire infrastructure. Additionally, we will continue to work with independent auditors to ensure we maintain a reliable level of security, as well as the processes necessary to ensure we maintain a safe environment for our commenters.
</p></blockquote>
<p>There is really only one good answer to this question: it should have read &#8220;<em>We will never store passwords on our systems again &#8211; either in clear text, or encrypted. As this episode demonstrates, storing passwords is a worst practice. We were stupid once, but we are going to show the world that we have the capacity to learn. From now on, our passwords will be hashed and salted using the strongest possible algorithms available on our back end</em>.&#8221;</p>
<h4>What You Can Do</h4>
<p>The obvious thing you need to do is to not use the same password on every site &#8211; this is a no-brainer. If you currently use <em>fluffy99</em> as your password on Amazon, PayPal, eBay, and Poker Stars, you are vulnerable. Just make a small change in your algorithm. Instead of using fluffly99, simply append the first letter of the site to the password: Amazon gets fluffy99a, PayPal gets fluffy99p, etc. Use some easy-to-remember variation on this theme and you are immediately protected against the first wave of automatic attacks following a breach.</p>
<p>The second thing is to start shaming the morons. From time to time, go through a password recovery exercise on your favorite sites. If they offer to send you an email with a copy of your password, or to show it to you after you answer some security questions, you are dealing with Gawker-league stupidity. Call it out, publicly, loudly, and make sure you file a support case on it.</p>
<p>And finally, if you work in an organization that holds sway over Internet policy, take this call for legal action seriously. If you&#8217;re part of the EFF, or CERT, or the FCC, start pushing for this legislation &#8211; it&#8217;s the right thing.</p>
<h4>Afterward</h4>
<p>Calling for federal legislation in a blog post is clearly troll bait. For starters, the Internet user base has a fairly large number of people who lust for a global adoption of <a href="http://en.wikipedia.org/wiki/Anarcho-capitalism" class="newpage">Anarcho-capitalism</a>. In their view, any new government institution is a step in in the wrong direction. They will weigh in on this idea with some vigor, arguing that the problem can easily be handled with existing tort law. Additionally, they will point out that smart people (like them) are already immune to this problem, because they carry USB keys with a list of randomly generated 32 character passwords for every web site they use.</p>
<p>There will also be a large number of people who claim structural obstacles with the exclusive use of hashed passwords &#8211; the example being my Dreamhost captors. </p>
<p>Countering all of the objections they will raise in this post runs the risk of turning it into a manifesto, and that&#8217;s not my goal &#8211; I don&#8217;t get paid by the word. I will address the arguments as they come in. The structural and procedural arguments will all be wrong, and easily addressed. The philosophical arguments are more difficult, because winners and losers in those arguments are generally selected based on personal opinion, only slightly tempered with the facts. (And much of political argument starts off with name-calling and deteriorates from there.) But it&#8217;s safe to say I don&#8217;t agree with the idea that there are no good laws.</p>
<p>Maybe Gawker will be the last million-user password breach. I hope so. But somehow I doubt it. It&#8217;s kind of fun to think of the same type of breach happening at, say, Mint.com or Intuit. Now that will be a call to action!</p>
<h4>Update</h4>
<p>Since writing this, I received some useful clarification from a source who has worked with Gawker. Like most people, I was basing my information on Gawker&#8217;s security practices from their own statement:</p>
<blockquote><p>
Passwords in our database are encrypted (i.e., not stored in plain text),
</p></blockquote>
<p>As it turns out, this statement false. According to a <a href="http://tech.gawker.com/5721670/gawker-password-management-qa" class="newpage">post from Gawker</a>, their user passwords were hashed using <a href="http://en.wikipedia.org/wiki/Crypt_(Unix)" class="newpage">crypt(3)</a>, the same algorithm used by the bearded UNIX gurus I talked to over 30 years ago.</p>
<p>This means that Gawker was using a hashed, salted password. Unfortunately, they were using an algorithm that was considered to weak for any reasonable security as long as 20 years ago. Dictionary-based cracking programs on modern computers can break crypt(3) passwords with astonishing speed. That is apparently what happened to Gawker.</p>
<p>This doesn&#8217;t change the gist of the problem much &#8211; Gawker was still horribly negligent with user passwords. For whatever reasons they chose to use a security scheme that simply doesn&#8217;t pass muster. This could clearly have been prevented with a FIPS standard based on modern technology.</p>
<h4>A Visit From Mr. Language Policeman</h4>
<p>As an aside, is it reasonable to claim that Gawker misspoke when they said their passwords were encyrypted? It&#8217;s perhaps a fine point, but the Wikipedia definition of <a href="http://en.wikipedia.org/wiki/Encryption" class="newpage">encryption</a> says:</p>
<blockquote><p>
In cryptography, encryption is the process of transforming information (referred to as plaintext) using an algorithm (called cipher) to make it unreadable to anyone except those possessing special knowledge, usually referred to as a key.
</p></blockquote>
<p>Clearly, the process of hashing passwords using crypt(3) does not meet this definition. You will sometimes hear people refer to this as <i>one way encryption</i>, but this usage doesn&#8217;t turn hashing into encryption.</p>
]]></content:encoded>
			<wfw:commentRss>http://marknelson.us/2011/02/06/gawker-considered-stupid-criminally-stupid/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Google Is a Scary Lifeline</title>
		<link>http://marknelson.us/2010/12/16/google-is-a-scary-lifeline/</link>
		<comments>http://marknelson.us/2010/12/16/google-is-a-scary-lifeline/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 19:49:51 +0000</pubDate>
		<dc:creator>Mark Nelson</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Complaining]]></category>

		<guid isPermaLink="false">http://marknelson.us/?p=146</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2010/12/16/google-is-a-scary-lifeline/' addthis:title='Google Is a Scary Lifeline' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div>When Google Voice stopped receiving my SMS messages, I was reminded how bad support can be for non-paying customers.]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2010/12/16/google-is-a-scary-lifeline/' addthis:title='Google Is a Scary Lifeline' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div><p>These days I&#8217;ve turned over a lot of my life to Google &#8211; they have my email, a lot of my documents, and my primary phone number.</p>
<p>This is all great while it works, because in general it&#8217;s free, and the uptime is very reliable.</p>
<p>But if you are non-paying customer, when things break, you can find yourself in a world of trouble.<br />
<span id="more-146"></span><br />
I use my Google Voice number as my primary phone number, and it rings my mobile, work, and home numbers. That&#8217;s a nice feature. In addition, I use it to receive texts, because I can send and receive them from both my Google Voice web page and my phone.</p>
<p>This morning I noticed that my texting traffic had strangely disappeared. A little checking showed that I could still send texts from my Google account, but it wasn&#8217;t receiving any. My cell phone could still send and receive properly, but nobody uses that number.</p>
<p>Generally my first debugging step on something like this is to search <a href="http://search.twitter.com/" class="newpage">Twitter</a> to see if this is a big problem. Maybe Google broke SMS for everyone, or some sizable portion of the population.</p>
<p>No such luck.</p>
<p>Now I found myself in free service hell. Something I depend on rather heavily stopped working, and I basically had no avenue for support. </p>
<p>As an unpaid Google Voice user, my only hope was to post a message on the appropriate forum. I wrote up a <a href="http://www.google.com/support/forum/p/voice/thread?tid=06407d9a9eedf4bc&#038;hl=en&#038;fid=06407d9a9eedf4bc0004978b45983217" class="newpage">problem report</a>, doing my best to provide as much detail as I could, but with not too much hope. If you browse through the forums you&#8217;ll see that the resolution rate for people&#8217;s problems is depressingly low.</p>
<p>As it happens, my story has a happy ending. Although I hadn&#8217;t done anything to my Google Voice settings, I remembered that this morning when I logged into gmail, Google asked if perhaps I would like to set up SMS password recovery for my account. Seemed like a good idea, so I gave them my Google voice number. I didn&#8217;t bother to try a test run &#8211; I have this feature set up on other accounts and it is drop dead simple.</p>
<p>But as it turns out, somewhere in the bowels of the Googleplex, adding that field to my account database broke some piece of code in Google Voice&#8217;s SMS reception code. When I changed the setting to point to my cell phone number, I instantly regained the ability to receive SMS messages on my Google Voice number. I have to believe this is a simple bug &#8211; I can&#8217;t think of any reason that using a Google Voice number for SMS password recovery should break it.</p>
<p>Of course, it appears that all the messages that were sent during my downtime were discarded, but I think I can recover from a few hours of SMS silence. If I hadn&#8217;t been fortunate enough to connect the dots and ferret out a fairly serious bug, there is no telling how long I would have waited to see a fix.</p>
<p>I might have even demanded a full refund.</p>
]]></content:encoded>
			<wfw:commentRss>http://marknelson.us/2010/12/16/google-is-a-scary-lifeline/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ripoff Artists</title>
		<link>http://marknelson.us/2010/11/14/ripoff-artists/</link>
		<comments>http://marknelson.us/2010/11/14/ripoff-artists/#comments</comments>
		<pubDate>Sun, 14 Nov 2010 20:07:20 +0000</pubDate>
		<dc:creator>Mark Nelson</dc:creator>
				<category><![CDATA[Complaining]]></category>
		<category><![CDATA[Scams]]></category>
		<category><![CDATA[Writing]]></category>

		<guid isPermaLink="false">http://marknelson.us/?p=139</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2010/11/14/ripoff-artists/' addthis:title='Ripoff Artists' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div>Nobody likes getting ripped off, and I&#8217;m no exception. I search the web from time to time to see who&#8217;s copying my stuff, and it&#8217;s always a little disheartening. This week I ran a check to see who was copying my 20-year old LZW Compression article. Mind you, I&#8217;m not talking about isolated quotes taken [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2010/11/14/ripoff-artists/' addthis:title='Ripoff Artists' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div><p>Nobody likes getting ripped off, and I&#8217;m no exception. I search the web from time to time to see who&#8217;s copying my stuff, and it&#8217;s always a little disheartening. </p>
<p>This week I ran a check to see who was copying my 20-year old <a href="http://marknelson.us/1989/10/01/lzw-data-compression/" class="newpage">LZW Compression article</a>. Mind you, I&#8217;m not talking about isolated quotes taken without attribution; for the most part I&#8217;m looking for people who have posted a wholesale copy of the article &#8211; a complete rip-off. Looking through the top 25 hits yields some interesting statistics:<br />
<span id="more-139"></span></p>
<ul>
<li>About 30% of the people who copy my work are University faculty. The assign the article as reading for a class, and instead of simply posting a link, they scrape the article off the web and post a private copy.</li>
<li>Another 40% are people who are blatantly plagiarizing &#8211; they&#8217;ve incorporated my work into a paper or thesis. Unfortunately for them Google now crawls PDF and PostScript files, which makes detection pretty easy</li>
<li>The remainder are blogging programmers who, for some reason, delight in taking my article and posting it on their site, reformatted and unattributed, but often with my name and contact information still intact</li>
</ul>
<h3>Taking Action</h3>
<p>Finding these rip-off artists is easy, but getting the stolen material removed from the web is another matter. In the cases where I can clearly identify a person who owns the site, I usually start with a friendly email. Maybe 25% of the time this works, but the typical response is dead silence.</p>
<p>When the informal methods fail, the next step is the formal takedown notice. In the United States, web publishers enjoy protection from claims of copyright infringement under the <a href="http://en.wikipedia.org/wiki/Online_Copyright_Infringement_Liability_Limitation_Act" class="newpage">Online Copyright Infringement Liability Limitation Act</a> if they register a copyright agent who handles complaints, and if they respond to those complaints in a timely fashion.</p>
<p>This means that a site like <a href="http://blogger.com" class="newpage">Blogger.com</a>, owned by Google, provides a formal mechanism for handling notices. When I can&#8217;t find a link to an abuse agent, I use the WHOIS database to find the hosting service, and send an email to their address. This generally works pretty well. For example, <a href="http://www.scribd.com" class="newpage">Scribd</a> responded to my requests within a matter of hours, and generally assumes that my complaints are legitimate unless the poster of the material puts up a decent defense.</p>
<p>Things aren&#8217;t always so simple though. Just as an example, <a href="http://citeseerx.ist.psu.edu/" class="newpage">CiteSeer</a>, a very popular database of academic publishing, has a cached copy of a stolen article that their crawler found. In their <a href="http://citeseerx.ist.psu.edu/help/faq" class="newpage">FAQ</a>, under the question &#8220;How can I remove a copy of my article from your database?&#8221;, they give this unhelpful tidbit:</p>
<blockquote><p>
Papers within CiteSeerX corpus are crawled from the web. The only reason a papers of yours is in the CiteSeerX database is because it was/is available from the web.
</p></blockquote>
<p>No kidding. And this helps me remove your illegal copy how?</p>
<h3>The Tough Cases</h3>
<p>With enough perserverance, I&#8217;m usually able to remove a large percentage of the illegal copies. But some problems remain intractable. Overseas servers in countries where English is not widely spoken are particularly difficult. I could certainly sue <a href="http://www.baidu.com/" class="newpage">Baidu.com</a> in Federal Court, but I have a feeling that wouldn&#8217;t get me very far. </p>
<p>Even when I don&#8217;t succeed, there is some entertainment value in the excuses. Today I got an email from a gentleman in India who incorporated my work in a paper published in a peer-reviewed article. He told me that he would work on taking it out, but right now he is busy taking care of his mother, who is in poor health. He hopes I will be patient.</p>
<p>Patient I will remain. Not like I have a choice.</p>
]]></content:encoded>
			<wfw:commentRss>http://marknelson.us/2010/11/14/ripoff-artists/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Innumeracy Part N</title>
		<link>http://marknelson.us/2008/07/20/innumeracy-part-n/</link>
		<comments>http://marknelson.us/2008/07/20/innumeracy-part-n/#comments</comments>
		<pubDate>Sun, 20 Jul 2008 19:56:27 +0000</pubDate>
		<dc:creator>Mark Nelson</dc:creator>
				<category><![CDATA[Complaining]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Snarkiness]]></category>

		<guid isPermaLink="false">http://marknelson.us/2008/07/20/innumeracy-part-n/</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2008/07/20/innumeracy-part-n/' addthis:title='Innumeracy Part N' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div>This isn&#8217;t the first time I&#8217;ve complained about innumeracy, and I&#8217;m sure it won&#8217;t be the last. Just to get off on the right foot, let me give the definition of the word from thesite innumeracy.com: A term meant to convey a person&#8217;s inability to make sense of the numbers that run their lives. Innumeracy [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2008/07/20/innumeracy-part-n/' addthis:title='Innumeracy Part N' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div><p>This isn&#8217;t the first time I&#8217;ve <a href="http://www.drdobbs.com/blog/archives/2008/05/innumeracy_cont.html" class="newpage">complained about innumeracy</a>, and I&#8217;m sure it won&#8217;t be the last. Just to get off on the right foot, let me give the definition of the word from thesite <a href="http://www.innumeracy.com/" class="newpage">innumeracy.com</a>:</p>
<blockquote><p>A term meant to convey a person&#8217;s inability to make sense of the numbers that run their lives. Innumeracy was coined by cognitive scientist Douglas R Hofstadter in one of his Metamagical Thema columns for Scientific American in the early nineteen eighties. Later that decade mathematician John Allen Paulos published the book Innumeracy. In it he includes the notion of chance as well to that of numbers.</p></blockquote>
<p>The example of innumeracy found in this post is somewhat more interesting than most, because it comes from a source that really should know better: <a href="http://discovermagazine.com/" class="newpage">Discover Magazine</a>.<br />
<span id="more-126"></span><br />
In the July 2008 of Discover Magazine, I was reading an article titled <a href="http://discovermagazine.com/2008/jul/16-ocean-acidification-a-global-case-of-osteoporosis" class="newpage">Ocean Acidification: A Global Case of Osteoporosis</a>, and saw this quote:</p>
<blockquote><p>One such event occurred 55 million years ago at the so-called Paleocene-Eocene Thermal Maximum (PETM), when 4.5 million tons of greenhouse gases were released into the atmosphere. </p></blockquote>
<p>Now, we&#8217;re supposedly talking about an event in which so much greenhouse gas was emitted that extraordinary climate change occurred. Is 4.5 million tons really a lot? Checking the Wikipedia <a href="http://en.wikipedia.org/wiki/Greenhouse_gas" class="newpage">article on greenhouse gas emissions</a> gave this interesting quote:</p>
<blockquote><p>According to a preliminary estimate by the Netherlands Environmental Assessment Agency, the largest national producer of CO2 emissions since 2006 has been China with an estimated annual production of about 6200 megatonnes. China is followed by the United States with about 5,800 megatonnes.</p></blockquote>
<p>So the US and China produce 12 <strike>million</strike> billion tons of CO2 in a year, while the PETM produced 4.5 million tons. And the PETM was a major event that we are blowing away every year, year after year? Something is not right here.</p>
<h4>Check the Source</h4>
<p>Fortunately, Discover references the source of their information right on the web page, and quick check of <a href="http://www.geosc.psu.edu/people/faculty/personalpages/tbralower/Bowenetal2006.pdf" class="newpage">the paper</a> shows what the actual number is supposed to be:</p>
<blockquote><p>Atmospheric temperatures inferred from surface ocean (references in Zachos et al. [2005]) and terrestrial (e.g., Wing et al. [2005]) proxies warmed by 5 &#8211; 9° C globally during the PETM. Warming was closely associated with the release of between ~1500 and 4500 Gt of carbon to the ocean and atmosphere, resulting in large but poorly quantified increases in atmospheric CO2 levels [Zachos et al., 2005].
</p></blockquote>
<p>Okay, so in my book, Gt means Gigatonne, and regardless of whether we are using English or Metric units, that&#8217;s going to be measured in billions, not millions of tons.</p>
<p>How did Discover take this number from the paper and mangle it by three orders of magnitude? We&#8217;ll never know. But avoid innumeracy, try to be aware of just how big the earth is, and realize that what seem like big numbers don&#8217;t always do it justice.</p>
]]></content:encoded>
			<wfw:commentRss>http://marknelson.us/2008/07/20/innumeracy-part-n/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Slate Rips Me Off</title>
		<link>http://marknelson.us/2008/06/02/slate-rips-me-off/</link>
		<comments>http://marknelson.us/2008/06/02/slate-rips-me-off/#comments</comments>
		<pubDate>Mon, 02 Jun 2008 19:51:35 +0000</pubDate>
		<dc:creator>Mark Nelson</dc:creator>
				<category><![CDATA[Complaining]]></category>

		<guid isPermaLink="false">http://marknelson.us/2008/06/02/slate-rips-me-off/</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2008/06/02/slate-rips-me-off/' addthis:title='Slate Rips Me Off' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div>Slate has a regular piece called Explainer, subtitled &#8220;Answers to your questions about the news.&#8221; A while back, they apparently lost their Explainer and asked for applications for a replacement. As part of the application, they requested that you submit a list of 10 sample questions to be explained. Now, I have no real general [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2008/06/02/slate-rips-me-off/' addthis:title='Slate Rips Me Off' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div><p><a href="http://slate.com" class="newpage">Slate</a> has a regular piece called <em>Explainer</em>, subtitled &#8220;Answers to your questions about the news.&#8221; </p>
<p>A while back, they apparently lost their Explainer and asked for applications for a replacement. As part of the application, they requested that you submit a list of 10 sample questions to be explained.</p>
<p>Now, I have no real general journalism experience &#8211; most of what I&#8217;ve done is technical writing of one form or another. So I&#8217;m not a particularly good candidate for this position. But I thought I&#8217;d give it a shot. Here is the list of 10 sample questions I submitted on March 17, all based on topical news items:<br />
<span id="more-124"></span></p>
<ul>
Do banks report transactions under $10,000 to the feds?<br />
Is Tibet an occupied country or a Autonomous Region of China?<br />
Why do cranes collapse?<br />
How do you get this free money from the Fed?<br />
What&#8217;s so bad about a weak dollar?<br />
Who are the superdelegates and what are their superpowers?<br />
Am I required to put my hand over my heart when the National Anthem is playing?<br />
Is Scientology a religion?<br />
What&#8217;s so bad about melting glaciers?<br />
Is pancreatic cancer deadly or not?
</ul>
<p>Well, I didn&#8217;t get the job, and of course, I didn&#8217;t get a response, but today I see this article in Slate Explainer: <a href="http://www.slate.com/id/2192501/" class="newpage">Why Do Cranes Fall Down?</a>. </p>
<p>I guess the reason I didn&#8217;t get the job was that I only had one article worth ripping off. If there had been five or six, I&#8217;d be explaining away at Slate as we speak!</p>
]]></content:encoded>
			<wfw:commentRss>http://marknelson.us/2008/06/02/slate-rips-me-off/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How Evil Is Apple?</title>
		<link>http://marknelson.us/2008/03/31/how-evil-is-apple/</link>
		<comments>http://marknelson.us/2008/03/31/how-evil-is-apple/#comments</comments>
		<pubDate>Mon, 31 Mar 2008 13:27:05 +0000</pubDate>
		<dc:creator>Mark Nelson</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Complaining]]></category>

		<guid isPermaLink="false">http://marknelson.us/2008/03/31/how-evil-is-apple/</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2008/03/31/how-evil-is-apple/' addthis:title='How Evil Is Apple?' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div>Apple is in the middle of a minor fuss right now over their use of software updates as a promotional device. It turns out that if you are a Windows user with a copy of iTunes, Apple’s update process does its best to get you to install a copy of their web browser, Safari, along [...]]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2008/03/31/how-evil-is-apple/' addthis:title='How Evil Is Apple?' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div><p>Apple is in the middle of a minor fuss right now over their use of software updates as a promotional device. It turns out that if you are a Windows user with a copy of iTunes,  Apple’s update process does its best to get you to install a copy of their web browser, Safari, along with whatever you need to keep your iPod humming along properly:</p>
<p><center><img src="http://marknelson.us/attachments/2008/is-apple-evil/apple.JPG" /></center></p>
<p>Of course, it’s not particularly unusual for companies like Google, Adobe, and Apple to try to sneak their software onto your system using somewhat deceptive practices. Last time I checked up on my Dad’s PC his browser had Google Toolbar, Yahoo Toolbar,  AOL Toolbar, and a Toolbar from his ISP. The actual browser window was a miserable little ribbon a few hundred pixels high. Dad had no idea how the toolbars got installed, but I have no doubt they were all stealthily piggybacked on one piece of software or another.</p>
<p>But Mozilla CEO John Lilly seems to think this use of the update feature to promote a web browser goes beyond aggressive marketing and into the depths of evil. His angry <a href="http://john.jubjubs.net/2008/03/21/apple-software-update/" class="newpage">blog post</a> basically says that using an update/patch service to load new software violates some sort of basic compact between users and providers:</p>
<blockquote><p>It’s wrong because it undermines the trust that we’re all trying to build with users. Because it means that an update isn’t just an update, but is maybe something more. Because it ultimately undermines the safety of users on the web by eroding that relationship. It’s a bad practice and should stop. </p></blockquote>
<p>John goes on to say that he doesn’t condemn the common practice of using installed software to push your other products – he seems to be saying that the update program is a special case.</p>
<p>Things get really interesting when you start reading the comments to his post. As is often the case with All Things Apple, the issue seems to have caused extreme polarization.  A selection of anti-Apple comments include:</p>
<blockquote><p>This is disgraceful. It fails the user in favor of serving Apple. It is, in fact, malware-level tactics. </p></blockquote>
<blockquote><p>This is just a sick way of tricking users to download their browser by making it seem as if an update if available for a piece of software already installed. I bet it even takes over as the default browser afterwards, which would look very bad on Apple.</p></blockquote>
<blockquote><p>Right on, John Lily. “Update” means “update,” not “Give me your other products.”</p></blockquote>
<p>But predictably, the Apple apologists insist that Cupertino can do no wrong:</p>
<blockquote><p>You Windows users are not only paranoid, but so anti-Apple that your comments are hysterical. This is the biggest NON-ISSUE yet – and anyone using a computer that can’t use that screen and make a good decision should go back to a typewriter. </p></blockquote>
<blockquote><p>The consumer has already trusted Apple (or any company) by downloading one of their pieces of software already. There is already a placement of trust in Apple (or other company). If they trust Apple enough to install one of their apps, then extending that to another one of their programs seems to make sense to me.</p></blockquote>
<blockquote><p>Some of the complaints here are over the top. Pushing Safari with a iTunes update is “Malware”? Please. Sure, it’s marketing, but it is utterly benign, other than using a little disk space that is trivial by modern standards. … Compared to all the <u>real</u> malware issues faced by Windows users, this is not worth notice. And, most of all, compared to the execrable practices of Microsoft and other PC software vendors, this is a tempest in a teapot.</p></blockquote>
<p>I think one thing we can agree on is that there are tens of millions of Windows users with iTunes installed, and the vast majority of them are going to be clueless about what Safari is and whether they should uncheck that radio box.Does this mean Apple is preying on the ignorant? Are they in fact somewhat evil? Or is this just the way the world works now?</p>
<p>Use the comment box to let me know what you think. Inquiring minds want to know.</p>
<p>(By the way, I should note that in the past I&#8217;ve <i>always</i> used Firefox on OS/X &#8211; Safari 2.0 was lame, unstable, your basic piece of crap. I&#8217;m writing this on Windows using Safari 3.1, which is surprisingly fast and seemingly bug free. Quite an improvement!)</p>
]]></content:encoded>
			<wfw:commentRss>http://marknelson.us/2008/03/31/how-evil-is-apple/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>I Trust American Express With My Money?</title>
		<link>http://marknelson.us/2007/12/11/amex-survey/</link>
		<comments>http://marknelson.us/2007/12/11/amex-survey/#comments</comments>
		<pubDate>Tue, 11 Dec 2007 22:18:45 +0000</pubDate>
		<dc:creator>Mark Nelson</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Complaining]]></category>
		<category><![CDATA[Snarkiness]]></category>

		<guid isPermaLink="false">http://marknelson.us/2007/12/11/amex-survey/</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2007/12/11/amex-survey/' addthis:title='I Trust American Express With My Money?' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div>If you're going to use the web to perform a survey of your customer base, this report on a similar project from American Express should serve as a cautionary tale.]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style" addthis:url='http://marknelson.us/2007/12/11/amex-survey/' addthis:title='I Trust American Express With My Money?' ><a class="addthis_button_twitter"></a><a class="addthis_button_favorites"></a><a class="addthis_button_print"></a><a class="addthis_button_facebook_like"></a><a class="addthis_button_google_plusone"></a><a class="addthis_button_compact"></a></div><p>American Express is so excited about having me as a customer that they were willing to pay me $5 to take part in a survey:</p>
<blockquote><p>
<b>American Express Needs YOUR Feedback!</b></p>
<p>Dear American Express Blue Cardmember:</p>
<p>American Express would like your feedback. We would like you to participate in a survey about your Blue card from American Express. Your participation will provide us with valuable feedback and help us tailor card benefits to better meet your needs.</p>
<p>As a token of our appreciation, you will receive $5 from American Express*. Please note that this survey will be running for a limited period of time. To increase your chances of receiving the honorarium, please complete the survey at your earliest convenience.</p>
<p>The web address for the survey is shown below. To begin the survey, simply double-click on the address to go directly to the questionnaire. However, if you are unable to double-click on the address, please copy and paste the text below into your browser&#8217;s address bar.
</p></blockquote>
<p>Well, I need five bucks, and a little bit of checking gave me moderate insurance that this was really from American Express, not a phisher. The survey was being outsourced to <a href="http://confirmit.com" class="newpage">Confirmit</a>, a real company, and they don&#8217;t seem to be on any malware site lists. Furthermore, as things went on, there was an enormous amount of content in the survey and seemingly no payoff for phishers, so it seems unlikely that this is a scam.</p>
<p>However, right off the bat there was some cause for concern. <i>Double-click on the address?</i> How many browsers do you use that need a double-click before they follow a link? If Confirmit is a real company, they clearly didn&#8217;t assign their top copywriter to this project.</p>
<p>The real fun started when I actually started the survey. The classic &#8220;make a good first impression&#8221; rule that your mother taught you is just as true for web pages as it is for anything else. And the first page of the American Express survey was the equivalent of showing up for your first date with a big gravy blotch on your tie:<br />
<span id="more-116"></span><br />
<center><img src="http://marknelson.us/attachments/2007/amex-survey/amex-01.png"></center></p>
<p>Yes, that&#8217;s right, the first thing I see is some inner workings they&#8217;ve inadvertently exposed. No doubt the URL I clicked was supposed to preload a survey question and zip me right past this. This question was undoubtedly in use to stage their testing of the survey, and was supposed to be removed in the published version. There&#8217;s a lesson in that.</p>
<h4>From Bad to Worse</h4>
<p>The rest of the survey only served to further tarnish my impressions of Amex&#8217;s IT outsourcing choice. After making it through a few innocuous questions, another page I wasn&#8217;t suppose to see popped up:<br />
<center><img src="http://marknelson.us/attachments/2007/amex-survey/amex-02.png"></center></p>
<p>Apparently I was going to be be seeing ths particular error quite a few times:</p>
<p><center><img src="http://marknelson.us/attachments/2007/amex-survey/amex-03.png"></center></p>
<p/>
<h4>Survey Hell</h4>
<p>Finally I seem to have made my way through the setup questions. The progress bar showed 50%, and I detected that I was entering the first ring of survey hell. This is where the survey designer starts trying to milk you for a ton of information by repeatedly varying some scenario, then asking you a bunch of detailed questions about it. (This is sheer idiocy on their part. Once they start trying to find the correct adjectives for how a particular ad makes me feel about the product/company, it&#8217;s over.)</p>
<p>In this case AmEx had a list of perhaps 15 benefits that their card offers. They started tossing them up in various combinations on the screen, and in each case asking me on a scale of 1-10 how that made me feel about the card. They then tried to quantify the results by asking me how much more I would put on my card each month given that benefit. (Again, totally moronic. No data retrieved this way could possibly have any value.)</p>
<p>This would all be great if their page actually worked. In this case, I&#8217;ve told them that I put a tidy $5,000 on the card each month, and they want to see how much I&#8217;m going to bump that up if someone comes to my house to give me a back rub. (No joke!) Just to see what would happen, I put down a lower number, and got this nifty error message:<br />
<center><img src="http://marknelson.us/attachments/2007/amex-survey/amex-04.png"></center></p>
<p>It turns out the only way I could get past this page was by putting in 1, yes $1. But that&#8217;s okay, because at this point there&#8217;s obviously no reason to cooperate with the tragically broken survey.</p>
<h4>Unending Hell</h4>
<p>AmEx then applied the coup de grâce by inserting a fiendish logic error in the survey. I started looping through various permutations of three possible card benefits, over and over, for each one picking a number from 1-10 and then assigning it a cash value. I realized that the progress bar at the top of the page was actually moving back to 50% after each answer! In other words, I was stuck in the survey forever. They had a bug that prevented them from exiting the loop.</p>
<p>Nicely done, Amex!</p>
<p>So I bailed. In theory I can come back in a day or two and finish. Perhaps they will have fixed things up by then. More likely they will have fired Confirmit. Will I get my $5? It doesn&#8217;t seem likely. AmEx put the fix in here as well, by breaking the payment page. As you can see here, I&#8217;ve entered data in all the fields, but the survey software refuses to accept it, somehow thinking I&#8217;ve left something blank. This is a big PR win for Amex, putting people through a 20 minute broken survey, then refusing to pay!</p>
<p><center><img src="http://marknelson.us/attachments/2007/amex-survey/amex-05.png"></center></p>
<p/>
<h4>Moral</h4>
<p>The moral of the story is obvious. If you&#8217;re going to send an email out to thousands of customers, all of whom are most likely uninformed civilians, it would be a good idea to thoroughly test your product first. The fact that Confirmit clearly didn&#8217;t do that is a nail in their coffin, considering this is their livelihood. The fact that AmEx hired this joke of a company doesn&#8217;t say much for them, either.</p>
<p><b>Priceless Web Design:</b></p>
<ul>
<li/>Designing a survey for your customer base? $10,000
<li/>Deploying the survey and passing out rewards? $25,000
<li/>Making yourself look like an incompetent pack of rubes for the whole Web to see? Priceless.
</ul>
]]></content:encoded>
			<wfw:commentRss>http://marknelson.us/2007/12/11/amex-survey/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

