prefix length calculation for ipv6 addresses - c++

I want to calculate the prefix length for Ipv4 and Ipv6 addresses . The subnet mask can be in the form of a string(1 , 32 ,97 etc) or in the dotted format(255.255.0.0) . I want to impose the following conditions.
1)For ipv4 , both the formats should be allowed . But when we cast from the string to an unsigned , the prefix length should not be more than 31
2)For ipv6 only the prefix length is allowed . It should not be more than 127
Although I can do the above calculations pretty easily by passing a sub routine , I have been asked to use boost defined classes and methods for the same .
Can anyone suggest the appropriate boost methods for the above . I've tried to do some searching , but unable to do so.
The paramaters can be the mask in the prefix length string format (16 , 97) or in the dotted format , and maybe the address(string) . The boost methods should be able to determine the prefix length as an unsigned based on the restrictions already mentioned.

Useful boost parts are regex, to analyze what you got, and lexical_cast to turn a string into a number.

Related

Find all possible positions for a wildcard in string

Let's say I have the string "hello" now I would like find all possible combinations to replace each character in the string with a wildcard. Where string length -1 wildcards are possible (4 in example).
e.g
_ello
h_llo
he_lo
hel_o
hell_
__llo
_e_lo
etc. (should be 30 possible one in this case)
Are there any simple algorithms for this?

Store 32 bit value as C string in most efficient form

I am trying to find the most efficient way to encode 32 bit hashed string values into text strings for transmission/logging in low bandwidth environments. Complex compression can't be used because the hash values need to be contained in human readable text strings when logged and sent between client and host.
Consider the following contrived examples:
given the key/value map
table[0xFE12ABCD] = "models/texture/red.bmp";
table[0x3EF088AD] = "textures/diagnostics/pink.jpg";
and the string formats:
"Loaded asset (0x%08x)"
"Replaced (0x%08x) with (0x%08x)"
they could be printed as:
"Loaded asset models/texture/red.bmp"
"Replaced models/texture/red.bmp with textures/diagnostics/pink.jpg"
Or if the key/value map is known by the client and server:
"Loaded asset (0xFE12ABCD)"
"Replaced (0xFE12ABCD) with (0x3EF088AD)"
The receiver can then scan for the (0xNNNNNNNN) pattern and expand it locally.
This is what I am doing right now but I would like to find a way to represent the 32 bit value more efficiently. A simple step would be to use a better identifying token:
"Loaded asset $FE12ABCD"
"Replaced $1000DEEE with $3EF088AD"
Which already reduces the length of each token - $ is not used anywhere else so it is reasonable.
However, what other options are there to make that 32 bit value even smaller? I can't use an index - it has to be a full 32 bit value because in some cases the generator of the string has the hash and sometimes it has a string it will hash immediately.
A common solution is to use Base-85 coding. You can code four bytes into five Base-85 digits, since 855 > 232. Pick 85 printable characters and assign them to the digit values 0..84. Then do base conversion to go either way. Since there are 94 printable characters in ASCII, it is usually easy to find 85 that are "safe" in whatever constrains your strings to be "readable".

convert IPv6 to decimal (ip number)

I've been trying to convert all ip addresses (both IPv4 and IPv6) to decimal format (ip number), store those numbers in the database which already contains ip ranges and get country location based on user's IP. Although this can be done easily for IPv4 addresses, I run into a stone wall when it comes to IPv6 ones.
say the fallowing IP should be converted to decimal
2a03:29ff:ffff:ffff:ffff:ffff:ffff:ffff
I tested it through some online services (that convert IPv6 to decimal) simply to check the consistency, namely what my final result should look like.
https://www.ultratools.com/tools/decimalCalc
http://www.ipaddressguide.com/ipv6-to-decimal
both returned the same number - 55844004574745424515003293805316145151
now within my coldfusion code I first removed : from the IP to get hex format and then tried to convert it to decimal with this
<cfset ipv6='2a0329ffffffffffffffffffffffffff'>
<cfoutput>#inputBaseN(ipv6, 16)#</cfoutput>
resulting in error msg
is it possible to achieve this? what do you think about my approach for handling this sort of thing? is there a better way to get country location based on IP? note: do not want to rely on any online service!!
InputBaseN is trying to convert to an Integer, and that value is too big for the maximum Integer value, hence why the error is claiming it is not a valid number.
(The error is actually only thrown for hex values of 8000000000000000 and higher (i.e. 263 or higher, the max for Long) - between 231 and 263-1 the InputBaseN function doesn't tell you it has failed but incorrectly returns zero.)
The solution is to create a BigInteger, which doesn't have a max value, and convert from your base 16 string like so:
BigInt = createObject("java","java.math.BigInteger").init( ipv6 , 16 ).toString()
I think you wont be able to get cf to generate a decimal that large. You need to do it manually as a string.

TFileListBox Mask Issue

The definition for TFileListBox.Mask is:
Set Mask to a regular expression to limit the list box to files that
match the mask. The value of the mask is a file name that may include
wildcards. The asterisk (*) is a wildcard which matches any number of
arbitrary characters. The question mark (?) is a wildcard which
matches a single arbitrary character. The file mask *.* displays all
files, which is the default value.
The * wildcard works fine. However the ? wildcard does not seem to work. I am trying to filter data files that have 14 digits. Examples would be:
012345678909090.dat
012345678900123.dat
012345678901234.dat
012345678901235.dat
012345678901236.dat
If you were to set the mask to *.23?.dat the last four data files are returned. However, the second data file (012345678900123.dat) should not be returned if the ? wildcard is doing its job.
By the way, this "problem" occurs in Raize Components TRzFileListBox and I imagine all others that derive from TFileListBox, too.
Any help with this?
Thanks in advance.

How to set the ASN1 NumericString type to SubjectDN OID?

I have a working program, which generates a CSR, from specified SubjectDN string (example: 2.5.4.3=Name Surname, 1.2.300.38.22=12345678), using MS Crypto API. I use the function: CertStrToName(), to encode it, and everything is working fine, except one thing: all OID values is created with ASN1 type PrintableString.
Is there any way to make OID 1.2.300.38.22 of type NumericString ?
So, i've found 2 ways to fix that:
1. programmatically, using the function CryptEncodeObject()
2. my cryptoprovider supports some specific oid's, so i could use the CertStrToName with them, without touching the code.
Microsoft's CertStrToName()-method is not RFC 4514 compliant. Instead of treating #-encodings as the AttributeValue-encodings, it treats them as values to be encoded in OctetStrings. This means that not all Distringuished Names can be generated from the CertStrToName-method - in particular yours cannot be generated.
The string representation of the distinguished name is the one from RFC 4514: String Representation of Distinguished Names.
Here you can see that if the attribute-type is in the dotted-decimal form, you are actually supposed to encode the attribute-value as a # followed by a BER encoding in hexadecimal of the ASN.1 AttributeValue. I.e.:
2.5.4.3=Name Surname, 1.2.300.38.22=#12083132333435363738
You can also read in the documentation for CertStrToName() that:
A value that starts with a number sign (#) is treated as ASCII
hexadecimal and converted to a CERT_RDN_OCTET_STRING. Embedded white
space is ignored. For example, 1.2.3 = # AB CD 01 is the same as
1.2.3=#ABCD01.