willichan Posted October 26, 2010 Share Posted October 26, 2010 (edited) Back in July, I was working with my Webelo Scouts, discussing things to make with wood. One of them described an Enigma Machine his uncle had built using wood and thumbtacks. Everyone was intrigued, and wanted to know more about the enigma machine. As part of a follow-up, I wrote the following UDF to demonstrate the principles. Please feel free to use this in your scripts, or for demonstration, ... or for just plain curiosity.I realize the comments are sparse, so if you have any questions, feel free to let me know.----Edit----By using a passkey to seed SRandom(), I eliminate the need to store details on each wheel. Random then gives me a reliable sequence of numbers to use for generating wheel data and reflector plates. Since I don't have to store each wheel in the script, I reduce the size of the script, while increasing the possible configurations.Enigma.au3expandcollapse popup#cs ---------------------------------------------------------------------------- Project Name: Enigma Description: Encryption based on Enigma machine AutoIt Version: v3.3.6.1 Author: David Williams (willichan) Email: david@optionsintegrated.com website: http://optionsintegrated.com Company: Options Integrated Creation Date: 7/26/2010 #ce ---------------------------------------------------------------------------- #include-once #cs *** Enigma_Object *** [0][0] = WheelCount [0][1] = BaseSeed ;number representing $basekey, used to seed random() [1][0] [0 - 255] = Reflector data [1][x] = Wheel x data [1][x] [0][0 - 255] = passforward data (0 - 255) [1][x] [0][256] = starting position (0 - 255) [1][x] [1][0 - 255] = passbackward data (0 - 255) [1][x] [1][256] = current position (0 - 255) #ce #cs *** WheelDefs *** [0][0] = # of wheels [x][0] = wheel x ID number (0 - 2147483647) [x][1] = wheel x starting position (0 - 255) #ce ; +------------------+ ; | Public Functions | ; +------------------+ Func _Enigma_Initialize($BaseKey, $WheelDefs = -1, $ReflectorDef = -1) Local $Enigma_Object Local $WheelCount Local $i, $j Local $automated = True If IsArray($WheelDefs) Then $automated = False Local $BaseSeed = _Enigma_Numify($BaseKey) SRandom($BaseSeed) If $automated Then $WheelCount = 4 Else $WheelCount = $WheelDefs[0][0] EndIf Dim $j[$WheelCount] For $i = 1 To $WheelCount If $automated Then $j[$i - 1] = Random(0, 65535, 1) Else $j[$i - 1] = $WheelDefs[$i][0] EndIf Next Dim $Enigma_Object[2][$WheelCount + 1] $Enigma_Object[0][0] = $WheelCount $Enigma_Object[0][1] = $BaseSeed If $ReflectorDef < 0 Then $Enigma_Object[1][0] = _Enigma_GenReflector(BitXOR($BaseSeed, Random(0, 65535, 1))) Else $Enigma_Object[1][0] = _Enigma_GenReflector(BitXOR($BaseSeed, $ReflectorDef)) EndIf For $i = 1 To $WheelCount $Enigma_Object[1][$i] = _Enigma_GenWheel(BitXOR($BaseSeed, $j[$i - 1])) If $automated Then _Enigma_SetSubArray($Enigma_Object, Random(0, 255, 1), 1, $i, 0, 256) _Enigma_SetSubArray($Enigma_Object, _Enigma_GetSubArray($Enigma_Object, 1, $i, 0, 256), 1, $i, 1, 256) Else _Enigma_SetSubArray($Enigma_Object, $WheelDefs[$i][1], 1, $i, 0, 256) _Enigma_SetSubArray($Enigma_Object, _Enigma_GetSubArray($Enigma_Object, 1, $i, 0, 256), 1, $i, 1, 256) EndIf Next SRandom($Enigma_Object[0][1]) Return $Enigma_Object EndFunc ;==>_Enigma_Initialize Func _Enigma_Reset(ByRef $Enigma_Object) Local $i For $i = 1 To $Enigma_Object[0][0] _Enigma_SetSubArray($Enigma_Object, _Enigma_GetSubArray($Enigma_Object, 1, $i, 0, 256), 1, $i, 1, 256) Next SRandom($Enigma_Object[0][1]) EndFunc ;==>_Enigma_Reset Func _Enigma_Crypt(ByRef $Enigma_Object, $data, $reset = True) Local $i Local $RetData If $reset Then _Enigma_Reset($Enigma_Object) $RetData = "" For $i = 1 To StringLen($data) $RetData &= Chr(_Enigma_CryptChar($Enigma_Object, Asc(StringMid($data, $i, 1)))) Next Return $RetData EndFunc ;==>_Enigma_Crypt ; +-------------------+ ; | Private Functions | ; +-------------------+ Func _Enigma_GetSubArray(ByRef $MainArray, $sub1, $sub2, $sub3 = -1, $sub4 = -1) Local $temp $temp = $MainArray[$sub1][$sub2] Switch @NumParams Case 3 Return $temp Case 4 Return $temp[$sub3] Case 5 Return $temp[$sub3][$sub4] EndSwitch EndFunc ;==>_Enigma_GetSubArray Func _Enigma_SetSubArray(ByRef $MainArray, $value, $sub1, $sub2, $sub3 = -1, $sub4 = -1) Local $temp $temp = $MainArray[$sub1][$sub2] Switch @NumParams Case 4 $temp = $value Case 5 $temp[$sub3] = $value Case 6 $temp[$sub3][$sub4] = $value EndSwitch $MainArray[$sub1][$sub2] = $temp EndFunc ;==>_Enigma_SetSubArray Func _Enigma_CryptChar(ByRef $Enigma_Object, $character) Local $i Local $RetData = $character For $i = 1 To $Enigma_Object[0][0] $RetData = _Enigma_GetSubArray($Enigma_Object, 1, $i, 0, $RetData) Next $RetData = _Enigma_GetSubArray($Enigma_Object, 1, 0, $RetData) For $i = $Enigma_Object[0][0] To 1 Step -1 $RetData = _Enigma_GetSubArray($Enigma_Object, 1, $i, 1, $RetData) Next _Enigma_Rotate($Enigma_Object) Return $RetData EndFunc ;==>_Enigma_CryptChar Func _Enigma_Rotate(ByRef $Enigma_Object, $WheelID = 1) _Enigma_SetSubArray($Enigma_Object, _Enigma_GetSubArray($Enigma_Object, 1, $WheelID, 1, 256) + 1, 1, $WheelID, 1, 256) If _Enigma_GetSubArray($Enigma_Object, 1, $WheelID, 1, 256) > 255 Then _Enigma_SetSubArray($Enigma_Object, 0, 1, $WheelID, 1, 256) If $WheelID < $Enigma_Object[0][0] Then _Enigma_Rotate($Enigma_Object, $WheelID + 1) EndIf EndFunc ;==>_Enigma_Rotate Func _Enigma_GenWheel($Seed) Local $Wheel[2][257] Local $remaining[256] Local $i, $j SRandom($Seed) For $i = 0 To 255 $remaining[$i] = 1 Next For $i = 0 To 255 $j = Random(0, 255, 1) While $remaining[$j] = -1 $j += 1 If $j > 255 Then $j = 0 WEnd $Wheel[0][$i] = $j $Wheel[1][$j] = $i $remaining[$j] = -1 Next Return $Wheel EndFunc ;==>_Enigma_GenWheel Func _Enigma_GenReflector($Seed) Local $Reflector[256] Local $i, $j SRandom($Seed) For $i = 0 To 255 $Reflector[$i] = $i Next For $i = 0 To 255 If $Reflector[$i] = $i Then $j = Random(0, 255, 1) While $Reflector[$j] <> $j $j += 1 If $j > 255 Then $j = 0 WEnd $Reflector[$i] = $j $Reflector[$j] = $i EndIf Next Return $Reflector EndFunc ;==>_Enigma_GenReflector Func _Enigma_Numify($data) Local $res[8] = [0, 0, 0, 0, 0, 0, 0, 0] Local $clipping, $i, $result While StringLen($data) > 0 $clipping = StringSplit(StringRight(" " & $data, 8), "", 2) For $i = 0 To 7 $res[$i] = BitXOR($res[$i], Asc($clipping[$i])) Next If StringLen($data) < 8 Then $data = "" Else $data = StringLeft($data, StringLen($data) - 8) EndIf WEnd $result = 0 For $i = 0 To 6 $result += $res[$i] $result *= 256 Next $result += $res[7] $result = BitAND($result, 2147483647) If BitAND($res[0], 128) > 0 Then $result = -1 * $result Return $result EndFunc ;==>_Enigma_NumifyHere is a sample file that uses it.sample.au3#include <Enigma.au3> $mykey = "Zippity Doo Da" ;my super-secret passkey Dim $WD[5][2] = [[4,4],[5000,200],[101,201],[3110,202],[11,203]] ;the wheel data array $RD = 65042 ;the reflector plate $a = "I picked out my own four-wheeler." ;the original string $crypter = _Enigma_Initialize($mykey, $WD, $RD) ;get the enigma object $b = _Enigma_Crypt($crypter, $a) ;Encrypt the original string $c = _Enigma_Crypt($crypter, $b) ;Decrypt the encrypted string MsgBox(0, "test1", "'" & $a & "'" & @CRLF & _ "'" & $b & "'" & @CRLF & _ "'" & $c & "'") $mykey = "Bibbidy Bobbidy Boo!" ;my super-secret passkey $a = "You pick out the wheels this time." ;the original string $crypter = _Enigma_Initialize($mykey) ;get the enigma object $b = _Enigma_Crypt($crypter, $a) ;Encrypt the original string $c = _Enigma_Crypt($crypter, $b) ;Decrypt the encrypted string MsgBox(0, "test2", "'" & $a & "'" & @CRLF & _ "'" & $b & "'" & @CRLF & _ "'" & $c & "'") Edited October 26, 2010 by willichan My UDFs: Barcode Libraries, Automate creation of any type of project folder, File Locking with Cooperative Semaphores, Inline binary files, Continue script after reboot, WinWaitMulti, Name Aggregator, Enigma, CornedBeef Hash Link to comment Share on other sites More sharing options...
czardas Posted October 26, 2010 Share Posted October 26, 2010 (edited) It looks interesting. I was wondering one thing though. That is whether using all 256 ascII characters is reliable, or not. I haven't fully examined what is happening with the code, so perhaps my concern is unfounded. I thought I would ask about it anyway. Are you including the NUL character, and can you do that?EditWhen I once tried something similar to this, I avoided using some of the control characters, because I wasn't sure of the consequences. Edited October 26, 2010 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
willichan Posted October 26, 2010 Author Share Posted October 26, 2010 I was wondering one thing though. That is whether using all 256 ascII characters is reliable, or not.When I once tried something similar to this, I avoided using some of the control characters, because I wasn't sure of the consequences.If you are planning on displaying the encrypted output (like the demo does), then no, it isn't stable. You would have to retool it to work only with displayable characters.If you are working with files, then yes, it works fine. When you are dealing with binary data, the NUL character (ASCII 0) has to be taken into account. I wrote this to handle the full ASCII 0-255 range.I'll think about making a displayable characters only version. My UDFs: Barcode Libraries, Automate creation of any type of project folder, File Locking with Cooperative Semaphores, Inline binary files, Continue script after reboot, WinWaitMulti, Name Aggregator, Enigma, CornedBeef Hash Link to comment Share on other sites More sharing options...
czardas Posted October 26, 2010 Share Posted October 26, 2010 (edited) Okay, thanks for the insight. I remember avoiding using them, just to be on the safe side; which is the reason it occured to me to ask. Edited October 26, 2010 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now