how to return unicode 8 byte value from string character - vb.net

I am trying to return the 2 byte WORD Hex value of a string character which is not typically English. Basically the Unicode representation. Using vb.net
Ex:
FF5F = ((
FF06 = &
These are represented in unicode standard 6.2. I do not have the ability to display some of the foreign language characters displayed in this set.
So would like for my string character to be converted to this 2 byte value. I haven't been able to find a function in .net to do this.
The code is currently nothing more than a for loop cycling through the string characters, so no sample progress.
I have tried the AscW and ChrW functions but they do not return the 2byte value. ASCII does not seem to be reliable above 255.
If necessary I could isolate the possible languages being tested so that only one language is considered through the comparisons, although an English character is always possible.
Any guidance would be appreciated.

I think you could convert your string to a byte array, which, would look something like this in C#:
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
From that you can just grab to two first bytes from the array, and there you go, you have them.
If you want to show them on a screen, I guess you should probably convert them to hex or some such displayable format.
I've stolen this from the question here.

A collegaue assisted in developing a solution. Each character of the string is converted to character array, and then to an unsigned integer, which is then converted to Hex.
lt = myString
Dim sChars() As Char = lt.ToCharArray
For Each c As Char In sChars
Dim intVal As UInteger = AscW(c)
Debug.Print(c & "=" & Hex(intVal))
Next
Note the AscW function... AscW returns the Unicode code point for the input character. This can be 0 through 65535. The returned value is independent of the culture and code page settings for the current thread. http://msdn.microsoft.com/en-us/library/zew1e4wc(v=vs.90).aspx
I then compare the resulting Hex to the spec for reporting.

Related

VB Xor - double-encryption

I am coding in VB6, but I can rewrite it for VB.net if it would help.
I am using XOR to do some basic encryption: printa = printa + Chr((q Xor chCode))
I am converting the result back to characters. The problem comes when I double encrypt. I think the problem arises when a XOR operation resulting in a 0. Hence, Chr(0) = a null character. PS: the chCode can be anything 1 to 254. Also when I double encrypt the source text is often out side the range of printable characters.
Any help would be appreciated. I'll try to give more info if needed. Thx
Encryption is an operation that works on all bits of the message and the result is no longer within the printable area, as you state.
There is no inherent problem with handling such a string internally in VB though, since it stores the string length at the beginning of the string, rather than using null-termination like in C.
You should look at base64-encoding your encrypted message to get back to the printable range if that is what you need. What that does is basically using 4 bytes to represent 6 bits from 3 bytes each.

How to declare a fixed length string in vb.net without increasing the length during assignment

I have a fixed length string variable:
<VBFixedString(10)>
Public myVar As String
When I assign the var to a value that has 11 chars the var changes length.
This is what I get:
myvar = "1234567890ABCD" ' result = myvar being "1234567890ABCD"
What I want is myvar to be: "1234567890"
and then if it is less than 10 I would like
myvar = "12345" to be "12345 "
I can do this with PadLeft PadRight but was wondering if I can declare it as a fixed length and it would handle all that for you.
and from the old school, LSET will do exactly what you're asking.
myvar = lset("1234567890ABCD",10)
results in "1234567890", while
myvar = lset("12345",10)
results in "12345___" - sorry, the editor trimmed the spaces after the 12345 replaced with underscores
see MSDN entry for LSET
From what I understand the VBFixedString attribute is only recognised by certain file based methods to help structure content written to/read from files. The compiler will not use that attribute for anything else, including to alter how a variable assignment is compiled.
Taken from MSDN:
The VBFixedStringAttribute is informational and cannot be used to
convert a variable length string to a fixed string. The purpose of
this attribute is to modify how strings in structures and non-local
variables are used by methods or API calls that recognize the
VBFixedStringAttribute. Keep in mind that this attribute does not
change the actual length of the string itself.
The last sentence is the important bit:
Keep in mind that this attribute does not change the actual length of the string itself.
http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.vbfixedstringattribute.aspx
EDIT 1:
A quick example on how to auto-padding a string based on a fixed length:
Function FixedLengthString(ByVal value As String, ByVal totalLength As Integer, ByVal padding As Char) As String
Dim length = value.Length
If (length > totalLength) Then Return value.Substring(0, totalLength)
Return value.PadRight(totalLength, padding)
End Function
Here you can pass in a string and if the length of the string is greater than the specified total length you will get a string matching that length. Anything less and you'll get the string plus the padding character upto the specified total length.
This can be improved with error checking and maybe making the method an extension method so you don't have to pass "value".

How do I get the length (i.e. number of characters) of an ASCII string in VB.NET?

I'm using this code to return some string from a tcpclient but when the string comes back it has a leading " character in it. I'm trying to remove it but the Len() function is reading the number of bytes instead of the string itself. How can I alter this to give me the length of the string as I would normally use it and not of the array underlying the string itself?
Dim bytes(tcpClient.ReceiveBufferSize) As Byte
networkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
' Output the data received from the host to the console.'
Dim returndata As String = Encoding.ASCII.GetString(bytes)
Dim LL As Int32 = Len(returndata)
Len() reports the number of bytes not the number of characters in the string.
Your code is currently somewhat broken. The answer is tcpClient.ReceiveBufferSize, regardless of how much data you actually received - because you're ignoring the return value from networkStream.Read. It could be returning just a few bytes, but you're creating a string using the rest of the bytes array anyway. Always check the return value of Stream.Read, because otherwise you don't know how much data has actually been read. You should do something like:
Dim bytesRead = networkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
' Output the data received from the host to the console.'
Dim returndata As String = Encoding.ASCII.GetString(bytes, 0, bytesRead)
Now, ASCII always has a single character per byte (and vice versa) so the length of the string will be exactly the same as the length of the data you received.
Be aware that any non-ASCII data (i.e. any bytes over 127) will be converted to '?' by Encoding.ASCII.GetString. You may also get control characters. Is this definitely ASCII text data to start with? If it's not, I'd recommend hex-encoding it or using some other option to dump the exact data in a non-lossy way.
You could try trimming the string inside the call to Len():
Dim LL As Int32 = Len(returndata.Trim())
If Len reports the number of bytes and it doesn't match the number of characters, then I can think of two possibilities:
There are more chars being sent than you think (ie, that extra character is actually being sent)
The encoding is not ASCII, so there can be more than one byte per char (and one of them is that 'weird' character, that is the character is being sent and is not 'wrong data'). Try to find out if the data is really ASCII encoded, if not, change the call accordingly.
When I read you correctly, you get a single quotation mark at the beginning, right?
If you get that one consistently why not just subtract one from the string length? Or use a substring from the second character:
Len(returndata.Substring(1)
And I don't quite understand what you mean with »the length of the string as I would normally use it and not of the array underlying the string itself«. You have a string. Any array which might represent that string internally is entirely implementation-dependent and nothing you should see or rely on. Or am I getting you wrong here. The string is what you are using normally. I mean, if that's not what you do, then why not take the length of the string after processing it into something you would normally use?
Maybe I am missing something here, but what is wrong with String.Length?
Dim LL As Int32 = returndata.Length

How do I type literal binary in VB.NET?

How do you type binary literals in VB.NET?
&HFF // literal Hex -- OK
&b11111111 // literal Binary -- how do I do this?
As of VB.NET 15 there is now support for binary literals:
Dim mask As Integer = &B00101010
You can also include underscores as digit separators to make the number more readable without changing the value:
Dim mask As Integer = &B0010_1010
You could define it as string and then parse it:
myBin = Convert.ToInt32("1010101010", 2)
Expanding on codymanix's answer... You could wrap this in an Extension on Strings, and add type checking...
something along the lines of:
<Extension> Public Function ParseBinary(target As String) As Integer
If Not RegEx.IsMatch(target, "^[01]+$") Then Throw New Exception("Invalid binary characters.")
Return Convert.ToInt32(target, 2)
End Function
This allows then, anywhere you have a string of binary value, say "100101100101", you can do:
Dim val As Integer = "100101100101".ParseBinary()
Note that to use <Extension>, you must import System.Runtime.CompilerServices, and be running on Framework 3.5 or later.
You don't.
VB.NET supports decimal (without prefix), octal (with &O prefix), and hexadecimal (with &H prefix) integer literals directly.

What's the suffix (type character) for "Byte" numeric constants in VB.NET?

Just out of curiosity:
I know I can tell the compiler if I want a value to be interpreted as a certain numeric type, e.g. as Integer (32 bit signed), this way appending an "I" (type character) to the constant value:
Private Function GetTheAnswerAsInteger() As Integer
Return 42I
End Function
There's also "S" for Short, "D" for Decimal, etc.
But what is the suffix for Byte? Hint: it's not the obvious one "B"...
There isn't one. If you need to distinguish between an integer and a byte (e.g. to call an appropriate overload) for a constant, you need to cast.
(The same is true in C#, by the way.)
MSDN provides confirmation:
Byte has no literal type character or
identifier type character.
There's also a list of type characters and literal suffixes.
So, we added binary literals in VB last fall and got similar feedback
from early testers. We did decide to add a suffix for byte for VB. We
settled on SB (for signed byte) and UB (for unsigned byte). The reason
it's not just B and SB is two-fold.
One, the B suffix is ambiguous if you're writing in hexadecimal (what
does 0xFFB mean?) and even if we had a solution for that, or another
character than 'B' ('Y' was considered, F# uses this) no one could
remember whether the default was signed or unsigned - .NET bytes are
unsigned by default so it would make sense to pick B and SB but all
the other suffixes are signed by default so it would be consistent
with other type suffixes to pick B and UB. In the end we went for
unambiguous SB and UB.
-- Anthony D. Green,
https://roslyn.codeplex.com/discussions/542111
It has been integrated to the upcoming VB.NET release, and this is the way it will work:
Public Const MyByte As Byte = 4UB;
Public Const MyByte2 As SByte = 4SB;
This answer does not really provide a suffix, but it's as close as it gets.
If you define an extension method as
Imports System.Runtime.CompilerServices
Module IntegerExtensions
<Extension()> _
Public Function B(ByVal iNumber As Integer) As Byte
Return Convert.ToByte(iNumber)
End Function
End Module
You can use it like this:
Private Function GetTheAnswerAsByte() As Byte
Return 42.B
End Function
There's no byte literal in .NET.