Adding Game Aspects to Boring Software

DES Algorithm Implementation

Implementing DES took me way longer (4 days) than it should have (4 hours). The reason? I was basing my understanding of how the algorithm works on two diagrams. Needless to say, they didn’t paint the whole picture…nor did they doodle it!

Anyway, here’s the python code for it. I hope it helps a poor soul out there someday.

Requirements: Python 2.6 and BitString library

Here’s a download that includes BitString: zip DES-python.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#!/usr/bin/python2.6
 
# Description: Can encrypt or decrypt a block of HEX plaintext (64 bits).
# Author: Gezim Hoxha
# License: GPL 3 
 
from bitstring import BitString
 
IK = [
       1,   2,   3,   4,   5,   6,   7,   8,
       9,  10,  11,  12,  13,  14,  15,  16,  
      17,  18,  19,  20,  21,  22,  23,  24,  
      25,  26,  27,  28,  29,  30,  31,  32,  
      33,  34,  35,  36,  37,  38,  39,  40,  
      41,  42,  43,  44,  45,  46,  47,  48,  
      49,  50,  51,  52,  53,  54,  55,  56,  
      57,  58,  59,  60,  61,  62,  63,  64
      ]
 
IKNOPAR = [
       1,   2,   3,   4,   5,   6,   7,
       9,  10,  11,  12,  13,  14,  15,  
      17,  18,  19,  20,  21,  22,  23,  
      25,  26,  27,  28,  29,  30,  31,  
      33,  34,  35,  36,  37,  38,  39,  
      41,  42,  43,  44,  45,  46,  47,  
      49,  50,  51,  52,  53,  54,  55,  
      57,  58,  59,  60,  61,  62,  63
      ]
 
 
IP = [
      58, 50, 42, 34, 26, 18, 10,  2,
      60, 52, 44, 36, 28, 20, 12,  4,
      62, 54, 46, 38, 30, 22, 14,  6,
      64, 56, 48, 40, 32, 24, 16,  8,
      57, 49, 41, 33, 25, 17,  9,  1,
      59, 51, 43, 35, 27, 19, 11,  3,
      61, 53, 45, 37, 29, 21, 13,  5,
      63, 55, 47, 39, 31, 23, 15,  7
      ]
 
RIP = [
       40,  8, 48, 16, 56, 24, 64, 32,
       39,  7, 47, 15, 55, 23, 63, 31,
       38,  6, 46, 14, 54, 22, 62, 30,
       37,  5, 45, 13, 53, 21, 61, 29,
       36,  4, 44, 12, 52, 20, 60, 28,
       35,  3, 43, 11, 51, 19, 59, 27,
       34,  2, 42, 10, 50, 18, 58, 26,
       33,  1, 41,  9, 49, 17, 57, 25
       ]
 
PC1 = [
       57, 49, 41, 33, 25, 17,  9,
        1, 58, 50, 42, 34, 26, 18,
       10,  2, 59, 51, 43, 35, 27,
       19, 11,  3, 60, 52, 44, 36,
       63, 55, 47, 39, 31, 23, 15,
        7, 62, 54, 46, 38, 30, 22,
       14,  6, 61, 53, 45, 37, 29,
       21, 13,  5, 28, 20, 12,  4
       ]
 
PC2 = [
       14, 17, 11, 24,  1,  5,  3, 28,
       15,  6, 21, 10, 23, 19, 12,  4,
       26,  8, 16,  7, 27, 20, 13,  2,
       41, 52, 31, 37, 47, 55, 30, 40,
       51, 45, 33, 48, 44, 49, 39, 56,
       34, 53, 46, 42, 50, 36, 29, 32
       ]
 
E = [
     32,  1,  2,  3,  4,  5,
      4,  5,  6,  7,  8,  9,
      8,  9, 10, 11, 12, 13,
     12, 13, 14, 15, 16, 17,
     16, 17, 18, 19, 20, 21,
     20, 21, 22, 23, 24, 25,
     24, 25, 26, 27, 28, 29,
     28, 29, 30, 31, 32,  1,
     ]
 
P = [
     16,  7, 20, 21, 29, 12, 28, 17,
      1, 15, 23, 26,  5, 18, 31, 10,
      2,  8, 24, 14, 32, 27,  3,  9,
     19, 13, 30,  6, 22, 11,  4, 25
     ]
 
SBoxes = [
        #s1
         [
         [14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7],
         [0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8],
         [4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0],
         [15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13],
         ],
 
         #s2
         [
          [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],
          [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],
          [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],
          [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]
          ],
 
         #s3
          [
          [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],
          [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],
          [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],
          [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12], 
           ],
 
          #s4
          [
           [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],
           [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],
           [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],
           [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]
           ],
 
          #s5
          [
           [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],
           [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],
           [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],
           [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3],
           ],
 
          #s6
          [
           [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],
           [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],
           [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],
           [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]
           ],
 
          #s7
          [
           [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],
           [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],
           [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],
           [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]
           ],
 
          #s8
          [
           [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],
           [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],
           [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],
           [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]
           ]
        ]
 
BS = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
 
def map(input, table):
    retIP = BitString('0b0')
    for i in range(len(table)):
        if i == 0:
            retIP[i] = input[table[i]-1]
        else:
            retIP.insert(input[table[i]-1], i)
    return retIP
 
def leftCircShift(bsc, numbits=1):
    bs = BitString(bsc)
    for bit in range(numbits):
        bs.insert(bs[0], bs.length)
        bs.deletebits(1,0)
    return bs
 
def sboxit(x, s):
    r = x[0] + x[x.length-1]
    c = x[1:5]
 
    rint = int(r.bin, 2)
    cint = int(c.bin, 2)
    inty = s[rint][cint]
    b = BitString(bin(inty))
    while b.length < 4:
        b.insert('0b0',0)
    return b
 
def keys(k):
    key = map(k, PC1)
    [c, d] = key.cut(28)
 
    retk = []
    for i in range(16):
        c = leftCircShift(c, BS[i])
        d = leftCircShift(d, BS[i])
        key = c + d
        key = map(key, PC2)
        retk.append(key)
 
    return retk
 
 
# 0123456789ABCDEF (plaintext)
# 85e813540f0ab405 (ecrypted)
# 133457799BBCDFF1 (key)
 
if __name__ == "__main__":
 
    op = raw_input("e or d (encrypt or decrypt):")
    if op == 'd':
        plaintext = raw_input("Encrypted text:")
    else:
        plaintext = raw_input("Plaintext:")
    key = raw_input("Key:")
 
    key = BitString('0x%s' % key)
    bsplaintext = BitString('0x%s' % plaintext)
    bsplaintextip20 = map(bsplaintext, IP)
    [l, r] = bsplaintextip20.cut(32)
    print "L0: %s" % l.bin
    print "R0: %s" % r.bin
 
    mek = keys(key)
    if op == 'd':
        mek.reverse()
 
    for rawRound in range(16):
        key = mek[rawRound]
        roundNoHuman = rawRound + 1
        roundNo = rawRound
        print "==========Round %d===================" % (roundNoHuman)
        er = map(r, E)
        print "E(R%d) = %s" % (roundNo, er.bin)
        print "K%d = %s" % (roundNoHuman, key.bin)
        funk = er ^ key
        print "E(R%d) ^ K%d = %s" % (roundNo, roundNoHuman, funk.bin)
        [x1, x2, x3, x4, x5, x6, x7, x8] = funk.cut(6)
        stotal = sboxit(x1,SBoxes[0]) + sboxit(x2,SBoxes[1]) + sboxit(x3,SBoxes[2]) \
            + sboxit(x4,SBoxes[3]) + sboxit(x5,SBoxes[4]) + sboxit(x6,SBoxes[5]) \
            + sboxit(x7,SBoxes[6]) + sboxit(x8,SBoxes[7])
        print "S-box output  %s" % stotal.bin
        frk = map(stotal, P)
        print "f(R%d,K%d) = %s" % (roundNo, roundNoHuman, frk.bin)
        ltmp = r
        r = l ^ frk
        l = ltmp
        print "L%d=R%d = %s" % (roundNoHuman+1, roundNoHuman, r.bin)
 
    crypt = map(r+l, RIP)
    print crypt

Impossible, eh?!

Impossible?!

Impossible?!

Me miss dem alreddy

291550.full

Again, if you’re not familiar with the crocs, have a look here.

Appreciate Your Customers

The Struggle

I’ve been struggling to come up with a theme for this blog; to write something that people will want to read. That is one of the reasons why I started using “Software and business” as a slogan. What I was trying to do is copy the success of Joel Spolsky; he talks about software and business, so I should do the same, I thought.

Well, I’m going to digress, just a tad.

The Epiphany

Just now, that’s right, at 4 a.m. in the morning, I had this stroke of insight. As a customer, I feel that I get mistreated by companies, sometimes and this is natural. Depending on the offense, I’ll stop doing business with that particular company. Now, as a self proclaimed, “future entrepreneur”, it’s only wise that I learn from the mistakes of the others and treat my customers right. With that in mind, I’m going to write posts that speak to the future me, so I will not forget these lessons, God Willing. They shall be tagged #notetoself.

Note to Self: Appreciate Your Customers

In every relationship, it’s a natural tendency to want to be appreciated. After all, who wants to be useless? That is especially important in a loyal relationship (including business-to-customer).
First, I think, we should answer the question as to what it means to appreciate your customers. While I might not know what appreciation exactly entails, I do know that it entails more than just claiming to appreciate. Although I’m often told that my business is appreciated, I certainly don’t feel appreciated when I have to wait for extended periods for a business to serve me, be it on the phone or person. As a recent example, I was trying to phone a certain floral company (PinkLotus) to ensure the online order I had placed had gone through and to give some specific delivery instructions. I called at least three times. The first two times the phone must have rung for a good twenty times; no one answered. I seriously wondered if the site was just a scam with no real presence! The third time, after it rang for a good while, someone picked up, finally.

Another bad example of customer appreciation is my experience with Telus. A few years back, I called Telus to cancel my internet connection as I was switching to the competition. I got transferred to the retention centre, and after telling the agent that I was about to go with the competition because it’s cheaper, he offered a discount! Excuse me?! When I was a loyal customer, you never cared, but now that I’m leaving, you care enough to offer me a discount?! It never occurred to you to say, “hey, Gezim has been such an awesome customer, let’s show him we appreciate his business!” Last minute retention doesn’t show customer appreciation.

That was years ago. What reminded me of all this was a similar incident that happened yesterday. I had been a customer of DiscoverULife for almost a year. The price I was paying for the coaching service was not cheap. Yesterday, I told my coach that I want to cancel my subscription with them because 1) I couldn’t afford it, 2) I didn’t find it effective*. Like in the Telus example, he offered a special discount because he appreciated our relationship, in addition, he said he’d offer the same discount to two addition people which I could refer! ARE YOU KIDDING?! Up to now, you milked me for all I was worth, and now you offer a special discount for me and two friends?!

Anyway,

Dear future entrepreneur, show your loyal customers that you appreciate their business. If you know how to show them that you appreciate them, do it. If you don’t, something like this might work:

  • Offer a special discount,
  • Send a gift, or
  • Buy them dinner.

If you don’t think that either of those options are appropriate, simply tell them, “Hey Bob, I appreciate your business, what can we do to make you feel appreciated?” Careful though, you don’t want to ask that question unless you can act upon the answer.

* I certainly benefitted from the coaching, but not as much as I would have liked. This is my own fault.

Who eediot NOW?!

Pearls Before Swine comic

Pearls Before Swine comic

If you’ve never read Pearls Before Swine before, get a feeling for the crocs, first.

Safari 4, great until it CRASHES

I admit, I should have written this article from good will and to praise Apple for their work on Safari 4, but alas it didn’t happen, until now.

Safari just crashed on me, the best thing about it, it doesn’t even seem to know that it crashed and it won’t save any tabs or windows you had open, no sir!
safari4

I think Apple is probably relying on the awesome History feature in the browser. Don’t get me wrong, I cannot emphasis how useful the new History feature is in Safari 4, but perhaps, just perhaps it’s not enough of a backup to recover from. For instance, although I can go back in history and see what web pages I have opened, problem occurs if you opened a few tabs and windows a long time ago and just never got to reading them. In this use case, to use the history to recover is, well, not doable especially since you might not even know what those other tabs and windows contained. Anyway, I should probably stop ranting now!

It’s unfortunate that we prefer to complain about something more than praise them. This post would have been much better if I wasn’t a little ticked off!

On an unrelated note, WordPress rocks! Go WordPress.

Google Tsunami

Google is just being humble by calling one of the latest projects Google Wave, I think Google Tsunami would be a better fit.

This technology, I believe has potential to be the next facebook. Often times when a new, brilliant, idea is introduced, you think “why didn’t I think of that” or “I should have seen that coming”. Well, I think this is one of those moments.

I think what’s imperative to Google Wave is how open Google plans to make it. This is just !

Just Brilliant — Pomegranate NS08

For details visit the Pomegranate website. Be sure to checkout the Release Date.

The Chinook Entrepreneur Challenge

The Challenge

Last night, I attended the first, introductory, seminar hosted by The Chinook Entrepreneur Challenge.

The Chinook Entrepreneur Challenge is the first business planning competition of its kind in Canada to be held in a non-metropolitan setting.

The challenge is designed and targeted toward individuals, new and existing businesses (agriculture and non-agriculture), and post-secondary students (college and university) who have a sustainable business idea.

Climbing businessman

Basically, The Chinook Entrepreneur Challenge offers participants eight free seminars to get help on business plan preparation.

The Prize

After the seminars are over, you can enter your business plan for the actual competition. The prizes for the winners are as follows:

  1. 1st place = $15,000
  2. 2nd place = $ 7,500
Money, money, money. Money!

Money, money, money. Money!

In addition The Chinook Entrepreneur Challenge can find mentors for participants (not just the winners) to assist them in launching and running the business.

My friend, Dennis Kamitomo, informed me about this competition and I joined right away. I want to write a concrete business plan for GizmoBooks and win $15,000!

Not sure if you can still join, but I would try! You can register here and also checkout their blog.

The Best Part

The best part of yesterday’s seminar was at the end when the seminar was over. How so? Well, talking to Craig Milner, a professor at the U of L — saying “a professor” doesn’t do Craig justice because he’s an amazing professor — and owner of East Side Mario’s who shared his experience and expertise at the seminar, I found out that he had heard about GizmoBooks and had seen my ad on the student newspaper, The Meliorist! Then Daniel Feiguth, the business analyst from Community Futures Lethbridge jumped in and said that he had heard of GizmoBooks and needed to sell some books! I was ecstatic!

Anyway, I’ll post the ‘racy’ ad here soon as well as the press release that got published in the Meliorist.