Friday, March 31, 2006

Ye Goode Olde Dayes

Check out this most excellent series of promotional computer images from the ’60s and ’70s, back when taking a photo of a computer required, as the author put it, “A wide-angle lens. And a woman in a thigh-high skirt.”

Compu-promo (lileks.com)

Tuesday, March 28, 2006

English > L337 Translator (ColdFusion)

Update: A demo is available on my new blog:

Leet Translator.

Apparently I had time to waste writing a L337 hax0r translator in ColdFusion (okay, so it only took about 15 minutes). I figured I might as well pass it on...the output is different every time & it's reasonably badass. I'll try to put it on a publically accessible ColdFusion server or rewrite it in JavaScript within a few days so you can see it in action.

<h1>L337 Translator!!</h1>

<!--- If form submitted with value --->
<cfif isDefined("Form.message") AND len(Form.message)>
   <cfset Variables.alphabet = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z" />
   <cfset Variables.cipher = "4,8,[,),3,ƒ,6,##,1,_|,X,1,|v|,|\|,0,|*,()_,2,5,+,(_),\/,\/\/,×,`/,2" />
   <cfset Variables.output = "" />
  
   <!--- Loop over received text, one character at a time --->
   <cfloop index="i" from="1" to="#len(Form.message)#">
       <!--- Gives 50% odds --->
       <cfif round(rand())>
           <!--- Add leet version of character to output --->
           <cfset Variables.output = Variables.output & replaceList(lCase(mid(Form.message, i, 1)), Variables.alphabet, Variables.cipher) />
       <cfelse>
           <cfif round(rand())>
               <!--- Add uppercase version of character to output --->
               <cfset Variables.output = Variables.output & uCase(mid(Form.message, i, 1)) />
           <cfelse>
               <!--- Add unviolated character to output --->
               <cfset Variables.output = Variables.output & mid(Form.message, i, 1) />
           </cfif>
       </cfif>
   </cfloop>
  
   <cfif round(rand())>
       <cfset Variables.suffixes = "w00t!,d00d!,pwnd!,!!!11!one!,teh l337!,hax0r!,sux0rs!" />
       <!--- Append random suffix from list to output --->
       <cfset Variables.output = Variables.output & " " & listGetAt(Variables.suffixes, int(listLen(Variables.suffixes) * rand()) + 1) />
   </cfif>
  
  
   <h2>Original Text:</h2>
   <div style="background:#d2e2ff; border:2px solid #369; padding:0 10px;">
       <p><cfoutput>#paragraphFormat(Form.message)#</cfoutput></p>
   </div>
  
   <h2>Translation:</h2>
   <div style="color:#0f0; background:#000; border:2px solid #0f0; padding:0 10px;">
       <p><cfoutput>#paragraphFormat(Variables.output)#</cfoutput></p>
   </div>
</cfif>


<form action="<cfoutput>#CGI.SCRIPT_NAME#</cfoutput>" method="post" style="margin-top:20px;">
   <cfparam name="Form.message" default="Enter text to translate" />
   <textarea name="message" style="width:300px; height:75px;"><cfoutput>#Form.message#</cfoutput></textarea>
   <br/><br/>
   <input type="submit"/>
</form>

Monday, March 27, 2006

God’s Pet Peeves

So, I was flipping through a Bible & came to Leviticus 11, with its variety of swimming, walking, crawling & flapping abominations. ’Twas an interesting re-read.

Some highlights:

We aren’t actually supposed to be eating ostriches. I was a bit surprised by that, as I didn't think ostriches were too bountiful in Hebrew lands in those days, so much so that there were ostrich-avoidance rules in place.

God is really peeved at “unclean” animals, & takes his time calling them names like abomination & defiler.

Apparently no one noticed that four-footed insects are mighty scarce, & that laws banning their consumption (see here…it’s good stuff) are a bit superfluous. Also, there is a distinction made between jumping & non-jumping bugs. Some of the former are yummy, while the latter are abominations without exception (so if mom tries to sneak one into your dinner, pick it out, feed it to the dog & then stone her to death).

Special mention is made that you aught not to “boil young goats in their mother’s milk” (Deut 14:21).

And let us never forget that god hates figs & shrimp.

Pondering further, I’d bet god is a shrimp lover too, like me. Think about it, he fools us into thinking they’re nasty so we don’t eat them & they can flourish in the ocean … Thousands of years of Christianity, Judaism & Islam might boil down to nothing more than an elaborate shrimp-saving conspiracy.

Sunday, March 26, 2006

Regex Recursion Without Balancing Groups (Matching Nested Constructs)

Update: Please view the updated version of this post on my new blog:

Regex Recursion (Matching Nested Constructs).

Some dude posed the following problem on a regex advice forum I visit every once in a while…

He was trying to scrape BibTeX entries from Web pages using JavaScript (from within a Firefox extension).

A single BibTeX entry looks roughly like this:

@resourceType{
    field1 = value,
    field2 = "value in quotation marks",
    field3 = "value in quotation marks, with {brackets} in the value",
    field4 = {brackets}
}

The resident regex experts were quick to point out that regexes are only capable of recursion through the use of “Balancing Groups”, a feature supported exclusively by .NET (see the chapter on .NETPDF icon in Mastering Regular Expressions).

Basically, searches requiring recursion have typically been the domain of parsers, not regexes. The problem in this particular case lies in how you distinguish between the last closing bracket of the @resourceType{…} block and any of the inner brackets. The only difference between the last closing bracket and the inner brackets is that they are logically linked (i.e. they form an open–close pair). This logic is impossible to implement by simple lookaround assertion.

Still, given that there was only one level of recursion, I figured it was possible. Here's the solution offered, which works just fine with JavaScript (it doesn't use any advanced regex features, actually):

@[^{]+{(?:[^{}]|{[^{}]*})*}

(Note: I've used RegexBuddy's formatting style to color it.)

This, however, works only if:

  • braces are always balanced, and
  • the level of brace nesting is no more than one.

Still, regex users might find the logic interesting, and better yet, find some actual use for it.

For those unfamiliar with regular expressions or who are looking for a good tutorial, see www.regular-expressions.info.

And feel free to post your own regex problems in the comments if you think I might be able to help.

Edit: This logic is easy to extend to support more levels of recursion, as long as you know in advance the maximum levels of recursion you need to support. Here's a simple example of matching HTML elements and their contents (yes, I know, element names can't start with a number, and I'm not supporting attributes or singleton elements, but that would make the regexes longer and this is only supposed to be for demonstration purposes):

No recursion:
<([a-z\d]+)>.*?</\1>
Up to one level of recursion:
<([a-z\d]+)>(?:<\1>.*?</\1>|.)*?</\1>
Up to two levels of recursion:
<([a-z\d]+)>(?:<\1>(?:<\1>.*?</\1>|.)*?</\1>|.)*?</\1>
And so on...

Edit 2 (2007-04-04): I've since learned that, in addition to using .NET's balancing groups, true recursion is possible in Perl 5.6+ using Perl's qr// operator to compile a regex as a variable, used together with the little known (??{ }) operator which instructs Perl that when compiling the regex it should not interpolate the encapsulated code until it's actually used. See the article Regexp Power by Simon Cozens for details.

Edit 3 (2007-04-10): Here's another Perl-specific way of achieving true recursion, this time supported by Perl 5.005+: Perl Regular Expression Mastery by Mark Jason Dominus: Slide 83.

Edit 4 (2007-04-16): Yet another method for recursion, this time supported by Perl 5.6+, PCRE, and Python: the special item (?R). See pcre.org/pcre.txt for details.

Brokeback to the Future

Funny shit: Brokeback to the Future (youtube.com).

I never realized how different you could make a movie seem just by adding a mournful guitar track in the background.

Saturday, March 25, 2006

The SNAFU Principle

A priceless bit from The New Hacker’s Dictionary

SNAFU principle /sna'foo prin'si-pl/ /n./

[from a WWII Army acronym for ‘Situation Normal, All Fucked Up’] “True communication is possible only between equals, because inferiors are more consistently rewarded for telling their superiors pleasant lies than for telling the truth.” — a central tenet of Discordianism, often invoked by hackers to explain why authoritarian hierarchies screw up so reliably and systematically. The effect of the SNAFU principle is a progressive disconnection of decision-makers from reality. This lightly adapted version of a fable dating back to the early 1960s illustrates the phenomenon perfectly:

In the beginning was the plan,
and then the specification;
And the plan was without form,
and the specification was void.

And darkness was on the faces of the implementors thereof;
And they spake unto their leader, saying:
"It is a crock of shit,
and smells as of a sewer."

And the leader took pity on them,
and spoke to the project leader:
"It is a crock of excrement,
and none may abide the odor thereof."

And the project leader
spake unto his section head, saying:
"It is a container of excrement,
and it is very strong, such that none may abide it."

The section head then hurried to his department manager,
and informed him thus:
"It is a vessel of fertilizer,
and none may abide its strength."

The department manager carried these words to his general manager,
and spoke unto him, saying:
"It containeth that which aideth the growth of plants,
and it is very strong."

And so it was that the general manager rejoiced
and delivered the good news unto the Vice President.
"It promoteth growth,
and it is very powerful."

The Vice President rushed to the President's side,
and joyously exclaimed:
"This powerful new software product
will promote the growth of the company!"

And the President looked upon the product,
and saw that it was very good.

After the subsequent and inevitable disaster, the suits protect themselves by saying “I was misinformed!”, and the implementors are demoted or fired.