Off to Alicante for Paul’s stag do tomorrow, fully expecting to become everything (well not everything) I despise for a few days.
This nice index card from Jessica Hagy got me thinking about all the wonderful people we’re likely to meet…

Off to Alicante for Paul’s stag do tomorrow, fully expecting to become everything (well not everything) I despise for a few days.
This nice index card from Jessica Hagy got me thinking about all the wonderful people we’re likely to meet…

Have been looking around at the unsecured loan market in recent days following my decision to buy a new(ish) car.
Sainsbury’s bank seemed a good option – underwritten (or whatever the term is) by HBOS, 7.9% interest. Not too shabby, although we’ll probably come back and look at the interest rate in a few years and laugh/cry.
Anyway, I proceeded with applying for a loan only to be told that to “courier” the cheque to my house (no direct transfers here…) would cost £49!!
The worst thing is this isn’t even a same day whizz it straight over to you bike messenger type courier, it would be two days as I was applying after 3pm.
I’m in the wrong game. Slow-ass “courier” service only £30 per letter here I come!
Just got this email from the Warwick Business School alumni relations office:
Dear Friend
World Class provides a framework for operational excellence, increased effectiveness and efficiency, enabling you to exploit your organisation's unique capabilities to deliver competitive advantage.
Seriously, that was the opening line as if I’m supposed to know what the hell they’re talking about.
It’s good to know that the tradition of clear and concise explanations lives on at Warwick.
I’m so glad I went to a World Class business school…
Private Function swapNibble(ByVal Octet As String) As String
If Octet.Length <> 2 Then
Throw New Exception("swapNibble expects string of length 2")
End If
Return String.Concat(Octet.Substring(1, 1), Octet.Substring(0, 1))
End Function
The following function will convert a 8bit encoded string into it's 7 bit GSM 03.38 equivalent. Some code samples on the net simply use ASCII characters and ‘fix’ them by replacing "0x00" / Chr(0) with an @ / Chr(64) which will work for all standard letters and some symbols as the GSM 7 bit alphabet has a 1-1 mapping with unicode for these, however it won't work for other special characters. Using the GSMCharMap class also included below solves this.
Decode function:
Private Shared Function octetByteArray(ByVal str As String) As Byte()
Dim b As New List(Of Byte)
For i As Integer = 0 To CInt((str.Length)) - 1 Step 2
b.Add(Convert.ToByte(String.Format("0x{0}", str.Substring(i, 2)), 16))
Next
Return b.ToArray
End Function
Shared Function BinaryToInt(ByVal Binary As String) As Integer
Dim Result As Integer = 0
For i As Integer = 0 To Binary.Length - 1
Result += CInt(CInt(Binary.Substring(Binary.Length - i - 1, 1)) * 2 ^ i)
Next
Return Result
End Function
Public Shared Function convert8bitTo7bit(ByVal str8bit As String) As String
Dim byte8() As Byte = octetByteArray(str8bit)
Dim revBinaryString As String = String.Empty
Dim sb8 As New StringBuilder
' Append in reverse to simply pull 8th bit out in next loop
For iByte As Integer = byte8.Length - 1 To 0 Step -1
revBinaryString = revBinaryString & Convert.ToString(byte8(iByte), 2).PadLeft(8, CChar("0"))
Next
Dim charCount7bit As Integer = CInt(Math.Floor(CDbl(str8bit.Length / 2 * 8 / 7)))
Dim isChar27 As Boolean = False
For i As Integer = 1 To charCount7bit
' Convert 7 bits of binary to integer
Dim char7 As Integer = BinaryToInt(revBinaryString.Substring(revBinaryString.Length - i * 7, 7))
Dim map As New GSMCharMap
If Not isChar27 Then
If char7 <> 27 Then
sb8.Append(map.getChar(char7))
Else
isChar27 = True
End If
Else
sb8.Append(map.getChar27(char7))
isChar27 = False
End If
Next
Return sb8.ToString
End Function
GSMCharMap class
Public Class GSMCharMap
Private m_map(128) As Char
Private m_27map(128) As Char
Public Sub New()
m_map(0) = Chr(64) '@
m_map(1) = Chr(163) '£
m_map(2) = Chr(36) '$
m_map(3) = Chr(165) '¥
m_map(4) = Chr(232) 'è
m_map(5) = Chr(233) 'é
m_map(6) = Chr(249) 'ù
m_map(7) = Chr(236) 'ì
m_map(8) = Chr(242) 'ò
m_map(9) = Chr(199) 'Ç
m_map(10) = Chr(10) 'Line feed
m_map(11) = Chr(216) 'Ø
m_map(12) = Chr(248) 'ø
m_map(13) = Chr(13) 'Carriage return
m_map(14) = Chr(197) 'Å
m_map(15) = Chr(229) 'å
m_map(16) = CChar("Δ") 'Δ Capital greek delta, not in Unicode
m_map(17) = Chr(95) '_
m_map(18) = CChar("Φ") 'Φ Capital greek phi, not in Unicode
m_map(19) = CChar("Γ") 'Γ Capital greek gamma, not in Unicode
m_map(20) = CChar("Λ") 'Λ Capital greek lambda, not in Unicode
m_map(21) = CChar("Ω") 'Ω Capital greek omega, not in Unicode
m_map(22) = CChar("Π") 'Π Capital greek pi, not in Unicode
m_map(23) = CChar("Ψ") 'Ψ Capital greek psi, not in Unicode
m_map(24) = CChar("Σ") 'Σ Capital greek sigma, not in Unicode
m_map(25) = CChar("Θ") 'Θ Capital greek theta, not in Unicode
m_map(26) = CChar("Ξ") 'Ξ Capital greek xi, not in Unicode
m_map(27) = Chr(10) 'Escape to map27 list
m_27map(10) = Chr(12) ' Form feed
m_27map(20) = Chr(94) ' ^
m_27map(40) = Chr(123) '{
m_27map(41) = Chr(125) '}
m_27map(47) = Chr(92) '\
m_27map(60) = Chr(91) ' [
m_27map(61) = Chr(126) '~
m_27map(62) = Chr(93) ' ]
m_27map(64) = Chr(124) ' |
m_27map(101) = CChar("€") '€ Euro sign
m_map(28) = Chr(198) 'Æ
m_map(29) = Chr(230) 'æ
m_map(30) = Chr(223) ' ß
m_map(31) = Chr(201) ' É
m_map(32) = Chr(32) '
m_map(33) = Chr(33) ' !
m_map(34) = Chr(34) ' "
m_map(35) = Chr(35) ' #
m_map(36) = CChar("¤") '¤ currency sign
m_map(37) = Chr(37) ' %
m_map(38) = Chr(38) ' &
m_map(39) = Chr(39) ' '
m_map(40) = Chr(40) ' (
m_map(41) = Chr(41) ' )
m_map(42) = Chr(42) ' *
m_map(43) = Chr(43) ' +
m_map(44) = Chr(44) ' ,
m_map(45) = Chr(45) ' -
m_map(46) = Chr(46) ' .
m_map(47) = Chr(47) ' /
m_map(48) = Chr(48) ' 0
m_map(49) = Chr(49) ' 1
m_map(50) = Chr(50) ' 2
m_map(51) = Chr(51) ' 3
m_map(52) = Chr(52) ' 4
m_map(53) = Chr(53) ' 5
m_map(54) = Chr(54) ' 6
m_map(55) = Chr(55) ' 7
m_map(56) = Chr(56) ' 8
m_map(57) = Chr(57) ' 9
m_map(58) = Chr(58) ' :
m_map(59) = Chr(59) ' ;
m_map(60) = Chr(60) ' <
m_map(61) = Chr(61) ' =
m_map(62) = Chr(62) ' >
m_map(63) = Chr(63) ' ?
m_map(64) = Chr(161) ' ¡
m_map(65) = Chr(65) ' A
m_map(66) = Chr(66) ' B
m_map(67) = Chr(67) ' C
m_map(68) = Chr(68) ' D
m_map(69) = Chr(69) ' E
m_map(70) = Chr(70) ' F
m_map(71) = Chr(71) ' G
m_map(72) = Chr(72) ' H
m_map(73) = Chr(73) ' I
m_map(74) = Chr(74) ' J
m_map(75) = Chr(75) ' K
m_map(76) = Chr(76) ' L
m_map(77) = Chr(77) ' M
m_map(78) = Chr(78) ' N
m_map(79) = Chr(79) ' O
m_map(80) = Chr(80) ' P
m_map(81) = Chr(81) ' Q
m_map(82) = Chr(82) ' R
m_map(83) = Chr(83) ' S
m_map(84) = Chr(84) ' T
m_map(85) = Chr(85) ' U
m_map(86) = Chr(86) ' V
m_map(87) = Chr(87) ' W
m_map(88) = Chr(88) ' X
m_map(89) = Chr(89) ' Y
m_map(90) = Chr(90) ' Z
m_map(91) = Chr(196) ' Ä
m_map(92) = Chr(214) ' Ö
m_map(93) = Chr(209) ' Ñ
m_map(94) = Chr(220) ' Ü
m_map(95) = Chr(167) ' §
m_map(96) = Chr(191) ' ¿
m_map(97) = Chr(97) ' a
m_map(98) = Chr(98) ' b
m_map(99) = Chr(99) ' c
m_map(100) = Chr(100) ' d
m_map(101) = Chr(101) ' e
m_map(102) = Chr(102) ' f
m_map(103) = Chr(103) ' g
m_map(104) = Chr(104) ' h
m_map(105) = Chr(105) ' i
m_map(106) = Chr(106) ' j
m_map(107) = Chr(107) ' k
m_map(108) = Chr(108) ' l
m_map(109) = Chr(109) ' m
m_map(110) = Chr(110) ' n
m_map(111) = Chr(111) ' o
m_map(112) = Chr(112) ' p
m_map(113) = Chr(113) ' q
m_map(114) = Chr(114) ' r
m_map(115) = Chr(115) ' s
m_map(116) = Chr(116) ' t
m_map(117) = Chr(117) ' u
m_map(118) = Chr(118) ' v
m_map(119) = Chr(119) ' w
m_map(120) = Chr(120) ' x
m_map(121) = Chr(121) ' y
m_map(122) = Chr(122) ' z
m_map(123) = Chr(228) ' ä
m_map(124) = Chr(246) ' ö
m_map(125) = Chr(241) ' ñ
m_map(126) = Chr(252) ' ü
m_map(127) = Chr(224) ' à
End Sub
Public Function getChar(ByVal index As Integer) As Char
If index = 27 Then
Throw New ApplicationException("Char 27 maps to extended character table and cannot be accessed directly")
End If
Return m_map(index)
End Function
Public Function getChar27(ByVal index As Integer) As Char
Return m_27map(index)
End Function
End Class
Any questions re: decoding SMS messages otherwise, just ask, there’s not a lot of easy to find info out there so I may do a follow up post.
Lars Pettersson has a great SMS resource over at www.dreamfabric.com/sms/ which is worth checking out too.