• erlang中通过ip和子网掩码,计算地址范围 【二进制和十进制的转换】


          在程序中,难免用的二进制和十进制之间的转换。遇到一个场景,通过ip和子网掩码,计算地址范围。

    而地址范围为:网络地址+1—— 广播地址 -1 .  网络地址即ip和子网掩码的与的位运算。广播地址为:网络地址的主机位全部换成1。

    打个比方:

    IP为: 192.168.0.0 /16 ,这里,/16表示前16为是网络位,后16位是主机位。

    子网掩码为:255.255.255.0/24,这里,/24表示前24位是网络位,后8位是主机位。

    要求得:地址范围,首先就需求出网络地址和广播地址。进而涉及到二进制和十进制之间的转换。

    十进制转二进制,erlang有BIF内置函数,integer_to_list(X,Y),

    举个栗子:在erlang的shell下,

             > erlang:integer_to_list(255,2), 

           > 11111111

    出来的二进制为8个1。当然,还有函数实现的。

    而二进制转换为十进制中, 在erlang的shell下,

    >2#11111111,输出结果为255.

    erlang没有直接调用二进制转换十进制的函数接口。于是,自己封装一个,如下:

    % 2进制转换10进制 
    testbin(X) ->
              A = integer_to_list(X div 10),
              B = X rem 10,
          erlang:trunc(bin2de(A)) + B.
    
    bin2de([]) -> 0;
    bin2de(A) -> 
             {L1,L2}  = lists:split(1,A),
             case list_to_integer(L1) of
                     1 -> math:pow(2,length(A)) + bin2de(L2);
                     0 -> bin2de(L2)
             end.

      思路很简单,就是除以10,取商和余数,分别做2的阶乘,最后再相加即可.

    测试结果如图:

    用2#数值,在shell下验证,结果一样的.

    附代码如下:

    -module(ip).
    
    -compile(export_all).
    
    
    test() ->
    		%% 读配置文件
    		%	{} = file:consult(),
    		[A,B,C,D] = [192,4,0,1],
    		[A1,B1,C1,D1] = [255,255,255,0],
    			%%计算网络地址
    			IP1  = [A,B,C,D], 
    			IP2  = [A1,B1,C1,D1],
    			NetAddress =  [A band A1, B band B1, C band C1, D band D1],
    			io:format("NetAddress.....~p~n",[NetAddress]),					%%网络地址的十进制
    			% Netaddressbin = lists:map(fun(X) ->  de2bin(X,[]) end, NetAddress),
    			% io:format("Naddressbin.....~p~n",[Netaddressbin]),				%%网络地址的二进制
    
    %%网络地址的二进制
    			Netaddressbin1 = lists:map(fun(X) ->  
    			                                     case length(integer_to_list(X,2))  of
    			                                     		8 -> integer_to_list(X,2);
    			                                     		7 -> "0" ++ integer_to_list(X,2);
    			                                     		6 -> "00" ++ integer_to_list(X,2);
    			                                     		5 -> "000" ++ integer_to_list(X,2);
    			                                     		4 -> "0000" ++ integer_to_list(X,2);
    			                                     		3 -> "00000" ++ integer_to_list(X,2);
    			                                     		2-> "000000" ++ integer_to_list(X,2);
    			                                     		1 -> "0000000" ++ integer_to_list(X,2)
    			                                     	end
    			                                      end, NetAddress),
    			io:format("Naddressbin1.....~p~n",[Netaddressbin1]),				
    
    			% 计算广播地址(广播地址是网络地址的主机位全部换成1后, 在减去1)
    			% BroadcastAddress = 
    			IP1bin = lists:map(fun(X) -> integer_to_list(X,2)  end, IP1),
    			io:format("IP1bin.....~p~n",[IP1bin]),
    
    			IP2bin = lists:map(fun(X) -> integer_to_list(X,2)  end, IP2),
    			io:format("IP2bin.....~p~n",[IP2bin]).
    
    
    % 2进制转换10进制 
    testbin(X) ->
    		  A = integer_to_list(X div 10),
    		  B = X rem 10,
    		  erlang:trunc(bin2de(A)) + B.
    
    bin2de([]) -> 0;
    bin2de(A) -> 
    		 {L1,L2}  = lists:split(1,A),
    		 case list_to_integer(L1) of
    		 		1 -> math:pow(2,length(A)) + bin2de(L2);
    		 		0 -> bin2de(L2)
    		 end.
    
    
    % 10进制转换2进制
    de2bin(0,Acc) ->   Acc;
    de2bin(N,Acc) ->   
    	de2bin(N bsr 1,[((N band 1)+$0)|Acc]).
    
    
    tempData([0])-> [];  
    tempData([Num]) ->
        Result = Num band 1,     
        integer_to_list(Result) ++ tempData([Num bsr 1]).  
     
    de2Binary(Num)->  
        BinaryList = lists:reverse(tempData([Num])),
        LoopTimes = length(BinaryList) rem 8,
        if LoopTimes > 0 -> addBlank(BinaryList,8 - LoopTimes);
           true -> BinaryList
        end.
     
    addBlank(BinaryList,0) -> BinaryList;
    addBlank(BinaryList,Times) ->
        addBlank("0" ++ BinaryList,Times-1).
    

      

  • 相关阅读:
    【k8s学习笔记】Kubernetes API概念
    【k8s学习笔记】使用 kubeadm 部署 v1.18.5 版本 Kubernetes集群
    通过yum展示安装包依赖关系,下载rpm包
    【kubeadm初始化报错】failed to run Kubelet: misconfiguration: kubelet cgroup driver: "cgroupfs" is different from docker cgroup driver: "systemd"
    npm 安装依赖报错解决:npm ERR! Unexpected end of JSON input while parsing near
    【K8s学习笔记】K8s是如何部署应用的?
    【K8S学习笔记】初识K8S 及架构组件
    python包的多种安装方式(内网)
    Python利用ConfigParser读取配置文件
    Tomcat 容器模型
  • 原文地址:https://www.cnblogs.com/unqiang/p/8317061.html
Copyright © 2020-2023  润新知