Generate A Unquie Id (GUID) That Is Only 25 Characters In Length - vb.net

What is the best appraoch to generate unquie ID's (no special characters) that will be 25 characters in length? I was thinking of generating a GUID and taking a substring of that, but I dont know if thats the best idea for uniqueness.
This is for dissconnected systems use. Creating a primary key in a database will not work in my situation. I need to create a unquie ID manually
I tried this but I am seeing duplicates in the output for some reason. So it doesnt seem too unquie even in this simple test..
Sub Main()
Dim sb As StringBuilder = New StringBuilder
For i As Integer = 1 To 100000
Dim s As String = GenerateRandomString(25, True)
sb.AppendLine(s)
sb.AppendLine(Environment.NewLine)
Next
Console.WriteLine(sb.ToString)
Console.ReadLine()
End Sub
Public Function GenerateRandomString(ByRef len As Integer, ByRef upper As Boolean) As String
Dim rand As New Random()
Dim allowableChars() As Char = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ0123456789".ToCharArray()
Dim final As String = String.Empty
For i As Integer = 0 To len - 1
final += allowableChars(rand.Next(allowableChars.Length - 1))
Next
Return IIf(upper, final.ToUpper(), final)
End Function

You’re probably seeing duplicates because New Random() is seeded according to a system clock, which may not have changed by the next iteration.
Try a cryptographically secure RNG:
Const ALLOWABLE_ALL As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Const ALLOWABLE_UPPERCASE As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Dim allowable As String = If(upper, ALLOWABLE_UPPERCASE, ALLOWABLE_ALL)
Dim result(len - 1) As Char
Dim current As Integer = 0
Using r As New Security.Cryptography.RNGCryptoServiceProvider()
Do
Dim buffer(255) As Byte
r.GetBytes(buffer)
For b As Byte In buffer
If b < allowable.Length Then
result(current) = allowable(b)
current += 1
If current = len Then Return New String(result)
End If
Next
Loop
End Using
This is also “more random” than your implementation in that letters aren’t weighted twice as heavily if upper is True.

A GUID might be 32 digits, but only if expressed in hexadecimal. That means it will only use characters 0-9 and A-F. If your string can use the entire alphabet then you can express the same GUID in fewer characters, especially if your string can be case sensitive.
See http://en.wikipedia.org/wiki/Globally_unique_identifier#Text_encoding for an example of alternative encoding, or http://web.archive.org/web/20100408172352/http://prettycode.org/2009/11/12/short-guid/ for example code. EDIT: Or Hans's method above which is much better. If you want to encode a GUID with only A-Z, a-z and 0-9 characters then you will need to look up Base-62 encoding (as opposed to base-64) because you only have 62 characters to encode into.

Stop trying to re-invent the wheel and just use .NET's built in GUID generator:
System.Guid.NewGuid()
which will generate a properly randomly seeded GUID, then simply sub-string it to your limit. Even better if you grab the last 25 chars, instead of the first 25.
PS: I don't consider this a great idea in general, because it's the entire GUID that's considered unique, not part of it, but it should satisfy what you want.

Related

using IndexOf in Mid function

Perhaps this is a simple solution for most, but I can't get this to work like it should according to syntax.
I have this line of text "Part Number123456Price$50.00"
I want to pull the part number out of it, so I use this function...
str = Mid(str, str.IndexOf("Part Number") + 12, str.IndexOf("Price"))
My results are str = "123456Price$50.0" every time. I know the part number can vary in length so I need a solid solution of pulling this out.
It can be confusing to mix the legacy VB string methods (such as Mid) with the .Net string methods (like IndexOf). The VB methods use 1 as the index of the first character while the .Net methods use 0.
The following code will extract the part number from a string
Dim str As String = "Part Number123456Price$50.00"
Dim iPart As Integer = str.IndexOf("Part Number") + 11
Dim iPrice As Integer = str.IndexOf("Price")
str = str.Substring(iPart, iPrice - iPart).Trim
The Mid() function of Visual Basic is documented as having three arguments: (1) a string, (2) the beginning location in the string, and (3) the number of characters to copy.
So if your string is "Part Number123456Price$50.00" and you want to pull the part number as a series of digits, the "123456" part of the string, using the Mid() function then you need to find the beginning of the part number digit string and to then know the number of digits.
If your string is in the variable str then you can find the offset by something like str.IndexOf("Number") + len("Number") which will provide the offset to after the string "Number".
Next you need to find the number of digits so you would do something like str.IndexOf("Price") to find where the text "Price" begins and then subtract from that offset the offset of where the digits begin.
The result of all of this is you need a bit of code something like the following. I have not tested this source as I am not a VB programmer so it may need a tweak and you might want to put some checks on data validity as well.
Dim TextNumber as String = "Number"
Dim TextPrice as String = "Price"
iOffset = str.IndexOf(TextNumber) + len(TextNumber)
str = Mid(str, iOffset, str.IndexOf(TextPrice) - iOffset)
Alternatively, if Price is always the format $00.00, this will also work.
Dim str as String = "Part Number123456Price$50.00"
str = str.Remove(str.IndexOf("Price"))

Get substring until first numeric character

like my title already explained, I want to get a substring of a string (who contains a address) and I would like to have only the street..
It's not possible to only take the text (non-numeric) chars, because then the box will remain.
It's not possible to take substring till first space, because the streetname can contain a space..
For example 'developerstreet 123a' -> would like to have 'developerstreet'
The 'a' is a box number of the house, which I'm not interested in..
How can I do this in VB.NET?
Parsing addresses is notoriously difficult, so I caution you to make sure that you a very deliberate about the choices you make. I would strongly recommend reviewing the documentation provided by the postal service. If these are US addresses, you should start by looking at the USPS Publication 28.
However, to answer your specific question, you can find the index of the first numeric character in a string by using the Char.IsDigit method. You may also want to take a look at the Char.IsNumber method, but that's probably more inclusive than what you really want. For instance, this will get the index of the first numeric character in the input string:
Dim index As Integer = -1
For i As Integer = 0 to input.Length - 1
If Char.IsDigit(input(i)) Then
index = i
Exit For
End If
Next
However, for complex string parsing, like this, I would suggest learning Regular Expressions. Getting the non-numeric portion at the beginning of a string becomes trivial with RegEx:
Dim m As Match = Regex.Match(input, "^\D+")
If m.Success Then
Dim nonNumericPart As String = m.Value
End If
Here is the meaning of the regular expression in the above example:
^ - The matching string must start at the beginning of the line
\D - Any non-numeric character
+ - One or more times
try this:
Private Sub MyFormLoad(sender As Object, e As EventArgs) Handles Me.Load
Dim str As String = "developerstreet 123a"
Dim index As Integer = GetIndexOfNumber(str)
Dim substr As String = str.Substring(0, index)
MsgBox(substr)
End Sub
Public Function GetIndexOfNumber(ByVal str As String)
For n = 0 To str.Length - 1
If IsNumeric(str.Substring(n, 1)) Then
Return n
End If
Next
Return -1
End Function
output will be: developerstreet
text.Substring(0, text.IndexOfAny("0123456789"))

How do I make a random character generator? VB.NET

I want to make a random character generator with numbers in vb.net, I know how to make a random number generator but not numbers mixed with letters. I want it to be around 15-20 characters.
Something like this:
F53Gsfdsj637jfsj5kd8
Thanks ahead!
You're mostly there once you have a random number generator. From there, just pick a random character within a collection of valid characters. The simplest way would be something like:
dim validchars as string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
dim sb as new StringBuilder()
dim rand as new Random()
for i as Integer = 1 to 10
dim idx as Integer = rand.Next(0, validchars.Length)
dim randomChar as char = validchars(idx)
sb.Append(randomChar)
next i
dim randomString = sb.ToString()
Of course, clean up the syntax a bit, and maybe use a constant value for the chars and length, a variable value for the number of digits, etc.

Replacing nth occurrence of string

This should be fairly simple but I'm having one of those days. Can anyone advise me as to how to replace the first and third occurrence of a character within a string? I have looked at replace but that cannot work as the string could be of different lengths. All I want to do is replace the first and third occurrence.
There is an overload of the IndexOf method which takes a start position as a parameter. Using a loop you'll be able to find the position of the first and third occurences. Then you could use a combination of the Remove and Insert methods to do the replacements.
You could also use a StringBuilder to do the replacements. The StringBuilder has a Replace method for which you can specify a start index and a number of characters affected.
aspiringCoder,
Perhaps something like this might be useful to you (in line with what Meta-Knight was talking about <+1>)
Dim str As String = "this is a test this is a test this is a test"
Dim first As Integer
Dim third As Integer
Dim base As Integer = 0
Dim i As Integer
While str.length > 0
If i = 0 Then
first = str.IndexOf("test")
else if i = 2 Then
third = base + str.IndexOf("test")
end if
base = base + str.IndexOf("test")
str = str.Remove(0, str.IndexOf("test") + "test".length -1 )
i++
End While
It might have a one-off error somewhere...but this should at least get you started.

Shortening a repeating sequence in a string

I have built a blog platform in VB.NET where the audience are very young, and for some reason like to express their commitment by repeating sequences of characters in their comments.
Examples:
Hi!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3
LOLOLOLOLOLOLOLOLOLOLOLOLLOLOLOLOLOLOLOLOLOLOLOLOL
..and so on.
I don't want to filter this out completely, however, I would like to shorten it down to a maximum of 5 repeating characters or sequences in a row.
I have no problem writing a function to handle a single repeating character. But what is the most effective way to filter out a repeating sequence as well?
This is what I used earlier for the single repeating characters
Private Shared Function RemoveSequence(ByVal str As String) As String
Dim sb As New System.Text.StringBuilder
sb.Capacity = str.Length
Dim c As Char
Dim prev As Char = String.Empty
Dim prevCount As Integer = 0
For i As Integer = 0 To str.Length - 1
c = str(i)
If c = prev Then
If prevCount < 10 Then
sb.Append(c)
End If
prevCount += 1
Else
sb.Append(c)
prevCount = 0
End If
prev = c
Next
Return sb.ToString
End Function
Any help would be greatly appreciated
You should be able to recursively use the 'Longest repeated substring problem' to solve this. On the first pass you will get two matching sub-strings, and will need to check if they are contiguous. Then repeat the step for one of the sub-strings. Cut off the algo, if the strings are not contiguous, or if the string size become less than a certain number of characters. Finally, you should be able to keep the last match, and discard the rest. You will need to dig around for an implementation :(
Also have a look at this previously asked question: finding long repeated substrings in a massive string