<?xml version="1.0" encoding="utf-8"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
    <channel>
        <title>Mark Pearce's technical blog</title>
        <link>http://sleeksoft.co.uk/</link>
        <description>Mark Pearce - technical blog</description>
        <copyright>Copyright Mark Pearce 2004-2011</copyright>
        <generator>Fog Creek CityDesk 2.0</generator>
        <lastBuildDate>Fri, 03 Feb 2012 01:22:30 +0000</lastBuildDate>
        <managingEditor>admin@sleeksoft.co.uk</managingEditor>
        <webMaster>admin@sleeksoft.co.uk</webMaster>
        <language>en-uk</language>
        
<item>
    <title>Demonstrating the password utilities library</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[<p><em><strong>Edit</strong>: I've cleaned-up the source a little and upgraded it to a</em> <a href="../../Misc/PasswordUtilities_VS2010.zip"><em>Visual Studio 2010 solution using .NET Framework 4.0</em></a>.</p>
<p>This is the eighth (and hopefully final) installment in a series about creating a C# password utilities library.</p>
<p><img style="MARGIN-LEFT: 5px" border="0" alt="" align="right" src="../../images/psn-no.jpg" width="270" height="100" />But first, we interrupt our scheduled programming to bring you the latest offender in end-user personal data storage. Sony's Playstation Network and Qriocity services have recently suffered a <a href="http://blog.us.playstation.com/2011/04/26/update-on-playstation-network-and-qriocity/">major intrusion that exposed personal data for its 77 million users</a>. It's not completely clear from their FAQs, but it appears that the user passwords weren't hashed or encrypted, but instead stored in plain text. This makes the <a href="http://blogs.technet.com/b/markrussinovich/archive/2005/10/31/sony-rootkits-and-digital-rights-management-gone-too-far.aspx">Sony rootkit fiasco</a> positively tame in comparison.</p>
<p>Back on topic: all that remains is to write a console program that demonstrates some of the functionality implemented in the password utilities library. The Main method is hopefully self-explanatory.&nbsp;</p>
<p><img border="0" alt="" src="../../images/ConsoleMain.jpeg" width="788" height="750" /></p>
<p>We start by setting the console so that it can display UTF-8 symbols, a necessity given that this library can generate Unicode passwords. Note that you need to set the console to use a font that can display Unicode characters - I use Lucida Console.</p>
<p><img border="0" alt="" src="../../images/ConsoleUnicode.jpeg" width="546" height="181" /></p>
<p>Check the die for modulo bias.</p>
<p><img border="0" alt="" src="../../images/DieTest.jpeg" width="788" height="324" /></p>
<p><img border="0" alt="" src="../../images/DieTestResult.jpeg" width="291" height="148" /></p>
<p>Generate some random passwords and hash them, then display the combined password/hash information entropy.</p>
<p><img border="0" alt="" src="../../images/TestEntropy.jpeg" width="800" height="220" /></p>
<p><img border="0" alt="" src="../../images/PasswordHashResult.jpeg" width="669" height="412" /></p>
<p>Generate some passwords, hash them, then verify the password hashes.</p>
<p><img border="0" alt="" src="../../images/VerifyHashes.jpeg" width="800" height="224" /></p>
<p><img border="0" alt="" src="../../images/PasswordVerifyResult.jpeg" width="669" height="412" /></p>
<p>You can download a <a href="../../Misc/PasswordUtilities_VS2005.zip">Visual Studio 2005 solution</a> containing the password utilities library and the console test program. I chose VS2005 as the lowest common denominator - you should upgrade as appropriate to your environment. <strong>Edit</strong>: I've cleaned-up the source a little and upgraded it to a <a href="../../Misc/PasswordUtilities_VS2010.zip">Visual Studio 2010 solution using .NET Framework 4.0</a>.</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20110503_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20110503_1.html</guid>
    <pubDate>Tue, 03 May 2011 23:55:04 +0000</pubDate>
</item>

<item>
    <title>Measuring password strength</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[<p>This is the seventh installment in a series about creating a C# password utilities library.</p>
<p>The final step is to measure the <a href="http://simple.wikipedia.org/wiki/Information_entropy">information entropy</a> of specific passwords and their hashes. In this context, entropy is a measure of unpredictability. For randomly-generated passwords, the information entropy (measured in bits) is a reasonable proxy for password strength.</p>
<p><img style="MARGIN-LEFT: 5px" border="0" alt="" align="right" src="../../images/DayInTheLife.png" width="488" height="341" />For example, a password with 42 bits of entropy is as strong as a string of 42 bits chosen randomly. An attacker would need 2<sup>42</sup> attempts to exhaust every possibility of finding this password by brute force. Adding an extra bit of entropy doubles the number of guesses required, making the attacker's task twice as difficult.</p>
<p>The standard formula for calculating the information entropy of a random password is <strong>L * ( logarithm N / logarithm 2)</strong>, where <strong>L</strong> is the number of symbols in the password and <strong>N</strong> is the number of possible symbols. The result is expressed in bits. The entropy of a password hash is calculated using a similar formula, <strong>logarithm N / logarithm 2</strong>, where <strong>N</strong> is the number of hash iterations.&nbsp;</p>
<p>The <em><a href="../../Misc/EntropyChecker.cs.txt" target="_blank">EntropyChecker.cs</a></em> class can measure the entropy of:</p>
<ul>
<li>A machine-generated password where the password policy is known.
</li>
<li>
A machine-generated password where the policy is not known.
</li>
<li>
A password generated by a human.
</li>
<li>
A password hash, based on the number of hash iterations.
</li>
</ul>
<p>The following code measures the entropy of a machine-generated random password where the password policy is known. In this case, the password itself isn't required. The password policy knows the allowed password symbols, and that list combined with the password length is enough to calculate the password strength.</p>
<p><img border="0" alt="" src="../../images/PolicyKnown.jpeg" width="778" height="369" /></p>
<p>The following code measures the entropy of a machine-generated random password where the password policy is not known. In this case, the password is analysed to discover which symbols it contains. Based on that, the list of allowed symbols is estimated, and then the entropy can be measured as before. One caveat is that if the code detects a non-ASCII symbol in the password, it has no way of knowing what range of non-ASCII symbols was used to construct the password. So it assigns an arbitrary number of non-ASCII symbols, in this case 100.</p>
<p><img border="0" alt="" src="../../images/PolicyUnknown.jpeg" width="749" height="396" /></p>
<p>The following code measures the entropy of a human-generated password. A password generated by a human is always weaker than a random password. Users rarely make full use of the larger symbol sets when creating passwords. For example, hacking results obtained from a MySpace phishing scheme in 2006 revealed 34,000 passwords. Only 8.3% used non-alphanumeric symbols. The most common passwords (in descending order) were <em>password1, abc123, myspace1, password, blink182, qwerty1, fuckyou,</em> and <em>123abc</em>. The <a href="http://accessdata.com/products/forensic-investigation/decryption/">Password Recovery Toolkit</a> would have been able to crack 23% of those 34,000 MySpace passwords in 30 minutes, and 55% in 8 hours.</p>
<p>To deal with this, the code uses a <a href="http://www.nist.gov/index.html">NIST</a> formula contained in a <a href="http://en.wikipedia.org/wiki/Password_strength">Wikipedia article on password strength</a>. The result is that human passwords always show as much weaker than machine-generated random passwords.</p>
<p><img border="0" alt="" src="../../images/HumanPassword.jpeg" width="749" height="352" /></p><p>The following code measures the entropy of a password hash, based on the number of hash iterations. As an example, the default hash policy uses 2<sup>14</sup> hash iterations, which increases the password's entropy by 14 bits. According to Moore's Law, each extra bit of entropy provided by the hash means an extra 18 months to crack the password in the same time as today. So it will be 21 years (14 x 18 months) before the iterated hash can be cracked in the same time as the raw password can be cracked today.</p>
<p><img border="0" alt="" src="../../images/HashEntropy.jpeg" width="616" height="238" /></p>
<p>Finally the information entropy in bits is converted to an estimated password strength in 2011 terms. This conversion is really a guesstimate, and will be increasingly inaccurate as hardware scales up (CPU/GPU speed, memory speed/size) and out (grids, etc).</p>
<ul>
<li>In 1998, the EFF cracked a 56-bit key in 56 hours using specialised FPGA hardware.
</li>
<li>In 2002, <a href="http://www.distributed.net/Main_Page/en">distributed.net</a> cracked a 64-bit key in 4 years, 9 months, and 23 days.
</li>
<li>In 2010, distributed.net estimated that cracking a 72-bit key using current hardware would take about 48,712 days or 133.5 years.
</li>
<li>NIST recommends 80 bits for the most secure passwords.
</li>
</ul>
<p><img border="0" alt="" src="../../images/PasswordStrength.jpeg" width="728" height="457" /></p>
<p>You can view and download <em><a href="../../Misc/EntropyChecker.cs.txt" target="_blank">EntropyChecker.cs</a></em>. The complete password utilities library, including this class, will be posted at the end of this series. This completes our analysis of the library itself. In the next installment, we'll look at a console program that tests all of the functions of this library.</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20110408_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20110408_1.html</guid>
    <pubDate>Fri, 08 Apr 2011 21:25:04 +0000</pubDate>
</item>

<item>
    <title>Generating and verifying password hashes</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[<p>This is the sixth installment in a series about creating a C# password utilities library.</p>
<p>The next step is to implement the password <a href="http://en.wikipedia.org/wiki/Salt_%28cryptography%29">salting</a>, <a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function">hashing</a>, and <a href="http://en.wikipedia.org/wiki/Key_stretching">stretching</a>.</p>
<p>The constructors of the <a href="../../Misc/HashGenerator.cs.txt" target="_blank">HashGenerator.cs</a> class let you specify the default hash policy or your own policy. As <a href="articles/20110326_1.html">discussed last time</a>, a policy consists of the salt length in bytes, the hash length in bytes, and how much the password should be stretched (number of hash iterations).</p>
<p><img border="0" alt="" src="../../images/HashGen_01.jpeg" width="888" height="632" /></p>
<p>Once you've specified the password, the code creates a random salt and passes the password, salt, and number of hash iterations into a method that creates and returns the salted hash.</p>
<p><img border="0" alt="" src="../../images/HashGen_02.jpeg" width="820" height="522" /></p>
<p>To create the random salt, we go back to our old friend <em><a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.aspx">RNGCryptoServiceProvider</a></em>, the basis of the <a href="articles/20110316_1.html">dice implementation</a> that we discussed earlier. The <em>GetBytes</em> function returns a set of cryptographically-secure random bytes. It's actually overkill for this purpose, because the salt randomness doesn't need to be that secure.</p>
<p><img border="0" alt="" src="../../images/HashGen_03.jpeg" width="534" height="178" /></p>
<p>To create the salted hash, we're going to use the .NET Framework's implementation of a key derivation function called <a href="http://en.wikipedia.org/wiki/PBKDF2">PBKDF2</a>, also published as <a href="http://www.ietf.org/rfc/rfc2898.txt">RFC 2898</a>. PBKDF2 has some useful properties: you can use a salt, you can define the hash output size, and you can configure the slowdown factor by specifying the number of iterations over the hash function.</p>
<p><img border="0" alt="" src="../../images/HashGen_04.jpeg" width="939" height="178" /></p>
<p>At this point, we're done with the salting, hashing, and stretching. It would be nice to return the salt, the hash, and the number of hash iterations in a single package. This package can then be stored, and used later to verify whether a password and stored salt matches the stored hash. To do this, we return a string containing an ASCII string in the format <em>XXXX.9999.YYYY</em>.&nbsp;<em>XXXX</em> is the salt encoded as a <a href="http://en.wikipedia.org/wiki/Base64">base-64</a> string,&nbsp;<em>9999</em> is the number of iterations of the hashing function, and&nbsp;<em>YYYY</em> is the hash encoded as a base-64 string.</p>
<p><img border="0" alt="" src="../../images/HashGen_05.jpeg" width="814" height="217" /></p>
<p>The final step is to verify a password against a stored salt and hash. To do this, you specify the password along with the stored salt, hash, and number of iterations. The latter can be passed as a single package in the format <em>XXXX.9999.YYYY</em> as discussed above. Or you can pass everything as separate parameters. The salted password is iteratively hashed before being compared to the supplied hash. If the two hashes match, the password is correct.</p>
<p><img border="0" alt="" src="../../images/HashGen_06.jpeg" width="832" height="409" /></p>
<p>You can view and download <a href="../../Misc/HashGenerator.cs.txt" target="_blank">HashGenerator.cs</a>. The complete library, including this class, will be posted at the end of this series. In the next installment, we'll look at the EntropyChecker.cs class, which attempts to measure the information entropy of randomly-generated and human-generated passwords. The information entropy is a reasonable proxy for the password strength.</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20110402_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20110402_1.html</guid>
    <pubDate>Sat, 02 Apr 2011 20:00:04 +0000</pubDate>
</item>

<item>
    <title>Password salting, hashing, and stretching</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[<p>This is the fifth installment in a series about creating a C# password utilities library.</p>
<p>The next step is implementation of a password hash policy. Specifically, a policy that covers salting, hashing, and stretching.</p>
<p>A password <a href="http://en.wikipedia.org/wiki/Salt_%28cryptography%29">salt</a> is a set of (usually random) bits that are the secondary input to a one-way hash function - the first input being the password itself. Salting protect you against pre-computed dictionary attacks, otherwise known as <a href="http://en.wikipedia.org/wiki/Rainbow_table">rainbow tables</a>. Because a rainbow table is made by straightforward hashing of a large dictionary of words, passwords, and passphrases, it can't be used where every password has been hashed with a different salt.</p>
<p><img style="MARGIN-LEFT: 5px" border="0" alt="Orange Explosion" align="right" src="../../images/OrangeExplosion.jpg" width="490" height="359" />There's a common misconception that password salts need to be kept secret. This isn't true - the only protection that salting provides is against rainbow tables. Even if every salt is known, it would take far too much space to create a rainbow table covering every combination of password and salt.</p>
<p><a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function">Hashing</a> a password involves a one-way function that converts an (optionally salted) password into a fixed-size set of bits. The idea is that you always store the password hashes rather than the passwords themselves. After storing a password hash, you can then verify the associated password, by hashing it and then comparing with the stored hash. The benefit of using password hashes is that because the hashing function is one-way, it's not possible for an attacker to reverse-engineer a password from its hashed value.</p>
<p>One issue with using a cryptographic hashing function such as <a href="http://en.wikipedia.org/wiki/SHA-1">SHA-1</a> for password storage is that it's designed to run very fast. Speed is exactly what you don't want in a password hash function, because it means that offline attacks can be executed very fast. Ideally you want to slow down the hashing process from microseconds to as long as 1 second or more. Somebody using a password won't notice a 1-second delay in the login process, but an attacker has no hope of brute-force password cracking if restricted to 1 attempt per second. To slow down the hashing process, we want to use some form of <a href="http://en.wikipedia.org/wiki/Key_stretching">key stretching</a>.</p>
<p>We could stretch the key by simply repeating the hash function multiple times in a loop. Alternatively we could use a hash function that has a slow setup time, for example <a href="http://en.wikipedia.org/wiki/Blowfish_%28cipher%29">Blowfish</a>. As we'll see in the next installment, the method I'm going to use involves a <a href="http://en.wikipedia.org/wiki/Key_derivation_function">key derivation function</a> called <a href="http://en.wikipedia.org/wiki/PBKDF2">PBKDF2</a>, also published as <a href="http://www.ietf.org/rfc/rfc2898.txt">RFC 2898</a>. PBKDF2 has some useful properties: you can use a salt, you can define the hash output size, and you can configure the slowdown factor by specifying the number of iterations over the hash function.</p>
<p><a href="../../Misc/HashPolicy.cs.txt"><img border="0" alt="Hash policy implementation" src="../../images/HashPolicy.jpeg" width="850" height="616" /></a></p>
<p>To create the password hash policy, you need to supply the number of required hash bytes, the number of required salt bytes, and the number of times that the hash function should be applied. The minimum hash size allowed in this implementation is 20 bytes (160 bits), because that's the output size of the hash function I'm going to use (<a href="http://en.wikipedia.org/wiki/HMAC">HMAC</a>-SHA1). The minimum salt size allowed is 8 bytes (64 bits), as that's the lowest size currently considered to give good protection against attacks using rainbow tables. The minimum number of iterations over the hash function is just 2, but the default policy uses 2^14, which is 16,384 iterations. Note that 2^X iterations increases protection (information entropy) against a brute-force attack by X bits. So the default iteration count of 2^14 is the equivalent of adding two extra characters to the original password.&nbsp;&nbsp;</p>
<p>You can <a href="../../Misc/HashPolicy.cs.txt" target="_blank">view and download HashPolicy.cs</a>. The complete library, including this class, will be posted at the end of this series. In the next installment, we'll look at the hash generator class.</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20110326_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20110326_1.html</guid>
    <pubDate>Sat, 26 Mar 2011 19:30:04 +0000</pubDate>
</item>

<item>
    <title>Generating random passwords</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[<p>This is the fourth installment in a series about creating a C# utilities library that covers the following areas:<?XML:NAMESPACE PREFIX = CD /?>
</p>
<ul>
<li>Specifying <a href="articles/20110312_1.html">password policies </a> that can match most application requirements.
</li>
<li>Generating cryptographically-secure <a href="http://en.wikipedia.org/wiki/Random_password_generator">random passwords</a> that satisfy a specified password policy.
</li>
<li>Measuring the <a href="http://en.wikipedia.org/wiki/Password_strength">strength</a> (or more precisely, information entropy) of human-generated and machine-generated passwords.
</li>
<li>Using <a href="http://en.wikipedia.org/wiki/Salt_%28cryptography%29">random salts</a> and <a href="http://en.wikipedia.org/wiki/Key_strengthening">key stretching</a> to make <a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function">password hashes</a> more secure than the original passwords.
</li>
<li>Measuring the additional strength added by iterative salted hashes.&nbsp;
</li>
<li>Timing the password generation and password hashing processes.
</li>
</ul><p><a href="http://jeremy.zawodny.com/blog/archives/006309.html"></a></p>
<p><img style="MARGIN-LEFT: 5px" border="0" alt="Finnish woods" align="right" src="../../images/FinnishWoods.jpg" width="532" height="406" /></p>
<p>Now that we have a <a href="articles/20110312_1.html">PasswordPolicy class</a> and a <a href="articles/20110316_1.html">Die class</a>, the actual password generation process is very straightforward.</p>
<p>We first need to know the password policy, and then roll a die which has the same number of sides as the number of symbols in the policy's acceptable symbols list. The roll result is used as an index into the symbols list, and the symbol at that position becomes the next character in the password. Repeat for as many characters as the password needs - again, this is defined by the password policy.</p>
<p>Most password policies give a wide choice in the password length. In these cases, the die can be used to pick a random actual length between the minimum and maximum password lengths permitted by the policy.</p>
<p>As each password is chosen randomly, it may not match the current password policy. In this case, the password is thrown away and a new one is generated. This continues until a password is found that matches the policy. In the case of a particularly draconian policy, this may take a significant number of attempts. As the current code generates around 20,000 passwords a second, this brute-force approach is not likely to cause a problem.</p>
<p>This method is at the heart of the <strong>PasswordGeneration</strong> class. It accepts a password policy, starts the timer, chooses the password length at random within the policy limits, then keeps generating passwords until it finds one that satisfies the specified password policy. Then the timer is stopped, the time it took to generate the password and the number of passwords rejected by the policy are both stored, and finally the newly-generated password is returned:</p>
<p><a href="../../Misc/PasswordGenerator.cs.txt"><img border="0" alt="Password generation implementation" src="../../images/PasswordGeneration.jpeg" width="772" height="660" /></a></p>
<p>The only other interesting method in this class is the one that calculates the password information entropy. For a password randomly-generated by a machine, entropy is a good proxy for the password's strength. Later in this series, we'll look at the class that calculates the entropy of machine-generated and human-generated passwords:</p>
<p><a href="../../Misc/PasswordGenerator.cs.txt"><img border="0" alt="Password generation implementation" src="../../images/Entropy_1.jpeg" width="852" height="263" /></a></p>
<p>You can <a href="../../Misc/PasswordGenerator.cs.txt" target="_blank">view and download PasswordGenerator.cs</a>. The complete library, including this class, will be posted at the end of this series. In the next installment, we'll look at the hash policy class.</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20110317_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20110317_1.html</guid>
    <pubDate>Thu, 17 Mar 2011 01:00:04 +0000</pubDate>
</item>

<item>
    <title>Secure pseudo-random numbers</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[<p>This is the third installment in a series about creating a C# utilities library that covers the following areas:<?XML:NAMESPACE PREFIX = CD /?>
</p>
<ul>
<li>Specifying <a href="articles/20110312_1.html">password policies </a> that can match most application requirements.
</li>
<li>Generating cryptographically-secure <a href="http://en.wikipedia.org/wiki/Random_password_generator">random passwords</a> that satisfy a specified password policy.
</li>
<li>Measuring the <a href="http://en.wikipedia.org/wiki/Password_strength">strength</a> (or more precisely, information entropy) of human-generated and machine-generated passwords.
</li>
<li>Using <a href="http://en.wikipedia.org/wiki/Salt_%28cryptography%29">random salts</a> and <a href="http://en.wikipedia.org/wiki/Key_strengthening">key stretching</a> to make <a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function">password hashes</a> more secure than the original passwords.
</li>
<li>Measuring the additional strength added by iterative salted hashes.&nbsp;
</li>
<li>Timing the password generation and password hashing processes.
</li>
</ul><p><a href="http://jeremy.zawodny.com/blog/archives/006309.html"><img style="MARGIN-LEFT: 5px" border="0" alt="" align="right" src="../../images/2601737.jpg" width="425" height="317" /></a></p>
<p>To generate random passwords, you obviously need a good source of random numbers. To generate genuinely random numbers, you need access to <a href="http://en.wikipedia.org/wiki/Hardware_random_number_generator">special hardware</a> or a subscription to a site like <a href="http://www.random.org/">random.org</a>. Failing that, you're restricted to using a pseudo-random number generator (<a href="http://en.wikipedia.org/wiki/Pseudorandom_number_generator">PRNG</a> for short). This <a href="http://www.usenix.org/event/evt08/tech/full_papers/calandrino/calandrino_html/">works just fine for password generation</a> as long as you have a suitable source of <a href="http://en.wikipedia.org/wiki/Entropy_%28information_theory%29">information entropy</a>. Enter a .NET Framework class called <a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.aspx">RNGCryptoServiceProvider</a>, which is a cryptographically-secure pseudo-random number generator (<a href="http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator">CSPRNG</a> for short).</p>
<p>Unlike normal PRNGs, CSPRNGs are designed to pass <a href="http://www.phy.duke.edu/~rgb/General/dieharder.php">rigorous statistical randomness tests</a>. They're also designed to hold up well under serious attack, even when their initial or running state becomes available to an attacker.</p>
<p>The term "pseudo-random", as used by cryptographers, may be misleading to a non-technical reader. A CSPRNG expands a collection of random values, known as a seed, into a longer sequence of numbers. That sequence is reproducible given the seed, but for any good CSPRNG, a minor change in the seed yields a very different sequence. Therefore, as long as at least some portion of the seed is chosen via an adequately random process, an attacker is unable to predict the resulting sequence - even if the attacker can influence the remainder of the seed. Numerous important systems, ranging from military communications to the encryption that protects virtually all online transactions, rely on the functionally-equivalent security between "cryptographically-secure pseudo-random" and "random".</p>
<p>To create its seed, the RNGCryptoServiceProvider class draws its entropy from the same pool as the <a href="http://en.wikipedia.org/wiki/CryptGenRandom">CryptGenRandom</a>&nbsp;function, a <a href="http://www.itl.nist.gov/fipspubs/">FIPS</a>-validated CSPRNG. These entropy sources include the current process ID, the current thread ID, the current tick count, the current local time, the global memory status, the amount of free disk space, the local computer name, the local user name, the cursor position, and so on.</p>
<p>A naive implementation of rolling a die with up to 255 sides using RNGCryptoServiceProvider might look something like this:</p>
<p><img border="0" alt="Naive die roll" src="../../images/NaiveDieRoll.jpeg" width="679" height="389" /></p>
<p>Then we roll a 6-sided die 1.2 million times and look at the results:</p>
<p><img border="0" alt="" src="../../images/NaiveRollResults.jpeg" width="274" height="117" /></p>
<p>Ooops! That doesn't look right at all - the distribution is clearly favouring the lower numbers. This is a problem called <a href="http://romhack.wikia.com/wiki/Random_number_generator#Modulo_bias">modulo bias</a>. There are several ways to overcome this. One of the quickest in terms of run-time involves specifically checking for modulo bias every time, and looks something like this:</p>
<p><img border="0" alt="" src="../../images/DieRoll.jpeg" width="683" height="900" /></p>
<p>Again we roll a 6-sided die 1.2 million times and look at the results:</p>
<p><img border="0" alt="" src="../../images/RollResults.jpeg" width="262" height="129" /></p>
<p>That looks like a much better distribution. Although you could go overboard and run some <a href="http://www.cacert.at/cgi-bin/rngresults">serious tests</a>.</p>
<p>Another complaint about using CSPRNGs is that they can be "slow". So let's generate some passwords with this die-rolling class and look at the performance:</p>
<p><img border="0" alt="" src="../../images/PasswordTiming.jpeg" width="283" height="313" /></p>
<p>Setup does take around 1/50th of a second, as reflected in the time taken to generate the first password. But after that, it's fairly fast - generating something in the region of 20,000 passwords a second. This is a clear example of the principle that <em>slow</em> is irrelevant to your customers, your management, and your stakeholders. <a href="http://stackoverflow.com/questions/3769989/should-linq-be-avoided-because-its-slow/3770194#3770194"><em>Not fast enough</em></a> is what's really relevant.</p>
<p>You can <a href="../../Misc/Die.cs.txt" target="_blank">view and download Die.cs</a>. The complete library, including this class, will be posted at the end of this series. In the next installment, we'll look at the password generator class.</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20110316_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20110316_1.html</guid>
    <pubDate>Wed, 16 Mar 2011 20:00:04 +0000</pubDate>
</item>

<item>
    <title>A password policy implementation</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[<p>As discussed in the <a href="articles/20110305_1.html">first installment</a>&nbsp;of this series, I'm on a mission to create a C# utilities library covering the following areas:<?XML:NAMESPACE PREFIX = CD /?>
</p>
<ul>
<li>Specifying <a href="http://en.wikipedia.org/wiki/Password_policy">password policies</a> that can match most application requirements.
</li>
<li>Generating cryptographically-secure <a href="http://en.wikipedia.org/wiki/Random_password_generator">random passwords</a> that satisfy a specified password policy.
</li>
<li>Measuring the <a href="http://en.wikipedia.org/wiki/Password_strength">strength</a> (or more precisely, entropy) of human-generated and machine-generated passwords.
</li>
<li>Using <a href="http://en.wikipedia.org/wiki/Salt_%28cryptography%29">random salts</a> and <a href="http://en.wikipedia.org/wiki/Key_strengthening">key stretching</a> to make <a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function">password hashes</a> more secure than the original passwords.
</li>
<li>Measuring the additional strength added by iterative salted hashes.&nbsp;
</li>
<li>Timing the password generation and password hashing processes.
</li>
</ul><p><a href="http://jeremy.zawodny.com/blog/archives/006309.html"><img style="MARGIN-LEFT: 5px" border="0" alt="" align="right" src="../../images/password-insanity.png" width="450" height="438" /></a>Most applications that use a password or passphrase for user authentication also have a policy that dictates the password complexity requirements. These requirements range from a simple minimum length to <a href="http://jeremy.zawodny.com/blog/archives/006309.html">some very complex rules</a>. There's a decent case for arguing that the more complex policies might actually reduce security in some circumstances. This is because these policies encourage users to invent easier-to-remember (i.e. weaker) passwords or to write down passwords in order to remember them.
</p>
<p>Another problem with password policies is that they're mainly aimed at reducing the threat of direct attacks on the application (the online attack) or on the application's login database (the offline attack). They ignore other attacks such as <a href="http://en.wikipedia.org/wiki/Keylogger">keylogging</a> and <a href="http://en.wikipedia.org/wiki/Botnet">botnets</a>, which could be considered as more common threats than the direct attacks.
</p>
<p></p>
<p>Finally, you might want to explain to your <a href="http://research.microsoft.com/en-us/um/people/cormac/papers/2009/SoLongAndNoThanks.pdf">over-eager security team</a> that the vast majority of end-users quite rationally believe that:</p>
<ul>
<li>The chance of their account being compromised by a direct online attack is almost zero.
</li>
<li>The chance of their account being compromised by a direct offline attack is very low.
</li>
<li>Their bank will likely make good any financial losses resulting from a direct offline/online compromise.
</li>
<li>Given the above three facts, it doesn't make sense to spend any time choosing strong passwords and never re-using passwords on other websites.
</li>
</ul>
<p>Moving swiftly on...let's look at the source code of <strong>PasswordPolicy.cs</strong>, a class that implements policies used to control the generation and validation of passwords. The constants in the following screenshot define all of the possible symbol groups, and individual symbols within those groups, that can be used to create passwords controlled by this policy generator. Note that symbols normally considered to be confusing, such as 0, O, I, 1, etc, have already been removed. I've split punctuation symbols into their own group as applications such as Gmail allow their use whilst prohibiting other non-alphanumeric ASCII symbols. I've also included some non-ASCII symbols, as an increasing number of applications are now <a href="http://www.joelonsoftware.com/articles/Unicode.html">Unicode-aware</a>. Feel free to tune these constants to suit your applications. Be aware that if you add or remove any symbol groups, you will need to change the <em>SymbolType</em> enumeration and also any code that uses that enumeration.</p>
<p><img border="0" alt="" src="../../images/PasswordPolicy_04.jpeg" width="682" height="328" /></p>
<p>The class constructor allows either the default password policy or a custom one. For a custom policy, the full list of parameters is shown in the screenshot. The use of symbols from each symbol group can be prohibited by passing null for that symbol group, made optional by passing zero, or made mandatory by passing the minimum number of password characters that must be drawn from that symbol group.</p>
<p><img border="0" alt="" src="../../images/PasswordPolicy_08.jpeg" width="767" height="797" /></p>
<p>The default policy doesn't try to do anything clever. It works on the principle that password length is the best security, hence the minimum length of 14. Non-ASCII symbols are prohibited, all other symbol groups are allowed but optional. Again, you can change this default policy as required.</p>
<p><img border="0" alt="" src="../../images/PasswordPolicy_06.jpeg" width="602" height="143" /></p>
<p>These two properties return a byte array or Unicode string containing the full list of symbols allowed in any password matching the current policy.</p>
<p><img border="0" alt="" src="../../images/PasswordPolicy_07.jpeg" width="587" height="247" />&nbsp;</p>
<p>For any password matching the current policy, this method provides the major input to a formula for measuring the entropy of randomly-generated passwords matching this policy. We'll take a detailed look at this formula in a later installment.</p>
<p><img border="0" alt="" src="../../images/PasswordPolicy_09.jpeg" width="851" height="520" /></p>
<p>Not shown is the method that calculates whether a given password matches the current policy. But you can <a href="../../Misc/PasswordPolicy.cs.txt" target="_blank">view and download PasswordPolicy.cs</a>. The complete library, including this class, will be posted at the end of this series. In the next installment, we'll look at the die-rolling class.</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20110312_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20110312_1.html</guid>
    <pubDate>Sat, 12 Mar 2011 21:20:04 +0000</pubDate>
</item>

<item>
    <title>A race against time - protecting user passwords</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p>It's disappointing that major web sites still aren't protecting their customer accounts properly. One of the more recent reports is about the controversial Gawker.com media empire where its complete customer login database has been placed on the Internet and <a href="http://www.lightbluetouchpaper.org/2010/12/15/the-gawker-hack-how-a-million-passwords-were-lost/">hundreds of thousands of its user passwords already cracked</a> using <a href="http://www.openwall.com/john/">John the Ripper</a>.&nbsp;Another <a href="http://arstechnica.com/tech-policy/news/2011/02/how-one-security-firm-tracked-anonymousand-paid-a-heavy-price.ars">major hack had unfortunate consequences</a> for a security firm.</p>
<p>Unlike the earlier <a href="http://techcrunch.com/2009/12/14/rockyou-hack-security-myspace-facebook-passwords/">RockYou hack</a>, where all the customer passwords were stored in plain text, Gawker used a <a href="http://en.wikipedia.org/wiki/Crypt_%28Unix%29">relatively primitive password hashing scheme</a>. Unfortunately, their scheme wasn't even close to adequate because of a combination of the primitive hashing, weak user passwords, and the <a href="http://blog.zorinaq.com/?e=42">enormous amount of firepower</a> that modern hardware and software gives to attackers.</p>
<p>In today's world, where <a href="http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator">cryptographically-strong pseudo-random number generators</a> and iterative hashing schemes such as <span class="comment"><font color="#000000"><a href="http://en.wikipedia.org/wiki/PBKDF2">PBKDF2</a> or <a href="http://www.bsdcan.org/2009/schedule/events/147.en.html">scrypt</a></font></span>&nbsp;combine to give an equal amount of firepower to defenders, this state of affairs is inexcusable. I thought it would be useful to package some C# code into a utilities library covering the following areas:</p>
<ul>
<li>Specifying <a href="http://en.wikipedia.org/wiki/Password_policy">password policies</a> that can match most application requirements.
</li>
<li>Generating cryptographically-secure <a href="http://en.wikipedia.org/wiki/Random_password_generator">random passwords</a> that satisfy a specified password policy.
</li>
<li>Measuring the <a href="http://en.wikipedia.org/wiki/Password_strength">strength</a> (or more precisely, entropy) of human-generated and machine-generated passwords.
</li>
<li>Using <a href="http://en.wikipedia.org/wiki/Salt_%28cryptography%29">random salts</a> and <a href="http://en.wikipedia.org/wiki/Key_strengthening">key stretching</a> to make <a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function">password hashes</a> more secure than the original passwords.
</li>
<li>Measuring the additional strength added by iterative salted hashes.&nbsp;
</li>
<li>Timing the password generation and password hashing processes.
</li>
</ul>
<p><img style="MARGIN-LEFT: 5px" border="0" alt="" align="right" src="../../images/1706256.jpg" width="400" height="314" /></p>
<p>Before diving into the detailed code, let's look at the major threat. Imagine that your website's security has been breached and its password database is now in the hands of the attacker. He can launch an offline attack on the database, and dump your users' account names and cracked passwords publicly on the Internet. When this happens, at the very least you have problems 1 and 2 in the list below, whilst your users have problems 3 and 4:</p>
<ol>
<li>Your organisation will have some rather unpleasant publicity.
</li>
<li>Many of your users will likely lose trust in your organisation.
</li>
<li>The dump will be harvested by people looking to compromise your application's user accounts.
</li>
<li>The dump will be harvested by people looking for passwords that might have been reused on other web sites.
</li>
</ol>
<p>So you're now in a race against time.&nbsp;</p>
<p>If your application stores the passwords in plain text like RockYou, it's "game over". Your best bet is first to warn your users about what happened and the implications. Then force them to change all of their user passwords, or change their passwords yourself.</p>
<p>If your application hashes the passwords using the same scheme as Gawker (DES crypt(3)), the situation may be a little better. It depends on the strength of your users' passwords and passphrases. Because DES can be executed extremely fast with modern hardware, weak passwords will be broken within a few minutes to a few hours. For these users, problems 3 and 4 in the bulleted list above will rapidly apply.</p>
<p>But for those users who used a much longer password, or hopefully a <a href="http://en.wikipedia.org/wiki/Passphrase">passphrase</a>, the situation isn't quite as bad. DES crypt(3) compresses the password hash to fit the size of a DES key, so many passphrases will hash to the same value. Your users will still have problem 3 in the bulleted list above. But as the passphrase itself can't be disclosed by a successful match, your users won't have to worry about problem 4.</p>
<p>What's clear is that the stronger your password hashing scheme and your user passwords are, the more time you and your users have to deal with problems 3 and 4 above. The next installment in this series will look at password policies and how they can be implemented in software to increase the strength of user passwords.&nbsp;</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20110305_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20110305_1.html</guid>
    <pubDate>Sat, 05 Mar 2011 19:00:04 +0000</pubDate>
</item>

<item>
    <title>Random Fizzbuzz</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p><a href="http://tickletux.wordpress.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/">FizzBuzz</a> is an interview-related meme that <a href="http://www.codinghorror.com/blog/archives/000781.html">did the rounds</a> about a year ago. The idea is that you can use a very simplistic question to screen-out a significant percentage of candidates applying for a job in software development. If you can't program FizzBuzz in a deep coma while having half your brain removed, then you can't program anything properly.&nbsp;</p>
<p>Of course, every software developer is basically a machine in search of <a href="http://xkcd.com/356/">curious problems to solve</a>, and I'm no different. Just how outrageous an answer to FizzBuzz would persuade an interviewer to hire me on the spot? Inspired by this <a href="http://chalain.livejournal.com/68788.html">Ruby gem</a>, I played a variation in the key of C#. It took about 9 minutes of CPU time to compute a&nbsp;<a href="http://web.archive.org/web/20011027002011/http://dilbert.com/comics/dilbert/archive/images/dilbert2001182781025.gif">pseudo-random number generator</a> seed that produces the correct answers for the FizzBuzz quiz in an entirely random fashion:</p>
<ul>
</ul>
<p><?XML:NAMESPACE PREFIX = CD /?>
<img height="536" alt="A random variation on FizzBuzz in the key of C#" src="../../images/RandomFizzBuz.jpg" width="699" border="0" /></p>
<p>
But we all know that coding <a href="http://en.wikipedia.org/wiki/Magic_number_%28programming%29#Unnamed_numerical_constant">magic numbers</a> into your code is a no-no, especially in an interview situation. So I turned to a <a href="http://pi.nersc.gov/">suitable source</a> to see if I could compute 126782503 rather than just hard-coding it. The 28-bit binary equivalent of 126782503 is 0111100011101000110000100111. And sure enough, you can find that binary number <a href="http://pi.nersc.gov/cgi-bin/pi.cgi?word=78E8C27&amp;format=hex">hiding sneakily in pi</a> at binary index 3,422,140,640. Unfortunately, it would take quite some time to compute pi to that length, even with the help of the amazing <a href="http://en.wikipedia.org/wiki/Bailey-Borwein-Plouffe_formula">BBP formula</a>.</p>
<p>Then I showed this to my <a href="http://pascal.alseyn.net/galaxy/MultiGirlFriendsManagement/">colourful</a> colleague <a href="http://pascal.alseyn.net/start/">Pascal Honore</a>, and he started playing with it in PHP. More on this in the next installment.</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20080313_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20080313_1.html</guid>
    <pubDate>Thu, 13 Mar 2008 23:00:04 +0000</pubDate>
</item>

<item>
    <title>The Skeptical Software Development Manifesto</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p>A delicious smorgasbord of random links today.</p>
<p><strong>Techie</strong></p>
<ul>
<li><a href="http://www.hacknot.info/hacknot/action/showEntry?eid=30">The Skeptical Software Development Manifesto</a>: Excellent thought-provoking parody of the <a href="http://agilemanifesto.org/">Manifesto for Agile Software Development</a>.
</li>
<li>
<a href="http://www.creativyst.com/Doc/Articles/Mgt/AgileBridges/AgileBridges.htm">Agile bridge building</a>: More satirising of the Agile approach to software development.
</li>
<li>
<a href="http://www.yoda.arachsys.com/csharp/events.html">Delegates and events</a>: Good and detailed explanation of events and delegates in .NET.
</li>
<li>
<?XML:NAMESPACE PREFIX = CD /?>
<a href="http://docs.sun.com/source/806-3568/ncg_goldberg.html">Essential floating-point arithmetic</a>: Important information about floating-point arithmetic for the software developer.
</li>
<li>
<a href="http://www.acme.com/mail_filtering/introduction_frameset.html">Heavyweight spam filtering</a>: How to block a few million spams per day without breaking sweat.
</li>
<li><a href="http://www.secretgeek.net/littlefishes_.asp">Why accurate estimates aren't possible</a>: This one really hits home hard.
&nbsp;
</li>
<li><a href="http://www.csd.uwo.ca/staff/magi/personal/humour/Computer_Audience/The%20Parable%20of%20the%20Two%20Programmers.html">Parable of Two Programmers</a>: And so does this, even though it was written in 1985.
&nbsp;
</li>
<li>
<a href="http://blogs.msdn.com/ricom/archive/2005/12/16/504800.aspx">Amdahl's Law</a>: Wisdom from a .NET performance guru.
</li>
</ul>
<p><strong>Non-Techie</strong></p><ul>
<li><a href="http://www4.sungard.com/flash/experience/index.php?namen=patricktam">Patrick Tam</a>: My boss where I work currently (Flash).&nbsp;</li>
<li>
<a href="http://www.plinko.net/404/area404.asp">404 Research Lab</a>: Some interesting "Page Missing" error messages - <a href="http://msmvps.com/error.htm?aspxerrorpath=/blogs/post.aspx">this one</a> is kinda funny.
</li>
<li>
<a href="http://www.scottberkun.com/blog/2006/the-vista-saga-opinions/">The Vista saga</a>: An insider's view on what might have happened with Vista.
</li>
<li><a href="http://www.fastcompany.com/magazine/94/open_change-or-die.html">Change or Die</a>: Could you change your behaviour if your life really depended on it?&nbsp;
</li>
<li>
<a href="http://www.msnbc.msn.com/id/3071466/">North Korean gulag</a>: Almost too <a href="http://news.bbc.co.uk/1/hi/programmes/this_world/3440771.stm">painful</a> to read - Camp 22 is apparently now closed, but the nightmare continues.
</li>
</ul>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20070526_2.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20070526_2.html</guid>
    <pubDate>Sat, 26 May 2007 23:50:04 +0000</pubDate>
</item>

<item>
    <title>I for one welcome our new chess overlords</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p>A while ago, I took <a href="http://www.codinghorror.com/blog/">Jeff Attwood</a> to task about his analysis of the <a href="http://www.codinghorror.com/blog/archives/000701.html">current state of chess and computers</a>. I <a href="articles/20061015_1.html">claimed</a>&nbsp;that the chess machines such as <a href="http://en.wikipedia.org/wiki/Hydra_(chess)">Hydra</a> and chess programs such as <a href="http://www.chessgames.com/player/deep_fritz.html">Deep Fritz</a> are now starting to crush all human opposition. Brute-force searching and clever tricks such as <a href="http://www.seanet.com/~brucemo/topics/nullmove.htm">null-move pruning</a> have finally won the day.&nbsp;</p>
<p>As I said in my previous entry, Hydra recently terminated <a href="http://tournament.hydrachess.com/aadams.php">English GM Michael Adams</a> with 5 wins and just 1 draw against the world's number 7. I also made the bold prediction that human <a href="http://news.bbc.co.uk/1/hi/world/europe/6049276.stm">world chess champion</a> Vladimir Kramnik was going to suffer in his November 2006 match against Deep Fritz. At the time, many knowledgeable and strong players disagreed with me. For example, <a href="http://www.susanpolgar.com/">Susan Polgar</a>, the second strongest female player ever, <a href="http://susanpolgar.blogspot.com/2006/11/kramnik-fritz-prediction.html">predicted a 3-3 draw</a>. Many other strong grandmasters thought that Kramnik had good chances based on his recent tournament results. And back in 2002, Kramnik managed a <a href="http://www.chess.gr/tourn/2002/kramnik-d.fritz/main.html">4-4 draw</a> against an older version of Deep Fritz.</p>
<p>So what happened?</p>
<p>Kramnik did indeed suffer, and eventually succumbed - Deep Fritz <a href="http://news.bbc.co.uk/1/hi/world/europe/6212076.stm">won 4-2</a>, with 2 wins and 4 draws. The intense pressure obviously made for some interesting chess - Kramnik's first loss was caused by&nbsp;<a href="http://susanpolgar.blogspot.com/2006/11/blunder-of-century-biggest-blunder.html">missing a mate in one</a>, almost unprecedented at this level. But in the final game, Fritz played some <a href="http://www.chessbase.com/newsdetail.asp?newsid=3524">deep and brilliant lines</a>, fooling most of the GMs present who thought the monster was finally going down.</p>
<p>Hydra is significantly stronger than Deep Fritz, and I think the result of a match between Hydra and Kramnik would be almost a foregone conclusion. I for one welcome our new chess overlords.</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20070526_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20070526_1.html</guid>
    <pubDate>Sat, 26 May 2007 18:45:04 +0000</pubDate>
</item>

<item>
    <title>Chilling-out in style</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p>I can't listen to music when I'm actually coding, or during deep design stuff. But at all other times, especially when I'm writing or web surfing, I have a few playlists that I regularly switch between depending on mood. But I spent a long time looking for a visualiser program that could produce nice flowing graphics. My search ended a few days ago. <a href="http://www.soundspectrum.com/g-force/">G-Force</a> is <a href="http://www.soundspectrum.com/g-force/screenshots.html">spectacular</a> - within 10 minutes of downloading the trial, I purchased the Platinum edition - it was that good. The Platinum edition comes bundled with <a href="http://www.soundspectrum.com/g-force/standalone.html">G-Force Standalone</a>, which produces visualisations from any sound source supported by your computer.</p>
<p>My 3.5 year-old daughter sits on my lap transfixed, almost hypnotised, by the rich tapestry of gorgeous colours and patterns that G-Force produces. Now I just need to hook it up to the 50-inch HD plasma screen, turn off the lights, sit back on the sofa with a pint of <a href="http://www.westons-cider.co.uk/acatalog/info%5fHWVR%2ehtml">vintage Special Reserve Westons cider</a>, and truly chill-out in style.</p>
<p><strong>Disclaimer</strong>: I have absolutely no connection with the company or people that produce G-Force, apart from being a happy customer.</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20061230_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20061230_1.html</guid>
    <pubDate>Sat, 30 Dec 2006 02:35:04 +0000</pubDate>
</item>

<item>
    <title>Office pictures</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p><a href="http://www.antair.com/blog/">Andrey Butov</a> started an <a href="http://discuss.joelonsoftware.com/default.asp?biz.5.417980.32">interesting thread</a> on Joel's <a href="http://discuss.joelonsoftware.com/?biz">Business of Software forum</a> where he presented a view of his work world in pictures. Unfortunately, very few people replied with their own pictures. So here is a small view of where I spend my time when working at home.</p>
<p>On the left is my space, on the right is my wife's space. We have 2 networked computers each (using KVM switches), and share an ADSL connection and a printer/scanner/copier - the latter is the ugly lump on the far right of my wife's desk. This is all on the top floor of a converted warehouse in north London.</p>
<?XML:NAMESPACE PREFIX = CD /?>
<p>
<img style="MARGIN-RIGHT: 5px" height="300" alt="" src="../../images/Office_Mark.jpg" width="400" align="left" border="0" /><img style="MARGIN-RIGHT: 5px" height="300" alt="" src="../../images/Office_Tamara.jpg" width="400" align="left" border="0" /></p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20061123_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20061123_1.html</guid>
    <pubDate>Thu, 23 Nov 2006 00:35:04 +0000</pubDate>
</item>

<item>
    <title>Cunning creatures, those bugs</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p>Still trying to exhaust my backlog of interesting links.</p>
<p><strong>Techie</strong></p>
<ul>
<li><a href="http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html">Cunning creatures, those bugs</a>: Be careful, especially when writing "easy" code.
</li>
<li><a href="http://pluralsight.com/blogs/mike/archive/2006/09/25/38697.aspx">Obfuscated C# 2.0</a>: Next time you're faced with an interviewee who thinks he's God's gift to .NET development, give him this test.
</li>
<li>
<a href="http://blogs.msdn.com/michkap/archive/2005/02/07/368570.aspx">Normalisation as obfuscation in C#</a>: And if he gets the previous one right, this one's really going to nail him!
</li>
<li>
<a href="http://blogs.msdn.com/michkap/archive/2006/04/11/572838.aspx">Case-sensitive VB .NET</a>: And when he claims that VB. NET is case-insensitive, this one ought to shut him up.
&nbsp;&nbsp;&nbsp;&nbsp;
</li>
<li><a href="http://wired.com/wired/archive/14.11/botnet.html">Attack of the bots</a>: Interesting Wired essay about crashing a significant portion of the Internet.
</li>
<li>
<a href="http://msmvps.com/error.htm?aspxerrorpath=/blogs/post.aspx">Nice error message</a>: When something goes wrong, a good sense of humour goes a long way.
</li>
<li>
<a href="http://michaelhyatt.blogs.com/workingsmart/2004/11/how_to_sell_you.html">How to sell your boss</a>: If you can't get your boss' approval at the right time, then you're not going to go far.
</li>
</ul>
<p><strong>Non-Techie</strong></p><ul>
<li><a href="http://www.nytimes.com/slideshow/2006/10/23/science/20061024_ALZH_SLIDESHOW_1.html">Disturbing self-images</a>: An artist records his own descent into dementia.&nbsp;
<?XML:NAMESPACE PREFIX = CD /?>
</li>
<li>
<a href="http://video.google.com/videoplay?docid=-6909078385965257294">All marketers are liars</a>: Interesting insights from a Seth Godin presentation at Google.
</li>
<li>
<a href="http://www.damninteresting.com/?p=160#more-160">This place is not a place of honor</a>: Physicists tell me this really isn't necessary, but it's interesting nonetheless.
</li>
</ul>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20061120_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20061120_1.html</guid>
    <pubDate>Mon, 20 Nov 2006 21:00:04 +0000</pubDate>
</item>

<item>
    <title>Naughty, naughty</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p>Some more interesting links harvested over the last few months - there should be something for everyone in today's link dump.</p>
<p><strong>Techie</strong></p>
<ul>
<li><a href="http://www.google.com/codesearch?q=+keygen+name+serial+show:n7lzx83Fh-k:Z1tHhQiuqr0:5FzGruqYsUI&amp;sa=N&amp;cd=21&amp;ct=rc&amp;cs_p=www.cs.mcgill.ca/~cs520/JOOS1.1/joosbench2005-v2.tar.gz&amp;cs_f=joosbench05/01Benchmark/KeyGen.java#a0">Keygen for WinZip 9</a>: Found using Google's new <a href="http://www.google.com/codesearch">code search app</a>.
</li>
<li>
<a href="http://xooglers.blogspot.com/">Xooglers</a>: Reminiscences from ex-Googlers.
</li>
<li>
<a href="http://www.ddj.com/dept/debug/193104891">Mars Polar Lander vanished</a>: Interesting analysis of the software bug that lost a spacecraft.
</li>
<li>
<a href="http://www.cs.tau.ac.il/~nachumd/horror.html">More software horror stories</a>: Dead bodies everywhere.
&nbsp;&nbsp;&nbsp;
</li>
<li><a href="http://c2.com/cgi/wiki?AlarmBellPhrase">Alarm bell phrases</a> : When you hear one of these, run.
</li>
<li><a href="http://www.tmk.com/ftp/humor/computer-error-messages.txt">Humorous error messages</a>: On the Nixdorf 8870, canceling a print job would sometimes produce the message <em>Spooling is too tough!</em>
</li>
<li>
<a href="http://www.codinghorror.com/blog/archives/000305.html">Google hardware circa 1999</a>: They've grown a little since then - 170,000+ servers was the last figure that I heard.
</li>
<li><a href="http://www.ex-parrot.com/~pete/upside-down-ternet.html">Naughty, naughty</a>: Beware when stealing somebody's wireless Internet access.
</li>
</ul>
<p><strong>Fun</strong></p><ul>
<li><a href="http://www.everything2.com/index.pl?node_id=1411652">Things nobody tells you about the South Pole</a>: Apparently, it's been stolen several times.&nbsp;
</li>
<li><?XML:NAMESPACE PREFIX = CD /?>
<a href="http://www.damninteresting.com/?p=410">KEO</a>: Watch the skies in <a href="http://www.keo.org/uk/pages/faq.html">52,007 AD</a>.
</li>
<li><a href="http://www.dangerouslaboratories.org/radscout.html">The radioactive boy scout</a>: Nobody really needs a home-made nuclear reactor .
</li>
<li><a href="http://www2.tech.purdue.edu/cgt/courses/cgt411/covey/48_laws_of_power.htm">The 48 Laws of Power</a>: Many software developers have Machiavellian tendencies.
</li>
</ul>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20061017_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20061017_1.html</guid>
    <pubDate>Tue, 17 Oct 2006 01:44:04 +0000</pubDate>
</item>

<item>
    <title>The chess Terminators are already among us</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p>Jeff Attwood has an <a href="http://www.codinghorror.com/blog/">interesting blog</a> which is consistently <a href="http://www.codinghorror.com/blog/archives/000688.html">informative</a>. But occasionally he strays onto subjects that are outside his core expertise. And his <a href="http://www.codinghorror.com/blog/archives/000701.html">recent article on chess and computers</a> is an example of this. As an ex-professional player (albeit a not very successful one), and co-author of a chess program that was quite strong in its day, I think that his analysis of the strength of chess computers is rather superficial.&nbsp;</p>
<p><strong>Brute force versus AI</strong></p>
<p><strong></strong>Jeff correctly points out that the <a href="http://en.wikipedia.org/wiki/Brute-force_search">brute-force approach</a>&nbsp;(type A) has historically been much more successful in producing strong chess computers than the AI-type approach (type B). But he then suggests that type B programs are starting to emerge, and uses a quote from an <a href="http://www.extremetech.com/article2/0,1697,1915528,00.asp">interesting ExtremeTech article</a> on building a personal computer optimised for playing chess:</p>
<p><em>"Despite its vastly inferior brute force, the Deep Blitz machine could already be a match for Deep Blue because of improvements in chess software. Deep Fritz is able to evaluate lines of play to a similar depth because it successfully narrows its search only to the strongest lines of play."</em></p>
<p>In fact, what <a href="http://www.chessgames.com/player/deep_fritz.html">Deep Fritz</a> is doing here (<a href="http://www.seanet.com/~brucemo/topics/nullmove.htm">null-move forward pruning</a>) has nothing to do with an AI-type approach. Instead, it's just a sophisticated tree-search technique that allows you to cut-off large parts of the search tree without actually doing a full analysis. So this is really just a clever addition to the brute-force armoury - it owes absolutely nothing to AI. <a href="http://en.wikipedia.org/wiki/Fritz_(chess)">Fritz</a> and its competitors such as <a href="http://www.shredderchess.com/">Shredder</a> and the <a href="http://en.wikipedia.org/wiki/Hydra_(chess)">chess monster known as Hydra</a> are basically brute-force searchers with only a rudimentary understanding of chess positions when compared to human grandmasters.&nbsp;</p>
<p><strong>Will chess computers consistently beat all humans?</strong></p>
<p>I think Jeff is correct in his dismissal of <a href="http://bramcohen.livejournal.com/29624.html">Bram Cohen's ultra-simplistic analysis</a> of the current state of computers versus humans in chess. But he counter-attacks with an old&nbsp;<a href="http://www.chessbase.com/newsdetail.asp?newsid=1244">article by chess statistician Jeff Sonas</a> stating that the top 200 humans are (or were in 2001-2003) keeping up with the best chess computers. This article has at least 3 problems:&nbsp;</p>
<ul>
<li>It's impossible to draw statistically-valid conclusions from just 65 games.
</li>
<li>2003 is a long time ago in computer terms.
</li>
<li>History has shown that Sonas was probably wrong.&nbsp;
</li>
</ul>
<p>The <a href="http://www.chessbase.com/newsdetail.asp?newsid=2476">most significant recent match</a> was in mid-2005 between <a href="http://tournament.hydrachess.com/aadams.php">English GM Michael Adams</a> (then rated number 7 in the world) and the aforementioned Hydra - a chess machine rather than a chess program. Once again, it's not feasible to draw a statistically-valid conclusion from a match of just 6 games. But the result was pretty convincing: <strong>5.5 - 0.5</strong>. That is to say Hydra won 5 games and drew 1 game. It's arguable that Adams didn't prepare properly for the match, but it's interesting that Hydra never had a bad position in the whole match. If a human GM can't get to a position that his computer opponent doesn't understand properly, then eventually he's going to be curled up in a corner with his paws pointing skywards. This is because the machines are so strong tactically that it's only a matter of time before the human is caught and pureed.</p>
<p>Here's some commentary from Adams himself on the match:</p>
<p><em>"I didn't play badly throughout the event, but it’s just so difficult to make an impact. It’s not like playing against other humans – for starters against humans you may actually win a point."</em></p>
<p>And here is GM Nigel Short's interesting analysis:</p>
<p><em>"I have a great business proposition for you: I give you $10,000, or $20,000 if you are really, really good. You get on a stage in London and allow yourself to be fucked by a machine for six days. How does it sound?"</em></p>
<p>GM John Nunn has his own opinion:</p>
<p><em>"The Adams-Hydra match signals the approaching end of man-machine contests. Already, <a href="http://www.chessbase.com/newsdetail.asp?newsid=1949">last year's event in Bilbao</a> was a sign that things were looking bleak for the humans. In Bilbao, it was not so much the performance of Hydra that was so impressive, but Fritz's score of 3.5/4 against Ponomariov, Topalov and Karjakin (twice). Hydra, which made the same score, was running on its special-purpose hardware but Fritz was running on a laptop computer from the local department store."</em></p>
<p>And if all that doesn't convince you, Vladimir Kramnik has recently retained his world chess champion title, and is due to play&nbsp;<a href="http://www.chessbase.com/newsdetail.asp?newsid=2947">a match against Deep Fritz</a> in November 2006. Here's his analysis of his chances against a program that isn't as strong as Hydra:</p>
<p><em>"Vladimir Kramnik said that Deep Fritz was definitely the favourite and rated his chances for beating the machine at about 40-50%.....The Classical Chess World Champion replied that certainly the day would come when computers would play so well that no human being could compete against them, but that he hoped that November 2006 would not be that day. He believed that the contest between man and machine will still be exciting for a couple of more years."</em></p>
<p>Wesner Moise adds <a href="http://wesnerm.blogs.com/net_undocumented/2006/10/computers_and_c.html">his own contribution</a> to the debate. It's true that "draw death" may give humans a chance to hold on to their illusions for an extra year or so. But the end is going to be both brutal and inevitable: the machines will prevail - and the chess Terminators are already among us.&nbsp;&nbsp;</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20061015_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20061015_1.html</guid>
    <pubDate>Sun, 15 Oct 2006 18:00:04 +0000</pubDate>
</item>

<item>
    <title>Web Services for Dummies</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p>Somebody on a <a href="http://www.joelonsoftware.com/">Joel on Software</a> forum asked how to explain Web Services to a non-technical business person. Here's my 10-second <a href="http://www.businessknowhow.com/money/elevator.htm">elevator pitch</a>:</p>
<ul>
<li>Web <strong>pages</strong> allow <strong>people</strong> to communicate and collaborate with each other using the Internet or an intranet.</li>
<li>Web <strong>services</strong> allow <strong>programs</strong> to communicate and collaborate with each other using the Internet or an intranet.</li>
</ul>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20060407_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20060407_1.html</guid>
    <pubDate>Fri, 07 Apr 2006 02:00:04 +0000</pubDate>
</item>

<item>
    <title>Edit &amp; Continue in VS 2005</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p>Dennis Forbes talks about <a href="http://www.yafla.com/dforbes/categories/everything/2005/12/20.html#a223">the dangers of Edit &amp; Continue</a> (via <a href="http://www.lenholgate.com/archives/000596.html">Len Holgate</a>), and its re-introduction in VS 2005.</p>
<p>Having been a long-time user of E&amp;C in the VB.Classic IDE, I have mixed feelings. There are both benefits and dangers to this feature, and on balance, I feel that the benefits outweigh the drawbacks. The arguments against E&amp;C tend to emphasise the dangers of this feature in the hands of inexperienced developers. Well, almost everything is dangerous in the hands of an inexperienced developer, so that's just not a convincing argument for me. And if you do understand what you're doing, E&amp;C can be a great benefit.</p>
<p>Enough preaching. Like any subject, the devil is in the details. So let's look closer at some typical uses of E&amp;C.</p>
<p><strong>Bad Debugging with E&amp;C</strong></p>
<p>A developer makes several attempts during a single run to fix a problem. He repeats a cycle of altering code and then resetting the current execution point to run through the altered code. For example, a developer believes that a bug is caused by an off-by-one error in a loop. So he firsts puts a +1 in the loop and then checks the result. If that doesn’t work, he puts a –1 in the loop instead, still hoping to get the right result.</p>
<p>Proponents of this debugging approach say that it is more efficient because there is no need to restart the program after every code change. The problem, though, is the indisputable fact that in this case the developer doesn’t actually understand the problem. If he did understand the problem, there would be no need to make multiple attempts at a fix — he could go straight to the problem area and fix it in one attempt.</p>
<p>While E&amp;C makes it very tempting to try many potential solutions until something seems to work, this is akin to poking a jellyfish with a stick to see if it moves; it doesn't actually teach you very much. A quality solution is much more likely to come from some deep thinking about a problem rather than ad-hoc attempts at a fix.</p>
<p><strong>More Bad Debugging with E&amp;C</strong></p>
<p>A developer starts by finding and fixing a single bug, but then attempts to fix more defects that appear. These defects are often related to or hiding behind the first bug. The temptation when using E&amp;C is to find and fix as many bugs as possible during a single run—this can be very satisfying and at first sight seems to be an efficient method of working.</p>
<p>Unfortunately, this approach also has problems. First, the developer once again probably doesn't understand the original defect at a deep level. If she understood the original bug properly, it is unlikely that her original fix would have exposed the multiple new issues. Even if she did understand the bug, it is debatable how well the new issues and subsequent fixes were understood. As before, E&amp;C makes it far too tempting to fix bugs as they arise, rather than taking time to think about the issues away from the heat of the battle.</p>
<p>Another problem with this approach is that if there are multiple issues being exposed within a block of code, it is likely that the code itself is fundamentally flawed. Such code always benefits from taking a step back from the situation rather than fixing the bugs in an ad-hoc manner. Using E&amp;C to push multiple fixes is unlikely to improve the code’s quality.</p>
<p>The next problem is that several programming experiments have been done that collectively show that the average developer introduces one new bug for every two bugs that he or she fixes. Even the best developers produce one new bug for every four that they fix. Making multiple concurrent fixes, some of which might potentially interfere with each other, is not conducive to producing high-quality solutions.</p>
<p>Perhaps the final nail in the coffin of “shotgun debugging” is that many of the E&amp;C fixes made are small ones, often affecting only a few lines of code. These are made because they are the type of changes that look manageable without having to perform desk-checking or proper review.</p>
<p>Unfortunately, the literature shows that the chances of creating a bug significantly increase when making such small changes. Specifically, as the number of lines changed increases from one to five lines, the chance of making a bad change is high and increases. With more than five altered lines, the chance of making a bad change decreases, probably because the developer becomes more careful as the fix becomes larger.</p>
<p><strong>Bad Unit Testing with E&amp;C</strong></p>
<p>A developer edits code several times within a single run in order to run multiple unit tests on a procedure or component. For example, a program that executes an embedded SQL script sees the developer correcting, tuning, and re-executing the SQL script many times until he is happy that everything is working properly. The typical argument for this approach is that it is much faster to run these multiple edit-and-test cycles in one hit rather than having to restart the program every time a change is made.</p>
<p>There are several problems with this type of ad-hoc testing. The first is that any tests done in this manner are not going to be as comprehensive as a manual or automated unit test harness that has been implemented beforehand. It’s hard to invent several good unit tests on the fly, especially when the psychological mindset is aimed at making the code work rather than proving that the code doesn't work.</p>
<p>The temptation is always to fix the code in-flight when each test fails rather than running a test suite, collating the results, and then thinking about the fixes as a single, well-controlled patch to the program. Simultaneous mixing of the unit testing mindset with the quite different mindset of fixing code that fails the unit tests is very dangerous.</p>
<p>A second problem with this approach is that it makes it very difficult to perform unit regression testing on future versions of the code. Even if the developer could manage to remember the entire unit test suite that he had performed, repeating a set of interactive regression tests every time the code changes is very boring and therefore prone to mistakes.</p>
<p>Another trap that many developers fall into with E&amp;C in this context is changing code on both sides of the interface being tested. It is just too easy to make a change to the calling code that makes the interface being tested appear to work. What might actually be happening is that two errors, one on either side of the interface, could compensate for each other and result in the interface appearing to work.</p>
<p>Once again, the psychological need to get the code working can interfere with the unit tests being performed. In effect, this makes it easier for the developer to fool himself into believing that everything is working correctly through an artificial test case created by manipulating two sets of code.</p>
<p><strong>Good Debugging with E&amp;C</strong></p>
<p>One appropriate way of debugging with E&amp;C is when you find an obvious coding error, often while looking at something completely different, and change the code for an obvious fix. While it is a fine line between an “obviously correct” fix and a “subtly wrong” fix, most developers know when they've found a glaringly obvious problem. In this case, it can be good practice to fix the problem, test the fix immediately, and then proceed on your way with your original mission.</p>
<p>Another reasonable way of using E&amp;C is when you've found an error and managed to reproduce it successfully. The next step is often to reproduce the error in several different ways in order to learn more about it. E&amp;C can be very useful in allowing multiple code changes and tests during a single run in order to triangulate the bug and learn more about it. The proviso, of course, is that you must put the code back into its original state once you have completed your investigation.</p>
<p><strong>Good Unit Testing with E&amp;C</strong></p>
<p>E&amp;C can prove very useful when you're unit-testing a GUI. Although it’s still better to create a proper test harness if possible, this can be difficult to automate because you have to simulate a very unpredictable component (the end user), and also it’s difficult to validate the unit test results. For this reason, many developers prefer to test interactively, so I'll grant that this can be a reasonable use of E&amp;C.</p>
<p><strong>Good Prototyping with E&amp;C</strong></p>
<p>In this scenario, a developer makes multiple code changes during a single run in order to prototype, typically when investigating the behaviour of a class, a control, or some other component. With E&amp;C, it is much faster to perform this type of testing, and because it is only prototyping, there is much less danger of bugs running rampant. This scenario is one of the genuinely useful ways of using E&amp;C.</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20051224_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20051224_1.html</guid>
    <pubDate>Sat, 24 Dec 2005 18:00:04 +0000</pubDate>
</item>

<item>
    <title>Language wars</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p><a href="http://addressof.com/blog/">Cory Smith</a> gives me a forceful reminder of why I read his blog. In two entertaining entries, he first <a href="http://addressof.com/blog/archive/2005/12/07/9298.aspx">demolishes</a> <a href="http://thecodingmonkey.blogspot.com/2005/07/reason-458-why-visual-basicnet-sucks.html">Nick Schweitzer</a>, and then <a href="http://addressof.com/blog/archive/2005/12/07/9299.aspx">dances on the head</a> of <a href="http://blog.angrypets.com/2005/11/vbnet_sucks.html">Michael Campbell</a>. At least each of these victims had the grace to acknowledge (in the article comments) that he got it completely wrong.</p>
<p>Having been in the software industry for *cough* years, I've seen my fair share of&nbsp;language wars. If you dig a little deeper, there are 2 types of "religious war" commonly on show:</p>
<ul>
<li>The developer who promotes a <a href="http://www.paulgraham.com/icad.html">specific language as superior to the alternatives</a>.
</li>
<li>The developer who denigrates a <a href="http://petesbloggerama.blogspot.com/2005/09/sloppy-code-band-aid-code-and-quality.html">specific language as inferior to the alternatives</a>.
</li>
</ul>
<p>The first type is usually the result of something akin to falling in love. The developer tumbles head-over-heels for, say, French rather than English, and wants to share the wonders of French <strong>at</strong> every other developer within range. There's sometimes a full 6-pack in evidence, but always a completely lack of the plastic thingy to hold it all together.&nbsp;</p>
<p>A good example of the second type is the often savage attacks aimed at any random dialect of the Basic language. The real target is rarely the language actually under attack, but rather the culture and abilities of the developers who use that language. It's a classic tribal attitude, "them" versus "us", and often a fundamental culture clash. And it's usually the result of a profoundly immature view of the world, one that fails to recognise that software development is actually multiple disciplines and really benefits from having multiple cultures.</p>
<p>You know that a specific discussion is turning towards a religious war rather than genuine technical debate when you start to learn more about the mindset of the developer doing the debating than you learn about the languages under debate. People start to confuse the strength of their feeling for the strength of their argument, and often try to pass off personal value choices and cultural attachments as objective technical evaluations.</p>
<p>Look, folks, just grow up!</p>
<ul>
<li>Don't put too much value on any one specific language.
</li>
<li>Don't be elitist or dogmatic when it comes to programming languages.
</li>
<li>Do learn how to step back and be more objective.
</li>
<li><a href="http://www.paulgraham.com/bronze.html">Do realise that you aren't as intelligent as you think you are</a>.
</li>
<li>Do understand that <strong>every</strong> language will teach you new stuff about software development.
</li>
<li>Do find out what you can learn from other software development cultures.
</li>
</ul>
<p>Perhaps one of the real and lasting benefits of .NET is that it puts developers from several different cultures and backgrounds onto the same development platform, where hopefully we can all learn from each other.</p>
<p><strong>UPDATED</strong>: As I don't have blog comments, Nick Schweitzer emailed me to point out that he has an <a href="http://schweitn.blogspot.com/2005/02/religion-in-software.html">older blog entry</a>&nbsp;which shows a more well-rounded view of the world than indicated by his entry mentioned above:</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
<p><em>When you get down to brass tacks however, being a religious software advocate is a really poor thing to do. I much prefer to be agnostic over my software choices. The simple fact is that the software you use to create something is not the goal. Software is just a medium to get somewhere else. People who get deeply religious about their software tend to be more excited about how they're going to do something, and not about what they're trying to accomplish.</em></p>
</blockquote>
<p>And it's Xmas, so I've toned-down my language slightly :-)</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20051214_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20051214_1.html</guid>
    <pubDate>Wed, 14 Dec 2005 02:20:04 +0000</pubDate>
</item>

<item>
    <title>Debugging a .NET Windows service within the IDE</title>
    <dc:creator>Mark Pearce</dc:creator>    
    <description><![CDATA[
<p>The Visual Studio documentation insists that you must install your Windows service before you can run it and debug it. During development of a service, it can be a real pain to have to uninstall the previous version and then re-install a new version every time you want to test a change to your code. Fortunately, you can set-up your service so that when using the <em>Debug</em> configuration it operates as a standard executable, and when using the <em>Release</em> configuration it reverts back to being a normal Windows service. This allows you to debug your service from within the Visual Studio IDE, without any messy installing and un-installing.</p>
<p>To do this, you need to emulate what the Service Control Manager (SCM) does when it starts your service — in other words, invoke your service’s <em>OnStart</em> method. In C#, this looks like:</p>
<p><img height="188" alt="" src="../../images/DebugServiceCSharp.png" width="581" border="0" /></p>
<p>And in VB, this looks like:</p>
<p><img height="218" alt="" src="../../images/DebugServiceVB.png" width="581" border="0" /></p>
<p>This approach also allows you to debug your <em>Main</em> procedure and the code in your <em>OnStart</em> method. This is otherwise rather tricky because these two procedures have already been executed (during service startup) before you get a chance to attach to the service process for debugging. This debugging trick has the additional benefit that if you want to debug other service commands such as <em>Stop</em> or <em>Pause</em>, you can just invoke the appropriate method directly from the IDE's <em>Immediate</em> window.</p>
<p><strong>UPDATED</strong>: Len Holgate has a <a href="http://www.lenholgate.com/archives/000584.html">more sophisticated version</a> of this idea, where he completely decouples the service from the SCM.</p>]]></description>
    <link>http://sleeksoft.co.uk/public/techblog/articles/20051128_1.html</link>
    <guid>http://sleeksoft.co.uk/public/techblog/articles/20051128_1.html</guid>
    <pubDate>Mon, 28 Nov 2005 01:05:04 +0000</pubDate>
</item>


    </channel>
</rss>
