Jump to content

- - - - -

Opdracht 059

  • Please log in to reply
Er zijn 1 reacties in dit onderwerp

#1 josk79


    Master Developer

  • Leden
  • PipPipPipPipPip
  • 614 Berichten
    Last Visit 16 Aug 2018 17:25

Geplaatst op 17 October 2010 - 16:55


Each character on a computer is assigned a unique code and the preferred standard is ASCII (American Standard Code for Information Interchange). For example, uppercase A = 65, asterisk (*) = 42, and lowercase k = 107.

A modern encryption method is to take a text file, convert the bytes to ASCII, then XOR each byte with a given value, taken from a secret key. The advantage with the XOR function is that using the same encryption key on the cipher text, restores the plain text; for example, 65 XOR 42 = 107, then 107 XOR 42 = 65.

For unbreakable encryption, the key is the same length as the plain text message, and the key is made up of random bytes. The user would keep the encrypted message and the encryption key in different locations, and without both "halves", it is impossible to decrypt the message.

Unfortunately, this method is impractical for most users, so the modified method is to use a password as a key. If the password is shorter than the message, which is likely, the key is repeated cyclically throughout the message. The balance for this method is using a sufficiently long password key for security, but short enough to be memorable.

Your task has been made easy, as the encryption key consists of three lower case characters. Using cipher1.txt (right click and 'Save Link/Target As...'), a file containing the encrypted ASCII codes, and the knowledge that the plain text must contain common English words, decrypt the message and find the sum of the ASCII values in the original text.

#2 josk79


    Master Developer

  • Leden
  • PipPipPipPipPip
  • 614 Berichten
    Last Visit 16 Aug 2018 17:25

Geplaatst op 17 October 2010 - 16:56

Mijn oplossing kraakt in 30 mSec de code:

Visual Basic Code:
	Public Class Problem059
		Implements IEulerSolution

		Public InputFilename As String = "c:\cipher1.txt"

		Public Function Solve() As String Implements IEulerSolution.Solve

			Dim encryptedmessage As String = ""
			'Lees boodschap uit tekstbestand
			Using infile As System.IO.StreamReader = New System.IO.StreamReader(InputFilename)
				Dim values As String() = infile.ReadLine.Split(","c)
				For Each value As String In values
					encryptedmessage &= Chr(Integer.Parse(value))
			End Using

			'Je kunt het ook met een andere boodschap proberen, bijv door onderstaande regel te decommentariseren:
			'encryptedmessage = decrypt("Dit is een andere boodschap met een andere sleutel van 3 karakters.", "bla")

			'Het is door de code een beetje uit te breiden zelfs mogelijk
			'om de key te vinden van een onbekend aantal karakters!

			Const keylength As Integer = 3
			Dim key As String = ""
			For i As Integer = 0 To keylength - 1
				key &= findkey(encryptedmessage, keylength, i)
			Dim decryptedmessage As String = decrypt(encryptedmessage, key)

			Console.WriteLine("KEY: " & key)
			Console.WriteLine("MSG: " & decryptedmessage & vbCrLf)

			'Bereken het totaal van de ascii waarden van de boodschap
			Dim solution As Integer = 0
			For Each cha As Char In decryptedmessage
				solution += Asc(cha)

			Return solution.ToString
		End Function

		Public Function findkey(ByVal encryptedmessage As String, ByVal KeyLength As Integer, ByVal KeyPos As Integer) As Char
			' Zoekt een van de karakters van de sleutel met opgegeven KeyLength.
			' In plaats van alle mogelijke combinaties te brute-forcen
			' is het vele male sneller iedere karakter van de key afzonderlijk
			' te zoeken.

			Dim charstodecrypt As String = ""
			For p As Integer = KeyPos To encryptedmessage.Length - 1 Step KeyLength
				charstodecrypt &= encryptedmessage(p)

			Dim maxscore As Double = -1
			Const validkeycharacters As String = "abcdefghijklmnopqrstuvwxyz"
			For Each cha As Char In validkeycharacters
				Dim score As Double = GetTextScore(decrypt(charstodecrypt, cha))
				If score > maxscore Then
					maxscore = score
					findkey = cha
				End If
		End Function

		Public Function decrypt(ByVal encryptedmessage As String, ByVal key As String) As String
			'Deze functie werkt ook om te encrypten want bij XOR is de encrypt actie gelijk aan de decrypt actie
			decrypt = ""
			For p As Integer = 0 To encryptedmessage.Length - 1
				decrypt &= Chr(Asc(encryptedmessage(p)) Xor Asc(key(p Mod key.Length)))
		End Function

		Public Function GetTextScore(ByVal text As String) As Double
			'Geef een score(0 ... 1) van hoe goed de tekst lijkt op een zinnige tekst
			Dim score As Double = 0
			For Each cha As Char In text
				Select Case cha
					'Karakter voor karakter een score berekenen (0..1) 
					Case " "c, "A"c To "Z"c, "a"c To "z"c
						score += 1
					Case "1"c To "9"c
						score += 0.9
					Case "'"c, "."c, ","c
						score += 0.8
				End Select
			Return score / text.Length
		End Function
	End Class

Also tagged with one or more of these keywords: Solved

0 gebruiker(s) lezen dit onderwerp

0 leden, 0 gasten, 0 anonieme gebruikers

Sign In

[Solved] Untitled 1

Met dank aan Jürgen voor de jarenlange inzet van visualbasic.be (anno dec 2000)
Met dank aan Mike en Ronneke voor de jarenlange inzet van vbib.be (anno dec 2010)
Met dank aan PascalBianca voor de jarenlange inzet van vbib.be (anno dec 2016)