[关闭]
@songpfei 2016-04-06T07:24:52.000000Z 字数 3754 阅读 1801

识别有效的IP地址和掩码并进行分类统计

OJ_算法


1. 题目描述

请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。

所有的IP地址划分为 A,B,C,D,E五类

A类地址1.0.0.0~126.255.255.255;

B类地址128.0.0.0~191.255.255.255;

C类地址192.0.0.0~223.255.255.255;

D类地址224.0.0.0~239.255.255.255;

E类地址240.0.0.0~255.255.255.255

私网IP范围是:

10.0.0.0~10.255.255.255

172.16.0.0~172.31.255.255

192.168.0.0~192.168.255.255

子网掩码为前面是连续的1,然后全是0

2. 输入

多行字符串。每行一个IP地址和掩码,已~隔开。如:

10.70.44.68~255.254.255.0

1.0.0.1~255.0.0.0

192.168.0.2~255.255.255.0

19..0.~255.255.255.0

3.输出

统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开,根据上面的IP,可以得到:

1.0.0.1~255.0.0.0 ----A类

192.168.0.2~255.255.255.0 ----C类,私有

10.70.44.68~255.254.255.0----错误的掩码

19..0.~255.255.255.0-----错误的IP

可以得到统计数据如下:

1 0 1 0 0 2 1

4. 代码实现

  1. //// huawei_test.cpp : 定义控制台应用程序的入口点。
  2. ////
  3. #include<stdio.h>
  4. #include<string.h>
  5. #include<stdlib.h>
  6. #define N 50
  7. int ConvertSubIPToInt(const char* sub_ip)
  8. {
  9. if (sub_ip == NULL)
  10. return -1;
  11. int length = strlen(sub_ip);
  12. if (length < 1 || length>3)
  13. return -1;
  14. int sub_value = 0;
  15. for (int i = 0; i < length; i++)
  16. {
  17. if (sub_ip[i]<'0' || sub_ip[i]>'9')
  18. return -1;
  19. sub_value = 10 * sub_value + sub_ip[i] - '0';
  20. }
  21. return sub_value;
  22. }
  23. bool isIPAddressValid(const char* pszIPAddr, int *subIPValue)
  24. {
  25. // 请在此处实现
  26. if (pszIPAddr == NULL || *pszIPAddr == '\0')
  27. return false;
  28. int szIPAddr_length = strlen(pszIPAddr);
  29. int index_start = 0;
  30. int index_end = szIPAddr_length - 1;
  31. //去除前边的空格
  32. while (pszIPAddr[index_start] == ' ')
  33. {
  34. ++index_start;
  35. }
  36. //去除后边空格
  37. while (pszIPAddr[index_end] == ' ')
  38. {
  39. --index_end;
  40. }
  41. if (index_end <= index_start)
  42. return false;
  43. int ip_length = index_end - index_start + 2;
  44. char *temp_ip=(char*)malloc(ip_length);
  45. strncpy(temp_ip, pszIPAddr + index_start, ip_length-1);
  46. temp_ip[ip_length - 1] = '\0';
  47. char* sub_ip = strtok(temp_ip, ".");
  48. int sub_ip_count = 0;
  49. while (sub_ip != NULL)//ip分段,计数分段ip,并转换为0-255
  50. {
  51. sub_ip_count++;
  52. if (sub_ip_count > 4)
  53. {
  54. free(temp_ip);
  55. return false;
  56. }
  57. subIPValue[sub_ip_count - 1] = ConvertSubIPToInt(sub_ip);
  58. if (subIPValue[sub_ip_count - 1] < 0 || subIPValue[sub_ip_count - 1] > 255)
  59. {
  60. free(temp_ip);
  61. return false;
  62. }
  63. sub_ip = strtok(NULL, ".");
  64. }
  65. free(temp_ip);
  66. if (sub_ip_count != 4)
  67. return false;
  68. else
  69. return true;
  70. }
  71. bool isValidMask(int* mask_value)
  72. {
  73. unsigned int mask_int32 = 0;
  74. for (int i = 0; i < 4; i++)
  75. {
  76. mask_int32 += ((unsigned int)mask_value[i]) << ((3 - i) * 8);
  77. }
  78. mask_int32 = ~mask_int32 + 1;
  79. if ((mask_int32 & (mask_int32 - 1)) == 0)//判断是否W为2^n次方
  80. return true;
  81. else
  82. return false;
  83. }
  84. bool isPrivateIP(int*ip_value)
  85. {
  86. if (ip_value[0] == 10)
  87. return true;
  88. if (ip_value[0] == 172 && ip_value[1] >= 16 && ip_value[1] <= 31)
  89. return true;
  90. if (ip_value[0] == 192 && ip_value[1] == 168)
  91. return true;
  92. return false;
  93. }
  94. bool IPAnalyse(char* str, int* result)
  95. {
  96. if (str == NULL)
  97. return false;
  98. char* p = strchr(str, '~');
  99. if (p == NULL)
  100. return false;
  101. else
  102. *p = '\0';
  103. char* ip = str;
  104. char* mask = p + 1;
  105. int sub_IP_value[4];
  106. int sub_mask_value[4];
  107. if (!isIPAddressValid(ip, sub_IP_value) || !isIPAddressValid(mask, sub_mask_value))
  108. {
  109. result[5]++;
  110. return true;//ip无效
  111. }
  112. if (!isValidMask(sub_mask_value))
  113. {
  114. result[5]++;
  115. return true;//子掩码无效
  116. }
  117. if (isPrivateIP(sub_IP_value))
  118. result[6]++;
  119. if (sub_IP_value[0] >= 1 && sub_IP_value[0] <= 126)//A类
  120. {
  121. result[0]++;
  122. return true;
  123. }
  124. if (sub_IP_value[0] >= 128 && sub_IP_value[0] <= 191)//B类
  125. {
  126. result[1]++;
  127. return true;
  128. }
  129. if (sub_IP_value[0] >= 192 && sub_IP_value[0] <= 223)//C类
  130. {
  131. result[2]++;
  132. return true;
  133. }
  134. if (sub_IP_value[0] >= 224 && sub_IP_value[0] <= 239)//D类
  135. {
  136. result[3]++;
  137. return true;
  138. }
  139. if (sub_IP_value[0] >= 240)//E类
  140. {
  141. result[4]++;
  142. return true;
  143. }
  144. return false;
  145. }
  146. int main()
  147. {
  148. char str[N];
  149. int statistic_info[7] = { 0 };
  150. while (fgets(str, sizeof(str), stdin) != NULL)
  151. {
  152. if (strlen(str) < 2)
  153. break;
  154. char* p = strrchr(str, '\n');
  155. if (p != NULL)
  156. *p = '\0';
  157. IPAnalyse(str, statistic_info);
  158. }
  159. for (size_t i = 0; i < 7; i++)
  160. {
  161. printf("%d ", statistic_info[i]);
  162. }
  163. return 0;
  164. }
  1. 重点: 判断子网掩码的方法
    下面给的例子是这样的:先验证是否为合法IP,然后将掩码转化成32无符号整型,取反为000...00111...1,然后再加1为00...01000...0,此时为2^n,如果满足就为合法掩码。
  1. int IsSubnetMask(char* subnet)
  2. {
  3. if(if_a_string_is_a_valid_ipv4_address (subnet))
  4. {
  5. unsigned int b = 0, i, n[4];
  6. sscanf(subnet, "%u.%u.%u.%u", &n[3], &n[2], &n[1], &n[0]);
  7. for(i = 0; i < 4; ++i) //将子网掩码存入32位无符号整型
  8. b += n[i] << (i * 8);
  9. b = ~b + 1;
  10. if((b & (b - 1)) == 0) //判断是否为2^n
  11. return 1;
  12. }
  13. return 0;

参见:http://blog.sina.com.cn/s/blog_6a6094d5010128fg.html

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注