This is what I have so far.
Public Function XOREncDec(ByVal textToEncrypt As String) As String
Dim inSb As New StringBuilder(textToEncrypt)
Dim outSb As New StringBuilder(textToEncrypt.Length)
Dim c As Char
For i As Integer = 0 To textToEncrypt.Length - 1
c = inSb(i)
c = Chr(Asc(AscW(c)) Xor "password")
outSb.Append(c)
Next
Return outSb.ToString()
End Function
However I am getting an error here
c = Chr(Asc(AscW(c)) Xor "password")
"Conversion from string "password" to type 'Long' is not valid."
First, read the comments about better methods to protect strings.
Then, we can look at your code. You would xor characters with one character at a time from the password, not the whole password. You can use the loop variable with the mod operator to get the corresponding index in the password so it will repeat the characters in password along the length of the string.
Using Asc(Ascw(c)) means that you get the character code for the first character of the string representation of the character code for the character. For example the character A would give you the character code 65, that would implicitly be converted to the string "65" to get the character code for the character 6, which is 54. As you only use the first digit of the character code, it would not be possible to get the original string back.
You should use ony AscW to get the character code, and then ChrW to turn the adjusted character code back to a character. The Asc and Chr function doesn't support Unicode characters.
You don't need a StringBuilder for the input, you can access the characters directly from the string.
Public Function XOREncDec(ByVal textToScramble As String) As String
Dim builder As New StringBuilder(textToScramble.Length)
Dim password As String = "password"
Dim c As Char
For i As Integer = 0 To textToScramble.Length - 1
Dim pos As Integer = i mod password.Length
c = textToScramble(i)
c = ChrW(AscW(c) Xor AscW(password(pos)))
builder.Append(c)
Next
Return builder.ToString()
End Function
Note that I renamed the parameter from textToEncrypt to textToScramble, as this simple encoding can't be called encryption in any modern sense of the word.
A word of caution also, the string that is the result of encoding will often contain character codes that doesn't correspond to real characters. It works as long as you decode the same string object, but if you for example write the string to a file and then try to read it back, it will most likely get corrupted. To get data that would survive any kind of storage or communication, you would encode the string into bytes, scramble the bytes, and then create a string value from the bytes using for example base64 encoding.
Related
I am using the Google Chrome Native Messaging which says that it supplies UTF8 encoded JSON. Found here.
I am pretty sure my code is fairly standard and pretty much a copy from answers here in C#. For example see this SO question.
Private Function OpenStandardStreamIn() As String
Dim MsgLength As Integer = 0
Dim InputData As String = ""
Dim LenBytes As Byte() = New Byte(3) {} 'first 4 bytes are length
Dim StdIn As System.IO.Stream = Console.OpenStandardInput() 'open the stream
StdIn.Read(LenBytes, 0, 4) 'length
MsgLength = System.BitConverter.ToInt32(LenBytes, 0) 'convert length to Int
Dim Buffer As Char() = New Char(MsgLength - 1) {} 'create Char array for remaining bytes
Using Reader As System.IO.StreamReader = New System.IO.StreamReader(StdIn) 'Using to auto dispose of stream reader
While Reader.Peek() >= 0 'while the next byte is not Null
Reader.Read(Buffer, 0, Buffer.Length) 'add to the buffer
End While
End Using
InputData = New String(Buffer) 'convert buffer to string
Return InputData
End Function
The problem I have is that when the JSON includes characters such as ß Ü Ö Ä then the whole string seems to be diffent and I cannot deserialize it. It is readable and my log shows the string is fine, but there is something different. As long as the string does NOT include these characters then deserialization works fine. I am not supplying the JavascriptSerializer code as this is not the problem.
I have tried creating the StreamReader with different Encodings such as
New System.IO.StreamReader(StdIn, Encoding.GetEncoding("iso-8859-1"), True)
however the ß Ä etc are then not correct.
What I don't understand is if the string is UTF8 and .NET uses UTF16 how am I supposed to make sure the conversion is done properly?
UPDATE
Been doing some testing. What I have found is if I receive a string with fuß then the message length (provided by native messaging) is 4 but number of Char in the buffer is 3, if the string is fus then the message length is 3 and number of characters is 3. Why is that?
With the above code the Buffer object is 1 too big and thus is why there is a problem. If I simple use the Read method on the stream then it works fine. It appears that Google Messaging is sending a message length that is different when the ß is in the string.
If I want to use the above code then how can I know that the message length is not right?
"Each message is serialized using JSON, UTF-8 encoded and is preceded with 32-bit message length in native byte order. The maximum size of a single message from the native messaging host is 1 MB." This implies that the message length is in bytes, also, that the length is not part of the message (and so its length is not included in length).
Your confusion seems to stem from one of two things:
UTF-8 encodes a Unicode codepoint in 1 to 4 code units. (A UTF-8 code unit is 8 bits, one byte.)
Char is a UTF-16 code unit. (A UTF-16 code unit is 16 bits, two bytes. UTF-16 encodes a Unicode codepoint in 1 to 2 code units.)
There is no way to tell how many codepoints or UTF-16 code units are in the message until after it is converted (or scanned, but then you might as well just convert it).
Then, presumably, stream will either be found to be closed or the next thing to read would be another length and message.
So,
Private Iterator Function Messages(stream As Stream) As IEnumerable(Of String)
Using reader = New BinaryReader(stream)
Try
While True
Dim length = reader.ReadInt32
Dim bytes = reader.ReadBytes(length)
Dim message = Encoding.UTF8.GetString(bytes)
Yield message
End While
Catch e As EndOfStreamException
' Expected when the sender is done
Return
End Try
End Using
End Function
Usage
Messages(stream).ToList()
or
For Each message In Messages(stream)
Debug.WriteLine(message)
Next message
if you're displaying the output of this code in a console, this would diffidently happen. because windows console doesn't display Unicode characters. if this wasn't the case, then try to use a string builder to convert the data inside your StdIn stream to a string
This question already has answers here:
How do I convert Unicode escape sequences to Unicode characters in a .NET string?
(5 answers)
Closed 3 years ago.
I am trying to parse a string (returned by a web server), which contains non-standard (as far as I can tell) unicode Id's such as "\Ud83c" or "\U293c", as well as plain text. I need to display this string, emojis in tact, to the user in a datagrid view.
btw, I am blind so please excuse any formatting errors :(
full example of what my code is parsing: "Castle: \Ud83d\Udc40Jerusal\U00e9m.Miles"
the code I wrote which is failing miserably:
Public Function ParseUnicodeId(LNKText As String) As String
Dim workingarray() As String
Dim CurString As String
Dim finalString As String
finalString = ""
' split at \ char
workingarray = Split(LNKText, chr(92))
For Each CurString In workingarray
If CurString <> "" Then
' remove leading U so number can be converted to hex
CurString = Right(CurString, Len(CurString) - 1)
' attempt to cut off right most chars until number can be converted to text as there is nothign separating end of Unicode chars and start of plain text
Do While IsNumeric(CurString) = False
If CurString = "" Then
Exit Do
End If
CurString = Left(CurString, Len(CurString) - 1)
Loop
If CurString.StartsWith("U", StringComparison.InvariantCultureIgnoreCase) Then
CurString = CurString.Substring(1)
End If
' convert result from above to hex
Dim numeric = Int32.Parse(CurString, NumberStyles.HexNumber)
' convert to bytes
Dim bytes = BitConverter.GetBytes(numeric)
' convert resulting bytes to a real char for display
finalString = finalString & Encoding.Unicode.GetString(bytes)
End If
Next
ParseUnicodeId = finalString
End Function
I tried to do this all kinds of ways; but can't seem to get it right. My code currently returns empty strings, although my guess is that is because of some of the more recent changes I have made to cut off the leading U or to try and chop off one char at a time. If I take those bits out and just pass it something like "Ud83c", it works perfectly; its only when plain text is mixed in that it fails, but I can't seem to come up with a way to separate the two and re-combine at the end.
You can use Regex.Unescape() to convert the unicode escaped char (\uXXXX) to a string.
If you receive \U instead of \u, you also need to perform that substitution, since \U is not recognized as a valid escape sequence.
Dim input as String = "Castle: \Ud83d\Udc40Jerusal\U00e9m.Miles"
Dim result As String = Regex.Unescape(input.Replace("\U", "\u")).
This prints (it may depend on the Font used):
Castle: 👀Jerusalém.Miles
As a note, you might also have used the wrong encoding when you decoded the input stream.
I'am comparing Strings in Visual Basic 2010 Express. While cuting the String together it sometimes adds a Char with "", what I hoped is "nothing"
Example:
Dim text as String = "test"
Dim sign as Char = ""
text = text + sign
while debuging it says that the new text is "test", but if I ask for the Length it is 5.
This is a problem when I try to compare this with an other String
Dim bigtext as String = "test1234"
Dim text as String = "test"
Dim sign as Char = ""
text = text + sign
bigtext.indexOf(text) 'should be 0 (index), but is -1 (not found)
any idea how to filter a "" away or any other workaround?
Edit - my workoround for now:
Now I add "§" everywhere instead of "" and when I need to use indexOf() to compare something, I Replace("§", "") it.
(with Replace() it is deleted)
As far as I can see, a Char variable always has a character in it (which can be the null character). Concatenating it to another string will append that character to the existing string.
I see two workarounds:
Use a String for sign instead of a Char. The string could be empty or have a single character in it.
Trim the undesired character from the resulting string:
text = (text + sign).Trim(CChar(""))
I have a plain text string that I'm converting to a byte array and then to a string and storing in a database.
Here is how I'm doing it:
Dim b As Byte() = System.Text.Encoding.UTF8.GetBytes("Hello")
Dim s As String = BitConverter.ToString(b).Replace("-", "")
Afterwards I store the value of s (which is "48656C6C6F") into a database.
Later on, I want to retrieve this value from the database and convert it back to "Hello". How would I do that?
You can call the following function with your hex string and get "Hello" returned to you. Note that the function doesn't validate the input, you would need to add validation unless you can be sure the input is valid.
Private Function HexToString(ByVal hex As String) As String
Dim result As String = ""
For i As integer = 0 To hex.Length - 1 Step 2
Dim num As Integer = Convert.ToInt32(hex.Substring(i, 2), 16)
result &= Chr(num)
Next
Return result
End Function
James Thorpe points out in his comment that it would be more appropriate to use Encoding.UTF8.GetString to convert back to a string as that is the reverse of the method used to create the hex string in the first place. I agree, but as my original answer was already accepted, I hesitate to change it, so I am adding an alternative version. The note about validation of input being skipped still applies.
Private Function HexToString(ByVal hex As String) As String
Dim bytes(hex.Length \ 2 - 1) As Byte
For i As Integer = 0 To hex.Length - 1 Step 2
bytes(i \ 2) = Byte.Parse(hex.Substring(i, 2), System.Globalization.NumberStyles.HexNumber)
Next
Return System.Text.Encoding.UTF8.GetString(bytes)
End Function
I have a string in VB.net that may contain something like the following:
This is a 0x000020AC symbol
This is the UTF-32 encoding for the Euro Symbol according to this article http://www.fileformat.info/info/unicode/char/20ac/index.htm
I'd like to convert this into
This is a € symbol
I've tried using UnicodeEncoding() class in VB.net (Framework 2.0, as I'm modifying a legacy application)
When I use this class to encode, and then decode I still get back the original string.
I expected that the UnicodeEncoding would recognise the already encoded part and not encode it against. But it appears to not be the case.
I'm a little lost now as to how I can convert a mixed encoded string into a normal string.
Background: When saving an Excel spreadsheet as CSV, anything outside of the ascii range gets converted to ?. So my idea is that if I can get my client to search/replace a few characters, such as the Euro symbol, into an encoded string such as 0x000020AC. Then I was hoping to convert those encoded parts back into the real symbols before I insert to a SQL database.
I've tried a function such as
Public Function Decode(ByVal s As String) As String
Dim uni As New UnicodeEncoding()
Dim encodedBytes As Byte() = uni.GetBytes(s)
Dim output As String = ""
output = uni.GetString(encodedBytes)
Return output
End Function
Which was based on the examples on the MSDN at http://msdn.microsoft.com/en-us/library/system.text.unicodeencoding.aspx
It could be that I have a complete mis-understanding of how this works in VB.net. In C# I can simply use escaped characters such as "\u20AC". But no such thing exists in VB.net.
Based on advice from Heinzi I implemented a Regex.Replace method using the following code, this appear to work for my examples.
Public Function Decode(ByVal s As String) As String
Dim output As String = ""
Dim sRegex As String = "0x[0-9a-zA-Z]{8}"
Dim r As Regex = New Regex(sRegex)
Dim myEvaluator As MatchEvaluator = New MatchEvaluator(AddressOf HexToString)
output = r.Replace(s, myEvaluator)
Return output
End Function
Public Function HexToString(ByVal hexString As Match) As String
Dim uni As New UnicodeEncoding(True, True)
Dim input As String = hexString.ToString
input = input.Substring(2)
input = input.TrimStart("0"c)
Dim output As String
Dim length As Integer = input.Length
Dim upperBound As Integer = length \ 2
If length Mod 2 = 0 Then
upperBound -= 1
Else
input = "0" & input
End If
Dim bytes(upperBound) As Byte
For i As Integer = 0 To upperBound
bytes(i) = Convert.ToByte(input.Substring(i * 2, 2), 16)
Next
output = uni.GetString(bytes)
Return output
End Function
Have you tried:
Public Function Decode(Byval Coded as string) as string
Return StrConv(Coded, vbUnicode)
End Function
Also, your function is invalid. It takes s as an argument, does a load of stuff and then outputs the s that was put into it instead of the stuff that was processed within it.