How does this code I found work? Cipher [closed] - vb.net

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
So I found this cool cipher, im making a project for school (its kinda like, show us everything you learned kinda of project) and were allowed to get heavy look at other peoples code online (as long is its not a complete copy and paste). I want to understand how it works and make my own version (without copy and pasting), ive put comments for the parts I understand, and question marks for the parts I dont.
Function EncryptDecrypt(ByVal text1 As String, ByVal key As String, ByVal isEncrypt As Boolean) As String //yea got this
Dim char1 As String //Defining char one
Dim char2 As String //Defining char two
Dim cKey As Byte //Defining a key as a byte
Dim strLength As Integer //Defining strLength as an integer
Dim Result As String = "" //Defining Result as String equal to nothing
Dim j As Integer = -1 //Defining j as an integer equal to -1
If text1 <> "" And IsNumeric(key) Then //if text1 is not nothing and the key is numeric then...
strLength = text1.Length //making strLength equal to the length of the text.
For i As Integer = 0 To strLength - 1 //Do until strLenth is less than 1 ???
char1 = text1.Substring(i, 1) //Char one is equal to
If j < key.Length - 1 Then //if j (-1) is less than the key's length - 1 then...
j = j + 1 //add one to j
Else //no explanation needed
j = 0 //no explanation needed
End If //no explanation needed
cKey = Val(key.Substring(j, 1)) //?? cKey is equal to value of the current character it is looking at (j, 1)??
If isEncrypt Then //if were encypting it
If (Asc(char1) + cKey) > 255 Then //????
char2 = Chr(Asc(char1) + cKey - 255) //????
Else //no explanation needed
char2 = Chr(Asc(char1) + cKey) //??
End If //no explanation needed
Else //no explanation needed
If (Asc(char1) - cKey) < 1 Then //????
char2 = Chr(Asc(char1) - cKey + 255) //?????
Else //no explanation needed
char2 = Chr(Asc(char1) - cKey) //?????
End If //no explanation needed
End If //no explanation needed
Result &= char2 //?????
Next //no explanation needed
Else //no explanation needed
MsgBox("Enter text or key!") //no explanation needed
End If //no explanation needed
Return Result //no explanation needed
End Function //no explanation needed
No explanation needed for these either VVVV
Private Sub btCrypt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btCrypt.Click
txtResult.Text = EncryptDecrypt(txtText.Text, txtKey.Text, True)
End Sub
Private Sub btDecrypt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btDecrypt.Click
txtResult.Text = EncryptDecrypt(txtText.Text, txtKey.Text, False)
End Sub
End Class
I kinda understand that each "letter" has an "Asc" value, but im not entirely sure how that works. Can anyone help, would be really great and helpful for me!

A good source of information can be found on the MSDN website. Below are some of the places you where getting stuck on. I've included references to the relivant documenation so if you still don't understand you can go away and see
For i As Integer = 0 To strLength - 1
Do until strLenth is equal to 0 decrementing 1 at a time
for loops msdn
cKey = Val(key.Substring(j, 1)) //?? cKey is equal to value of the
current character it is looking at (j, 1)??
Yes, cKey will be assigned the last char of the key. If they key was 854824 then cKey is now '4'.
If (Asc(char1) + cKey) > 255 Then //????
char2 = Chr(Asc(char1) + cKey - 255) //????
Else //no explanation needed
char2 = Chr(Asc(char1) + cKey) //??
End If //no explanation needed
Here this formula is used for decrying. What is useful to know here is that the Asc function will return the Asci Value for the character (table here)
A Asci character of a Single-byte Character Sets can not be greater than 255 or less than 0, so if it is greater, then they -255 + the cKey to find the original Ascii value.
If (Asc(char1) - cKey) < 1 Then //????
char2 = Chr(Asc(char1) - cKey + 255) //?????
Else //no explanation needed
char2 = Chr(Asc(char1) - cKey) //?????
End If //no explanation needed
Same as above but in reverse, this code will encrypt the character value by incrementing 255 to the char value if the ASCII value of char1 - x (where x = the numeric value of the last digit in the cKey) is greater than 0.
Result &= char2 //?????
and lastly this will concatanate the string onto Result each loop.
This is short hand for writing
Result = Result + Char2
You'll probably understand it more stepping through the program in debug and seeing the values of the variables as you go along.
Best of luck to you,
hope this helps

It cycles through the input character-by-character, and the key (all numbers, one digit at a time). Each character is converted to its ASCII character code, and has the key digit added or subtracted from it.
When it runs out of key, it loops back to the start of the key and goes through again.
If adding/subtracting gets a character outside the ASCII character code table (<0 or >255), it wraps round to the other side of the table.
And builds up a string of output, character by character.

Related

(in Visual Basic) Is it possible to "loop" or "rotate" through a byte, without using an( if-then-tree) or (and &HFF)?

What I mean is: If a byte has value of 255, and I add 1. It becomes 0 again.
Or if I subtract 1 from a zero value it becomes 255.
I have a lot of code, that treats bytes like this,
and I'd rather not sift through all them lines to find occurrences of such rotations
Well, nothing ventured and all that...
Cheers
Jhonny
Edit:
Just a dumb example:
Sub Tester()
Dim Arr(255) As Byte
Dim BytePointer As Byte = 200
Dim value As Byte
Arr(50) = 1
For i = 0 To 5000
BytePointer = BytePointer + 1
value = Arr(BytePointer)
If value = 1 Then MessageBox.Show("Found 1")
Next
end sub
As such it results in an overflow exception.
Can this work without doing:
BytePointer = (BytePointer + 1) and &FF
You didn't specify the BASIC that you use, but this answer assumes FreeBasic.
You should declare the BytePointer variable as UByte.
The number range for Byte is from -128 to +127 ("signed"), but for UByte it is 0 to 255 ("unsigned") which nicely matches the array bounds.
When your code initializes the BytePointer variable with Dim BytePointer As Byte = 200, FreeBasic already sets it at -56, and when your code increments the BytePointer variable with BytePointer = BytePointer + 1 it becomes -55.
The instruction value = Arr(BytePointer) will not address an element of your array since this index (-55) is out of bounds (0,255).
Next code works fine and has no problem with the wraparound from 255 back to 0:
Dim Arr(255) As Byte
Dim BytePointer As UByte = 251
Dim value As Byte
Dim i As Integer
For i = 0 To 255
Arr(i)=i
Next
For i = 1 To 10
value = Arr(BytePointer)
Print BytePointer, value
BytePointer = BytePointer + 1
Next
OK....
By "Removing integer overflow checks in the Advanced Compiler Options dialog", you can wrap-around bytes and integers, without overflow-errors.
But it does so for the whole project.
I can work with this...
It's a shame though, that VB does not offer variables (let's call them winteger or wbyte) that do this by default. (just my 2 cents...)

Longest Common substring breaking issue

Hi I have a function that finds the longest common substring between two strings. It works great except it seems to break when it reaches any single quote mark: '
This causes it to not truly find the longest substring sometimes.
Could anyone help me adjust this function so it includes single quotes in the substring? I know it needs to be escaped someplace I'm just not sure where.
Example:
String 1: Hi there this is jeff's dog.
String 2: Hi there this is jeff's dog.
After running the function the longest common substring would be:
Hi there this is jeff
Edit: seems to also happen with "-" as well.
It will not count anything after the single quote as part of the substring.
Here's is the function:
Public Shared Function LongestCommonSubstring(str1 As String, str2 As String, ByRef subStr As String)
Try
subStr = String.Empty
If String.IsNullOrEmpty(str1) OrElse String.IsNullOrEmpty(str2) Then
Return 0
End If
Dim num As Integer(,) = New Integer(str1.Length - 1, str2.Length - 1) {}
Dim maxlen As Integer = 0
Dim lastSubsBegin As Integer = 0
Dim subStrBuilder As New StringBuilder()
For i As Integer = 0 To str1.Length - 1
For j As Integer = 0 To str2.Length - 1
If str1(i) <> str2(j) Then
num(i, j) = 0
Else
If (i = 0) OrElse (j = 0) Then
num(i, j) = 1
Else
num(i, j) = 1 + num(i - 1, j - 1)
End If
If num(i, j) > maxlen Then
maxlen = num(i, j)
Dim thisSubsBegin As Integer = i - num(i, j) + 1
If lastSubsBegin = thisSubsBegin Then
subStrBuilder.Append(str1(i))
Else
lastSubsBegin = thisSubsBegin
subStrBuilder.Length = 0
subStrBuilder.Append(str1.Substring(lastSubsBegin, (i + 1) - lastSubsBegin))
End If
End If
End If
Next
Next
subStr = subStrBuilder.ToString()
Return subStr
Catch e As Exception
Return ""
End Try
End Function
I tried it with dotnetfiddle and there it is working with your Code you posted. Please activate your warnings in your project. You have function with no return value and you return an integer or a string. This is not correct. How are you calling your function?
Here is my example I tested for you:
https://dotnetfiddle.net/mVBDQp
Your code works perfectly like Regex! As far as I can see, there is really nothing wrong with your code.
Here I even tested it under more severe case:
Public Sub Main()
Dim a As String = ""
Dim str1 As String = "Hi there this is jeff''s dog.-do you recognize this?? This__)=+ is m((a-#-&&*-ry$##! <>Hi:;? the[]{}re this|\ is jeff''s dog." 'Try to trick the logic!
Dim str2 As String = "Hi there this is jeff''s dog. ^^^^This__)=+ is m((a-#-&&*-ry$##! <>Hi:;? the[]{}re this|\ is jeff''s dog."
LongestCommonSubstring(str1, str2, a)
Console.WriteLine(a)
Console.ReadKey()
End Sub
Note that I put '-$#^_)=+&|\{}[]?!;:.<> all there. Plus I tried to trick your code by giving early result.
But the result is excellent!
You could probably put more actual samples on the inputs which give you problems. Else, you could possibly describe the environment that you use/deploy your code into. Maybe the problem lies elsewhere and not in the code.
The quickest way to solve this would be to use an escape code and replace all the ' with whatever escape code you use

signed result of Val function in VBA

I use vba in ms access,and found that ,if my parameter greater than 0x8000
less than 0x10000, the result is minus number
eg. Val("&H8000") = -32768 Val("&HFFFF")= -1
how can i get the unsigned number?
thanks!
There's a problem right here:
?TypeName(&HFFFF)
Integer
The Integer type is 16-bit, and 65,535 overflows it. This is probably overkill, but it was fun to write:
Function ConvertHex(ByVal value As String) As Double
If Left(value, 2) = "&H" Then
value = Right(value, Len(value) - 2)
End If
Dim result As Double
Dim i As Integer, j As Integer
For i = Len(value) To 1 Step -1
Dim digit As String
digit = Mid$(value, i, 1)
result = result + (16 ^ j) * Val("&H" & digit)
j = j + 1
Next
ConvertHex = result
End Function
This function iterates each digit starting from the right, computing its value and adding it to the result as it moves to the leftmost digit.
?ConvertHex("&H10")
16
?ConvertHex("&HFF")
255
?ConvertHex("&HFFFF")
65535
?ConvertHex("&HFFFFFFFFFFFFF")
281474976710655
UPDATE
As I suspected, there's a much better way to do this. Credits to #Jonbot for this one:
Function ConvertHex(ByVal value As String) As Currency
Dim result As Currency
result = CCur(value)
If result < 0 Then
'Add two times Int32.MaxValue and another 2 for the overflow
'Because the hex value is apparently parsed as a signed Int64/Int32
result = result + &H7FFFFFFF + &H7FFFFFFF + 2
End If
ConvertHex = result
End Function
Append an ampersand to the hex literal to force conversion to a 32bit integer:
Val("&HFFFF" & "&") == 65535
Val("&H8000&") == +32768
Don't use Val. Use one of the built-in conversion functions instead:
?CCur("&HFFFF")
65535
?CDbl("&HFFFF")
65535
Prefer Currency over Double in this case, to avoid floating-point issues.

Increment character in a string

I have a 2 character string composed only of the 26 capital alphabet letters, 'A' through 'Z'.
We have a way of knowing the "highest" used value (e..g "IJ" in {"AB", "AC", "DD", "IH", "IJ"}). We'd like to get the "next" value ("IK" if "IJ" is the "highest").
Function GetNextValue(input As String) As String
Dim first = input(0)
Dim last = input(1)
If last = "Z"c Then
If first = "Z"c Then Return Nothing
last = "A"c
first++
Else
last++
EndIf
Return first & last
End Function
Obviously char++ is not valid syntax in VB.NET. C# apparently allows you to do this. Is there something shorter less ugly than this that'd increment a letter? (Note: Option Strict is on)
CChar(CInt(char)+1).ToString
Edit: As noted in comment/answers, the above line won't even compile. You can't convert from Char -> Integer at all in VB.NET.
The tidiest so far is simply:
Dim a As Char = "a"
a = Chr(Asc(a) + 1)
This still needs handling for the "z" boundary condition though, depending on what behaviour you require.
Interestingly, converting char++ through developerfusion suggests that char += 1 should work. It doesn't. (VB.Net doesn't appear to implicitly convert from char to int16 as C# does).
To make things really nice you can do the increment in an Extension by passing the char byref. This now includes some validation and also a reset back to a:
<Extension>
Public Sub Inc(ByRef c As Char)
'Remember if input is uppercase for later
Dim isUpper = Char.IsUpper(c)
'Work in lower case for ease
c = Char.ToLower(c)
'Check input range
If c < "a" Or c > "z" Then Throw New ArgumentOutOfRangeException
'Do the increment
c = Chr(Asc(c) + 1)
'Check not left alphabet
If c > "z" Then c = "a"
'Check if input was upper case
If isUpper Then c = Char.ToUpper(c)
End Sub
Then you just need to call:
Dim a As Char = "a"
a.Inc() 'a is now = "b"
My answer will support up to 10 characters, but can easily support more.
Private Sub Test
MsgBox(ConvertBase10ToBase26(ConvertBase26ToBase10("AA") + 1))
End Sub
Public Function ConvertBase10ToBase26(ToConvert As Integer) As String
Dim pos As Integer = 0
ConvertBase10ToBase26 = ""
For pos = 10 To 0 Step -1
If ToConvert >= (26 ^ pos) Then
ConvertBase10ToBase26 += Chr((ToConvert \ (26 ^ pos)) + 64)
ToConvert -= (26 ^ pos)
End If
Next
End Function
Public Function ConvertBase26ToBase10(ToConvert As String) As Integer
Dim pos As Integer = 0
ConvertBase26ToBase10 = 0
For pos = 0 To ToConvert.Length - 1
ConvertBase26ToBase10 += (Asc(ToConvert.Substring(pos, 1)) - 64) * (26 ^ pos)
Next
End Function
Unfortunately, there's no easy way -- even CChar(CInt(char)+1).ToString doesn't work. It's even uglier:
CChar(Char.ConvertFromUtf32(Char.ConvertToUtf32(myCharacter, 0) + 1))
but of course you could always put that in a function with a short name or, like Jon E. pointed out, an extension method.
Try this
Private Function IncBy1(input As String) As String
Static ltrs As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Dim first As Integer = ltrs.IndexOf(input(0))
Dim last As Integer = ltrs.IndexOf(input(1))
last += 1
If last = ltrs.Length Then
last = 0
first += 1
End If
If first = ltrs.Length Then Return Nothing
Return ltrs(first) & ltrs(last)
End Function
This DOES assume that the code is only two chars, and are A-Z only.
Dim N as String = ""
Dim chArray As Char = Convert.ToChar(N)
Dim a As String = CChar(Char.ConvertFromUtf32(Char.ConvertToUtf32(chArray, 0) + 1))

How to reverse this algorithm to get back the original text? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
Can anyone please explain with the easy coding how to reverse this algorithm so that I get back the original text string?
Public Function CreateIntChecksum(ByVal s As String) As Integer
Dim r As Integer = 0
For i As Integer = 0 To (s.Length() - 1)
Dim bchar As Byte = Convert.ToByte(s(i))
r = bchar + ((r << 5) - r)
Next
Return r
End Function
Although it is impossible to find the original text, it is possible find a preimage easily. The crucial point is
r = bchar + ((r << 5) - r)
which is equivalent to
r = bchar + r*31
Therefore, the hash encodes the string in base-31. To find a preimage, just rewrite the integer in base 31.
For instance, if the result is 3456, we know 3456 = 3 × 312 + 18 × 31 + 15, so one possible original text is "\x03\x12\x0f". Of course, we could rearrange the numbers to give 110 × 31 + 46 ("n.") or 109 × 31 + 77 ("mM") etc, which shows there is no unique preimage.
You can't. What you have here is a Checksum, which is a basic hashing function. The the whole point of a hashing function is that it is irreversible. Hashing functions map a set of inputs (usually infinite) to a smaller set of outputs - so multiple inputs can end up with the same output, and thus this makes reversing a hash impossible (assuming the hash is correctly done). This is why they are used to store passwords - there is no way to read a hash and go "Oh, that is password XYZ".
One way of trying to find out the original value is to use a Rainbow Table. This is merely a massive table of inputs and their equivalent hashed (or in this case checksummed) values. If you have the hashed value of your unknown string you can search for it in the table and get the set of possible inputs. This is not a way to reverse a hash function, which is impossible; it is merely a brute force guessing method. Note also that in this case (assuming the hashing function is not biased) there are an infinite number of strings that match each checksummed value, as a visual basic string can be of arbitrary length. This would make a rainbow table for this very impractical - you could cover the set of probably inputs for a hashing (as most normal users won't enter more than a 10 character code), but nothing stops the user using a 67 character code, or 109, or...
Read the wikipedia articles for Hash Functions, Checksums and Rainbow Tables.
how to reverse this algorithm so that I get back the original text string?
You can't, by design.
This is a (simple) checksum or hashing function.
Take a look at the size of the information going in and out: the function transforms a string s of arbitrary length into a 32-bit Integer. For each integer value there will be many input strings that will yield that result.
Edit: Apparently you want a shuffling algorithm. Maybe take a look at ROT13. Be advised this is not a (very) safe form of encryption.
You simply can't reverse it. It's a checksum which is not reversible.
You can't. If nothing else, then simply because Integer contains only 32 bits of data and String can have any length.
First of all the code as posted will throw an exception for anything but the shortest of strings.
The following code includes the OP's original code, plus a simple checksum, and a guess at how the checksum might be used.
Private Sub Button2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button2.Click
Dim buffer() As Byte
Dim tstString As String = "Calculate a checksum for a given string"
Dim chkSumFix As Integer = CreateIntChecksumFixed(tstString) 'get a checksum
buffer = SendPacket(tstString, chkSumFix) 'create a byte buffer to send
tstString = decodePacket(buffer)
'do the same using the OP's original code
Dim chkSum As Integer = CreateIntChecksum(tstString) 'error
buffer = SendPacket(tstString, chkSum)
End Sub
'OP
Public Function CreateIntChecksum(ByVal s As String) As Integer
Dim r As Integer = 0
For i As Integer = 0 To (s.Length() - 1)
Dim bchar As Byte = Convert.ToByte(s(i))
r = bchar + ((r << 5) - r)
Next
Return r
End Function
'a very simple checksum
Public Function CreateIntChecksumFixed(ByVal s As String) As Integer
Dim r As Integer = 0
For i As Integer = 0 To (s.Length() - 1)
Dim bchar As Byte = Convert.ToByte(s(i))
r = (r And &HFFFF) + bchar
Next
Return r
End Function
Private Function SendPacket(ByVal aString As String, _
ByVal aChecksum As Integer) As Byte()
'construct a packet to be sent
'Packet format
'returns a byte buffer
'byte(0 -3) = length of original string - use BitConverter.ToInt32 to extract
'byte(4-n) = original string. n = (4 + string length) - 1
'byte(n + 1, n + 2, n + 3, n + 4) = checksum
Dim length As Integer
Dim retV As New List(Of Byte)
retV.AddRange(System.Text.Encoding.ASCII.GetBytes(aString)) 'add string to packet
length = retV.Count 'get length - use this length in case a different encoding is used
retV.AddRange(BitConverter.GetBytes(aChecksum)) 'add checksum
retV.InsertRange(0, BitConverter.GetBytes(length)) 'insert length at start of packet
Return retV.ToArray
End Function
Private Function decodePacket(ByVal buffer As Byte()) As String
Dim sLen As Integer = BitConverter.ToInt32(buffer, 0)
If sLen + 8 <> buffer.Length Then Throw New ArgumentOutOfRangeException
Dim s As String = System.Text.Encoding.ASCII.GetChars(buffer, 4, sLen)
Dim chksum As Integer = CreateIntChecksumFixed(s)
Dim embeddedChecksum As Integer = BitConverter.ToInt32(buffer, sLen + 4)
If chksum <> embeddedChecksum Then Throw New ArgumentException("Invalid checksum")
Return s
End Function