• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lduchosal / ipnetwork / 822

17 Aug 2025 01:37PM UTC coverage: 93.698% (+0.5%) from 93.223%
822

push

appveyor

web-flow
Feat: parserange (#364)

IP Range to CIDR Converter
A C# utility for converting IP address ranges into optimal CIDR blocks, supporting both IPv4 and IPv6 addresses.
Methods
ParseRange(string range)
Parses an IP range string and returns the optimal CIDR blocks. Throws exceptions on invalid input.
Parameters:

range (string): IP range in format "startIP-endIP" (e.g., "192.168.1.45-192.168.1.65")

Returns: IEnumerable<IPNetwork2> - Collection of optimal CIDR blocks
Throws: ArgumentException, FormatException for invalid input
TryParseRange(string range, out IEnumerable<IPNetwork2> result)
Attempts to parse an IP range string. Returns success/failure without throwing exceptions.
Parameters:

range (string): IP range in format "startIP-endIP"
result (out): Collection of CIDR blocks if successful, null if failed

Returns: bool - True if parsing succeeded, false otherwise

* Feat: parserange
* Chore: Test units
* Chore: upgrade version
* Chore: documentation
* Fix: sonarqube issues
* Fix: formatting
* Fix: 100% coverage

1918 of 2047 relevant lines covered (93.7%)

684512.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.47
/src/System.Net.IPNetwork/IPNetwork2InternalParse.cs
1
// <copyright file="IPNetwork2InternalParse.cs" company="IPNetwork">
2
// Copyright (c) IPNetwork. All rights reserved.
3
// </copyright>
4

5
namespace System.Net;
6

7
using System.Text.RegularExpressions;
8

9
/// <summary>
10
/// The InternalParse methodes.
11
/// </summary>
12
public partial class IPNetwork2
13
{
14
    /// <summary>
15
    /// 192.168.168.100 - 255.255.255.0
16
    ///
17
    /// Network   : 192.168.168.0
18
    /// Netmask   : 255.255.255.0
19
    /// Cidr      : 24
20
    /// Start     : 192.168.168.1
21
    /// End       : 192.168.168.254
22
    /// Broadcast : 192.168.168.255.
23
    /// </summary>
24
    /// <param name="tryParse">Whether to throw exception or not during conversion.</param>
25
    /// <param name="ipaddress">A string containing an ip address to convert.</param>
26
    /// <param name="netmask">A string containing a netmask to convert (255.255.255.0).</param>
27
    /// <param name="ipnetwork">The resulting IPNetwork.</param>
28
    private static bool InternalParse(bool tryParse, string ipaddress, string netmask, out IPNetwork2 ipnetwork)
29
    {
81✔
30
        if (string.IsNullOrEmpty(ipaddress))
81✔
31
        {
5✔
32
            if (!tryParse)
5✔
33
            {
3✔
34
                throw new ArgumentNullException(nameof(ipaddress));
3✔
35
            }
36

37
            ipnetwork = null;
2✔
38
            return false;
2✔
39
        }
40

41
        if (string.IsNullOrEmpty(netmask))
76✔
42
        {
6✔
43
            if (!tryParse)
6✔
44
            {
4✔
45
                throw new ArgumentNullException(nameof(netmask));
4✔
46
            }
47

48
            ipnetwork = null;
2✔
49
            return false;
2✔
50
        }
51

52
        bool ipaddressParsed = IPAddress.TryParse(ipaddress, out IPAddress ip);
70✔
53
        if (!ipaddressParsed)
70✔
54
        {
6✔
55
            if (!tryParse)
6✔
56
            {
4✔
57
                throw new ArgumentException("ipaddress");
4✔
58
            }
59

60
            ipnetwork = null;
2✔
61
            return false;
2✔
62
        }
63

64
        bool netmaskParsed = IPAddress.TryParse(netmask, out IPAddress mask);
64✔
65
        if (!netmaskParsed)
64✔
66
        {
4✔
67
            if (!tryParse)
4✔
68
            {
2✔
69
                throw new ArgumentException("netmask");
2✔
70
            }
71

72
            ipnetwork = null;
2✔
73
            return false;
2✔
74
        }
75

76
        bool parsed = InternalParse(tryParse, ip, mask, out ipnetwork);
60✔
77
        return parsed;
58✔
78
    }
66✔
79

80
    /// <summary>
81
    /// Internal parse an IPNetwork2.
82
    /// </summary>
83
    /// <param name="tryParse">Prevent exception.</param>
84
    /// <param name="network">The network to parse.</param>
85
    /// <param name="cidrGuess">The way to guess CIDR.</param>
86
    /// <param name="sanitize">If true, removes invalid characters and normalizes whitespace from the network string, keeping only valid network address characters (0-9, a-f, A-F, ., /, :, and spaces).</param>
87
    /// <param name="ipnetwork">The resulting IPNetwork.</param>
88
    /// <exception cref="ArgumentNullException">When network is null.</exception>
89
    /// <exception cref="ArgumentException">When network is not valid.</exception>
90
    /// <returns>true if parsed, otherwise false</returns>
91
    private static bool InternalParse(bool tryParse, string network, ICidrGuess cidrGuess, bool sanitize, out IPNetwork2 ipnetwork)
92
    {
4,001,025✔
93
        if (string.IsNullOrEmpty(network))
4,001,025✔
94
        {
5✔
95
            if (!tryParse)
5✔
96
            {
3✔
97
                throw new ArgumentNullException(nameof(network));
3✔
98
            }
99

100
            ipnetwork = null;
2✔
101
            return false;
2✔
102
        }
103

104
        if (sanitize)
4,001,020✔
105
        {
4,001,013✔
106
            network = Regex.Replace(network, @"[^0-9a-fA-F\.\/\s\:]+", string.Empty, RegexOptions.None, TimeSpan.FromMilliseconds(100));
4,001,013✔
107
            network = Regex.Replace(network, @"\s{2,}", " ", RegexOptions.None, TimeSpan.FromMilliseconds(100));
4,001,013✔
108
            network = network.Trim();
4,001,013✔
109
        }
4,001,013✔
110

111
        StringSplitOptions splitOptions = sanitize ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None;
4,001,020✔
112
        string[] args = network.Split([' ', '/'], splitOptions);
4,001,020✔
113
        
114
        if (args.Length == 1)
4,001,020✔
115
        {
54✔
116
            string cidrlessNetwork = args[0];
54✔
117
            if (cidrGuess.TryGuessCidr(cidrlessNetwork, out byte cidr))
54✔
118
            {
49✔
119
                bool parsed = InternalParse(tryParse, cidrlessNetwork, cidr, out ipnetwork);
49✔
120
                return parsed;
49✔
121
            }
122

123
            if (!tryParse)
5✔
124
            {
2✔
125
                throw new ArgumentException("network");
2✔
126
            }
127

128
            ipnetwork = null;
3✔
129
            return false;
3✔
130
        }
131
        
132
        if (args.Length == 2)
4,000,966✔
133
        {
4,000,962✔
134
            if (byte.TryParse(args[1], out byte cidr1))
4,000,962✔
135
            {
4,000,917✔
136
                bool parsed2 = InternalParse(tryParse, args[0], cidr1, out ipnetwork);
4,000,917✔
137
                return parsed2;
4,000,917✔
138
            }
139

140
            bool parsed3 = InternalParse(tryParse, args[0], args[1], out ipnetwork);
45✔
141
            return parsed3;
43✔
142
        }
143
        
144
        if (!tryParse)
4✔
145
        {
×
146
            throw new ArgumentNullException(nameof(network));
×
147
        }
148

149
        ipnetwork = null;
4✔
150
        return false;
4✔
151
    }
4,001,018✔
152

153
    /// <summary>
154
    /// 192.168.168.100 255.255.255.0
155
    ///
156
    /// Network   : 192.168.168.0
157
    /// Netmask   : 255.255.255.0
158
    /// Cidr      : 24
159
    /// Start     : 192.168.168.1
160
    /// End       : 192.168.168.254
161
    /// Broadcast : 192.168.168.255.
162
    /// </summary>
163
    /// <param name="tryParse">Whether to throw exception or not during conversion.</param>
164
    /// <param name="ipaddress">An ip address to convert.</param>
165
    /// <param name="netmask">A netmask to convert (255.255.255.0).</param>
166
    /// <param name="ipnetwork">The resulting IPNetwork.</param>
167
    private static bool InternalParse(bool tryParse, IPAddress ipaddress, IPAddress netmask, out IPNetwork2 ipnetwork)
168
    {
4,001,090✔
169
        if (ipaddress == null)
4,001,090✔
170
        {
4✔
171
            if (!tryParse)
4✔
172
            {
2✔
173
                throw new ArgumentNullException(nameof(ipaddress));
2✔
174
            }
175

176
            ipnetwork = null;
2✔
177
            return false;
2✔
178
        }
179

180
        if (netmask == null)
4,001,086✔
181
        {
4✔
182
            if (!tryParse)
4✔
183
            {
2✔
184
                throw new ArgumentNullException(nameof(netmask));
2✔
185
            }
186

187
            ipnetwork = null;
2✔
188
            return false;
2✔
189
        }
190

191
        var uintIpAddress = ToBigInteger(ipaddress);
4,001,082✔
192
        bool parsed = TryToCidr(netmask, out byte cidr2);
4,001,082✔
193
        if (!parsed)
4,001,082✔
194
        {
4✔
195
            if (!tryParse)
4✔
196
            {
2✔
197
                throw new ArgumentException("netmask");
2✔
198
            }
199

200
            ipnetwork = null;
2✔
201
            return false;
2✔
202
        }
203

204
        var ipnet = new IPNetwork2(uintIpAddress, ipaddress.AddressFamily, cidr2);
4,001,078✔
205
        ipnetwork = ipnet;
4,001,078✔
206
        return true;
4,001,078✔
207
    }
4,001,084✔
208

209
    /// <summary>
210
    /// 192.168.168.100/24
211
    ///
212
    /// Network   : 192.168.168.0
213
    /// Netmask   : 255.255.255.0
214
    /// Cidr      : 24
215
    /// Start     : 192.168.168.1
216
    /// End       : 192.168.168.254
217
    /// Broadcast : 192.168.168.255.
218
    /// </summary>
219
    /// <param name="tryParse">Whether to throw exception or not during conversion.</param>
220
    /// <param name="ipaddress">A string containing an ip address to convert.</param>
221
    /// <param name="cidr">A byte representing the CIDR to be used in conversion (/24).</param>
222
    /// <param name="ipnetwork">The resulting IPNetwork.</param>
223
    private static bool InternalParse(bool tryParse, string ipaddress, byte cidr, out IPNetwork2 ipnetwork)
224
    {
4,001,066✔
225
        if (string.IsNullOrEmpty(ipaddress))
4,001,066✔
226
        {
6✔
227
            if (!tryParse)
6✔
228
            {
2✔
229
                throw new ArgumentNullException(nameof(ipaddress));
2✔
230
            }
231

232
            ipnetwork = null;
4✔
233
            return false;
4✔
234
        }
235

236
        bool ipaddressParsed = IPAddress.TryParse(ipaddress, out IPAddress ip);
4,001,060✔
237
        if (!ipaddressParsed)
4,001,060✔
238
        {
37✔
239
            if (!tryParse)
37✔
240
            {
1✔
241
                throw new ArgumentException("ipaddress");
1✔
242
            }
243

244
            ipnetwork = null;
36✔
245
            return false;
36✔
246
        }
247

248
        bool parsedNetmask = TryToNetmask(cidr, ip.AddressFamily, out IPAddress mask);
4,001,023✔
249
        if (!parsedNetmask)
4,001,023✔
250
        {
3✔
251
            if (!tryParse)
3✔
252
            {
1✔
253
                throw new ArgumentException("cidr");
1✔
254
            }
255

256
            ipnetwork = null;
2✔
257
            return false;
2✔
258
        }
259

260
        bool parsed = InternalParse(tryParse, ip, mask, out ipnetwork);
4,001,020✔
261
        return parsed;
4,001,020✔
262
    }
4,001,062✔
263
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc