0

I'm trying to convert one IP from string to Decimal using split and aggregate. Specifically I made this question about Split and Aggregate not other solutions like IpAddress or similar.

For the "192.168.0.1" ip, the number must be 3232235521

var decimalIP = "192.168.0.1".Split(".").Aggregate(0, (numIP, segment) => {
    numIP = numIP<< 8;
    return numIP + Decimal.Parse(segment);
});

This method does not work:

Decimal number = "192.168.0.1".Aggregate(0m, (numIP, segment) => {
    numIP = (long)numIP << 8;
    return (Decimal)(numIP + Decimal.Parse(segment));
});

I was also trying

var segments = "192.168.0.1".Select(segment => Decimal.Parse(segment));
var reverse = segments.Reverse();

Decimal reverseSumm = reverse.Aggregate(0m, (numIP, segment) => {
    numIP = (long)numIP << 8;
    return (Decimal)(numIP + segment);
});

Decimal directSumm = segments.Aggregate(0m, (numIP, segment) => {
    numIP = (long)numIP << 8;
    return (Decimal)(numIP + segment);
});

The number

How to do it?

5
  • 3
    Are you trying to learn the Aggregate function? If not, is there any reason you can't use System.Net.IPAddress.Parse for this task? Then you can use System.BitConverter.ToUInt32(ip.GetAddressBytes(), 0) to "aggregate" the bytes. In any case you should make sure whether you want them bytes to be "aggregated" from left to right or the other way around (Little- / Big-Endian). Edit: Judging by your edit, you might actually need to use .Reverse().ToArray() to reverse the byte order. Still the result would be 3232235521 and not 3194548201 Commented Aug 9, 2021 at 16:25
  • @TimSchmelter I get negative number, and the integer would be overflow Commented Aug 9, 2021 at 16:30
  • 2
    Does this answer your question? Convert IP Address to UInt32/UInt64 in .NET Core and How do you parse an IP address string to a uint value in C#? and How to convert an IPv4 address into a integer in C#? Commented Aug 9, 2021 at 16:31
  • @MrPaulch I was times by 255 instead of 256... I'm mistake! Commented Aug 9, 2021 at 16:33
  • IPv4 addresses are natively UInt32 values. Why would you want decimal when uint is right there? Also System.Net.IPAddress.Parse() Commented Aug 9, 2021 at 16:58

1 Answer 1

0

There are multiple issues here.

  • Your question is constantly changing
  • Bit shift operations are not allowed for decimals as they are floating point numbers
  • Your aggregate function needs to have the same return value type as its input value type
  • You can't add a string to a numeric type without parsing it to a numeric type first.
  • You can't use an int type as it uses 32 bit to represent a range including negative numbers, but uint is suited to represent a 32 bit positive number - which an IP address basically is.

This would work:

Decimal directSum = "192.168.0.1".Split(".").Aggregate(0m, (numIP, segment) => {
    numIP = (uint)numIP << 8;
    return numIP + Decimal.Parse(segment);
});

But what this is basically doing is casting inside a loop, which is not the most elegant way to do things. I'ld recommend operating with uint and doing the cast once you are finished:

            Decimal directSum = "192.168.0.1".Split(".").Aggregate(0u, (numIP, segment) => {
                numIP = numIP << 8;
                return numIP + uint.Parse(segment);
            });

Or if you want to keep using var:

            var directSum = (decimal) "192.168.0.1".Split(".").Aggregate(0u, (numIP, segment) => {
                numIP = numIP << 8;
                return numIP + uint.Parse(segment);
            });

I`d also propose to use uint and not decimal for your result, if it's not a hard requirement to use decimal:

            var directSum = "192.168.0.1".Split(".").Aggregate(0u, (numIP, segment) => {
                numIP = numIP << 8;
                return numIP + uint.Parse(segment);
            });
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.