There is no advantage that I can see for you to use a MemoryBlock over 4 integer variables. The question is (what neither I nor, I think, Tim understands), why you need the binary representation at all? What are you doing with the bits you count? .[/quote] There are a few functions that I am using to compare Network Mask Octet against a Subnet Mask Octet to see which bits fall through. I only know how to do that bit by bit in binary form.
n2 = SubnetMask2Dec
Select Case n2
Case 0
m2 = 0
Case 128
m2 = 1
Case 192
m2 = 2
Case 224
m2 = 3
Case 240
m2 = 4
Case 248
m2 = 5
Case 252
m2 = 6
Case 254
m2 = 7
Case 255
m2 = 8
End Select
Can be written as
dim i, mask as integer
n2 = SubnetMask2Dec
m2 = 8
mask = 254
for i = 1 to 8
if (mask and n2) <> n2 then exit
m2 = m2 - 1
mask = bitwise.shiftleft(mask, 1)
next
So, for example, with 192.168.1.1/255.255.255.0, an AND of each octet to its mask would give me 192.168.1.0. With 172.172.200.19/255.255.128.0, I’d get 172.168.128.0. Subtract each octet of the mask from 256 to find the range of each IP octet. With the latter example, that would tell me that I could go from 172.172.128.0 thru 172.172.255.255.
Didn’t follow all of this thread, but I think this code:
Dim DecimalAddress as String = Str(FirstOctet) + "." + Str(SecondOctet) + "." + Str(ThirdOctet) + "." + Str(FourthOctet)
might be slow. Try this instead:
dim DecimalAddressParts() as string=Array(Str(FirstOctet),Str(SecondOctet),Str(ThirdOctet), Str(FourthOctet))
dim DecimalAddress as String =join(DecimalAddressParts,".")
Tim/Kem thank you as the bitwise function is exactly what I was trying to “recreate” in my non efficient attempt of integer --> string(binary) --> integer. The basis of this simple set of code will replace two functions for me
This does the Binary 1+0 comparison for every bit (bitwise.BitAnd).
Quite the detour, but the learning experience has been great. Thanks all!
dim network1, network2, network3, network4, Subnet1, subnet2, subnet3, subnet4 as integer
Network1 = 10
Subnet1 = 255
network2 = 20
Subnet2 = 255
network3 = 5
subnet3 = 255
network4 = 1
subnet4 = 0
Dim Results1 as Integer = Bitwise.BitAnd(Network1,Subnet1)
Dim Results2 as Integer = Bitwise.BitAnd(Network2,Subnet2)
Dim Results3 as Integer = Bitwise.BitAnd(Network3,Subnet3)
Dim Results4 as Integer = Bitwise.BitAnd(Network4,Subnet4)
MsgBox "Results: " + Str(Results1)+"."+Str(Results2)+"."+Str(Results3)+"."+Str(Results4)
Yeah, once upon a time, And, Or, and Xor only did boolean comparisons, hence the need for the Bitwise functions. Later, they were changed to do double-duty as bitwise operators, but many didn’t realize.
Now we just need operators for ShiftLeft and ShiftRight and we’d be set.
But Xor will cancel bits out, so make sure it’s not Or you want instead. (And it actually should be And if you’re talking about applying the subnet mask).
Mike, since you got me interested, I wrote these two methods. Feel free to use any part, if it helps.
Protected Function ToMemoryBlock(stringValue As String) As MemoryBlock
// Converts a string representation of an address or mask to a MemoryBlock
dim parts() as string = stringValue.SplitB( "." )
dim mb as new MemoryBlock( 4 )
dim lastIndex as integer = parts.Ubound
if lastIndex > 3 then lastIndex = 3
for byteIndex as integer = 0 to lastIndex
mb.Byte( byteIndex ) = parts( byteIndex ).Val
next
return mb
End Function
Protected Function ValidSubnetMask(mask As String, ByRef maskMB As MemoryBlock) As Boolean
// Validates a subnet mask as valid.
// Returns a MemoryBlock of the mask as bytes, but only if it's valid
dim r as Boolean = true
// Make sure it's just digits and periods
dim rx as new RegEx
rx.SearchPattern = "[^\\d.]"
if rx.Search( mask ) <> nil then // Contains something other than digits or periods
r = false
end if
if r and mask.CountFieldsB( "." ) <> 4 then
r = false
end if
if r then
maskMB = ToMemoryBlock( mask )
// Do the validation of the octets
if maskMB.Byte( 0 ) <> 255 then
r = false
else
static validOctets() as UInt32 = Array( &b00000000, &b10000000, &b11000000, &b11100000, &b11110000, &b11111000, &b11111100, &b11111110 )
for i as integer = 1 to 3
if i <> 3 and maskMB.Byte( i ) = 255 then continue // Last octet can't be 255
if maskMB.Byte( i - 1 ) = 255 then
if validOctets.IndexOf( maskMB.Byte( i ) ) <> -1 then continue
else // The previous value is something less then 255 so this has to be 0
if maskMB.Byte( i ) = 0 then continue
end if
// If we get here, can't be valid
r = false
exit
next i
end if // maskMB.Byte( 0 ) <> 255
end if
if not r then
maskMB = nil
end if
return r
End Function
Awesome thanks Kem! I rewrote many of my functions with only converting from IP Decimal format to a 32bit decimal word and performing all functions against that. It works very well and fast, however when I get to the array/listbox loading I am still trying to increase efficiencies there. Ill check out your code so I can add it in Thank you again!
This is my loop that runs all subnet iterations. I dramatically decreased its size and complexity.
// Get ClassFull Boundary Starting Point
NetworkSubnetID = fGetClassFullNetwork(Input_StartIP_32BitDecimalWord,Input_SubnetMask_32BitDecimalWord)
BitsStolen = SubnetPrefixLength - ClassFullSubnetPrefix
CalculateLoopEnd = 2^BitsStolen
for y = 0 to CalculateLoopEnd // 2^ Number of Stolen Bits on that class
HostFirst_32BitDecimalWord = NetworkSubnetID+1
ReverseSubnetMask = Bitwise.OnesComplement(Input_SubnetMask_32BitDecimalWord)
BroadCastID_32BitDecimalWord = NetworkSubnetID+ReverseSubnetMask
HostLast_32BitDecimalWord = BroadCastID_32BitDecimalWord-1
NetworkSubnetID = BroadCastID_32BitDecimalWord+1
Next y
BTW are there any speed differences with Xojo using For/Next, While/Wend, Do/Loop? I will try a few of the tonight to see if I can increase that speed a bit. Thanks again!