中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [已结][超级感谢netbenton和其他老师的帮助]IP类型转换
« [1] [2] »
作者:
标题: [已结][超级感谢netbenton和其他老师的帮助]IP类型转换 上一主题 | 下一主题
cz1314
初级用户





积分 64
发帖 43
注册 2007-11-12
状态 离线
『楼 主』:  [已结][超级感谢netbenton和其他老师的帮助]IP类型转换

现在ip的表示方式有2种:

一种是数字型 例如:3758096383
另一种是大家常用的点分十进制 例如:223.255.255.255

我来解释下这2中ip 格式是如何进行转换的。
这个过程可以用windows的计算器实现,
首先打开科学计算方式,在十进制下输入数字型ip,转换成16进制
比如  3758096383  转换为16进制就是 DFFFFFFF
那么这个IP实际上就是dF.FF.FF.FF
分别把DF和FF转化为十进制,那么就是  223和255
最后的转换结果就是:233.255.255.255。原理比较简单。

我这里有一个文本ip.txt,内容如下:

=====txt=====
50331648        50331903        US
50331904        50332671        US
50332672        50332927        US
50332928        50333695        US
50333696        50333951        US
... ...
... ...
50333952        50334719                US
============

文本中的数字就是 ip地址。
我想写个批处理能把这个文本中的数字型ip 转换成点分十进制格式,并输出到另外一个文本保存。

当中涉及到10进制和16进制的多次转换和输出。由于本人批处理水平太菜,整了3天也没整出来,
特在此请象各位大侠请教,感谢万分! !



感谢各位老师的帮助。  请打下看看下面这段代码如何? 因为ip.txt数据量巨大,有700万条。


=====
echo off&setlocal enabledelayedexpansion
set hex=0123456789ABCDEF
for /f "usebackq tokens=1,2*" %%i in ("ip.txt") do (
   if not "%%i"=="" set var=&set h=&set s=%%i&call:lp
   set/a ha=0x!var:~-8,2!,hb=0x!var:~-6,2!,hc=0x!var:~-4,2!,hd=0x!var:~-2,2!
   set str1=!ha!.!hb!.!hc!.!hd!
   if not "%%j"=="" set var=&set h=&set s=%%j&call:lp
   set/a ha=0x!var:~-8,2!,hb=0x!var:~-6,2!,hc=0x!var:~-4,2!,hd=0x!var:~-2,2!
   set str2=!ha!.!hb!.!hc!.!hd!
   >>ip1.txt echo !str1!      !str2!     %%k
  )
start "" "ip1.txt"
pause&goto :eof
:lp
    set/a m=s/16,n=s%%16
    set n=!hex:~%n%,1!
    set h=%n%%h%
    if %m% geq 16 set s=%m%&goto lp
    set m=!hex:~%m%,1!
    set var=0%m%%h%
=========


[ Last edited by HAT on 2009-1-16 at 15:44 ]

2009-1-3 06:23
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
3742668
荣誉版主





积分 2013
发帖 718
注册 2006-2-18
状态 离线
『第 2 楼』:  



  Quote:
ping -n 1 -w 1 50331903

用for+ping很简单.

2009-1-3 11:06
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
pooronce
中级用户





积分 484
发帖 250
注册 2007-6-5
状态 离线
『第 3 楼』:  


@echo off
del IP_out.txt
for /f "tokens=1,2,3" %%i in (ip.txt) do @call :output %%i %%j %%k
type IP_out.txt
pause&goto :eof

:output
set ip1=
set ip2=
call :ipconv "ip1" %1
call :ipconv "ip2" %2

echo %ip1%         %ip2%         %3>>IP_out.txt


goto :eof

:ipconv
rem 注意,此过程只能IP首位在127以下,即2147483647最大
set varname=
set tmpIP=
set _IP_a=
set _IP_b=
set _IP_d=

if %~2 gtr 2147483646 (echo 数字太大,转呼过程2&call :ipconv2 %1 %2&goto :eof)
set "varname=%~1"
set tmpIP=%2

set /a _IP_a=tmpIP^>^>24
set /a _IP_b=(tmpIP^>^>16)^&255
set /a _IP_c=(tmpIP^>^>8)^&255
set /a _ip_d=tmpIP^&255

set %varname%=%_IP_a%.%_IP_b%.%_IP_c%.%_IP_d%
goto :eof

:ipconv2
set tmpIP=
set varname=
rem Hmmm...用ping的方式应该无限制吧 囧
set "varname=%~1"
set tmpIP=%2

::这行的比较搞不定,不搞了,哪位有兴趣试试吧,过了31位的数就不能直接比较了,要字符串比较很麻烦呀很麻烦
::if %tmpIP% gtr 4294967294 (echo 大哥!超范围了,你自己处理吧,我做不来了 囧rz&set %varname%=数字太大,自行处理!&goto :eof)

for /f "tokens=2" %%i in ('ping %tmpIP% -n 1 -w 0') do set %varname%=%%i&goto :eof


   此帖被 +2 点积分    点击查看详情   
评分人:【 HAT 分数: +2  时间:2009-1-4 01:36


2009-1-3 11:55
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
slore
铂金会员





积分 5212
发帖 2478
注册 2007-2-8
状态 离线
『第 4 楼』:  

直接ping会转换的……



S smile 微笑,L love 爱,O optimism 乐观,R relax 放松,E enthusiasm 热情...Slore
2009-1-3 12:20
查看资料  发短消息 网志   编辑帖子  回复  引用回复
pooronce
中级用户





积分 484
发帖 250
注册 2007-6-5
状态 离线
『第 5 楼』:  



  Quote:
Originally posted by slore at 2009-1-3 12:20 PM:
直接ping会转换的……

ping效率比较低...
能想办法解决31位限制就ok了...

2009-1-3 12:25
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
slore
铂金会员





积分 5212
发帖 2478
注册 2007-2-8
状态 离线
『第 6 楼』:  

-n 1 -w 1 速度不算慢



S smile 微笑,L love 爱,O optimism 乐观,R relax 放松,E enthusiasm 热情...Slore
2009-1-3 12:35
查看资料  发短消息 网志   编辑帖子  回复  引用回复
pooronce
中级用户





积分 484
发帖 250
注册 2007-6-5
状态 离线
『第 7 楼』:  

慢的
在大量转换的场合,时间消耗不可胜数的
你看上面,我用0的,随便遇到几个高值ip,就会小卡一会儿了

2009-1-3 13:11
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
netbenton
银牌会员

批处理编程迷


积分 1916
发帖 752
注册 2008-12-28
来自 广西
状态 离线
『第 8 楼』:  回复3楼

@echo off
del IP_out.txt>nul
for /f "tokens=1,2,3" %%i in (ip.txt) do @call :output %%i %%j %%k
type IP_out.txt
pause&goto :eof

:output
set ip1=
set ip2=
call :ipconv "ip1" %1
call :ipconv "ip2" %2

echo %ip1%         %ip2%         %3>>IP_out.txt


goto :eof

:ipconv
rem 注意,此过程只能IP首位在127以下,即2147483647最大
if %~2 gtr 2147483646 (echo 数字太大,转呼过程2&call :ipconv2 %1 %2&goto :eof)
set ou=

:ipconv1
set varname=
set tmpIP=
set _IP_a=
set _IP_b=
set _IP_c=
set _IP_d=

set "varname=%~1"
set tmpIP=%2

set /a _IP_a=tmpIP^>^>24
if defined ou set /a _IP_a=_IP_a+128
set /a _IP_b=(tmpIP^>^>16)^&255
set /a _IP_c=(tmpIP^>^>8)^&255
set /a _ip_d=tmpIP^&255

set %varname%=%_IP_a%.%_IP_b%.%_IP_c%.%_IP_d%
goto :eof

:ipconv2
rem 增加此过程处理IP首位在127以上的代码

set "var=%~2"
set varf=%var:~0,1%
set varb=1%var:~1%
set /a varf=%varf%-2
set /a varb=%varb%-147483648
if %varb% lss 1000000000 set /a varf=varf-1
set /a var=%varf%*1000000000+%varb:~-9%
set ou=128
call :ipconv1 %~1 %var%


goto :eof

   此帖被 +2 点积分      点击查看详情   
评分人:【 pooronce 分数: +2  时间:2009-1-3 17:10




精简
[你的+我的+他的]=>[大家的]    个人网志   
2009-1-3 15:32
查看资料  发送邮件  发短消息 网志  OICQ (37659560)  编辑帖子  回复  引用回复
pooronce
中级用户





积分 484
发帖 250
注册 2007-6-5
状态 离线
『第 9 楼』:  

思路不错
不过有些东西你没处理好
试下这个ip.txt:
50331648        1033418400        US
4000000001        50332671        US
3549476416        50332927        US
4000000000        50333695        US
4007483643        50333951        US
2123369536        50334719                US

2009-1-3 17:06
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
pooronce
中级用户





积分 484
发帖 250
注册 2007-6-5
状态 离线
『第 10 楼』:  

改进版来喽:
@echo off
del IP_out.txt>nul
for /f "tokens=1,2,3" %%i in (ip.txt) do @call :output %%i %%j %%k
type IP_out.txt
pause&goto :eof

:output
set ip1=
set ip2=
call :ipconv "ip1" %1
call :ipconv "ip2" %2

echo %ip1%         %ip2%         %3>>IP_out.txt


goto :eof

:ipconv
rem 注意,此过程只能IP首位在127以下,即2147483647最大
set _hmark=
set varname=
set tmpIP=
set _IP_a=
set _IP_b=
set _IP_c=
set _IP_d=

set "varname=%~1"
set tmpIP=%2
if %~2 gtr 2147483646 call :iptrip %2 "tmpIP" "_hmark"

if "%_hmark%"=="Error" set "%varname%=此IP错误"&goto :eof

set /a _IP_a=tmpIP^>^>24
if "%_hmark%"=="1" set /a _IP_a+=128
set /a _IP_b=(tmpIP^>^>16)^&255
set /a _IP_c=(tmpIP^>^>8)^&255
set /a _ip_d=tmpIP^&255

set %varname%=%_IP_a%.%_IP_b%.%_IP_c%.%_IP_d%
goto :eof

:iptrip
rem 此过程处理IP首段过127的部分,参数2为要处理的变量名,参数3为标记名
if "%1"=="2147483647" goto :eof
set _or_ip=%1
set _ip_right=%_or_ip:~-9%
        :_trip_pre_zero
        if "%_ip_right:~0,1%"=="0" if not "%_ip_right:~1,2%"=="" set "_ip_right=%_ip_right:~1%"&goto :_trip_pre_zero
if not defined _ip_right set _ip_right=0
set _ip_left=%_or_ip:~0,-9%

set /a _ip_right-=147483648
set /a _ip_left-=2

if %_ip_left% lss 2 goto :_iptrip_goon
if %_ip_left% equ 2 if %_ip_right% leq 147483647 goto :_iptrip_goon
set %~3=Error
goto :eof
        :_iptrip_goon
::if %ip_right% lss 0 (set /a _ip_left-=1&set /a _ip_right+=1000000000)
set /a %~2=_ip_left*1000000000+_ip_right
set %~3=1

goto :eof


2009-1-3 17:09
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
netbenton
银牌会员

批处理编程迷


积分 1916
发帖 752
注册 2008-12-28
来自 广西
状态 离线
『第 11 楼』:  回复:pooronce

我试了没有问题呀,贴上结果:

3.0.0.0         61.152.182.160         US
238.107.40.1         3.0.3.255         US
211.144.182.64         3.0.4.255         US
238.107.40.0         3.0.7.255         US
238.221.88.251         3.0.8.255         US
126.144.12.64         3.0.11.255         US
请按任意键继续. . .



精简
[你的+我的+他的]=>[大家的]    个人网志   
2009-1-3 18:28
查看资料  发送邮件  发短消息 网志  OICQ (37659560)  编辑帖子  回复  引用回复
pooronce
中级用户





积分 484
发帖 250
注册 2007-6-5
状态 离线
『第 12 楼』:  

哦。。。贴错,试这个:

50331648        1033418400        US
3500000001        50332671        US
3949476416        50332927        US
3100000001        50333695        US
4207483643        4150333951        US
2123369536        50334719                US

借位与不借位的区别吧。。。
另外有两个数字落空,虽然机率很小,也得处理一下的

[ Last edited by pooronce on 2009-1-3 at 21:38 ]

2009-1-3 20:21
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
cz1314
初级用户





积分 64
发帖 43
注册 2007-11-12
状态 离线
『第 13 楼』:  

牛人啊!!谢谢 大侠门了!!佩服!!

2009-1-3 22:53
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
netbenton
银牌会员

批处理编程迷


积分 1916
发帖 752
注册 2008-12-28
来自 广西
状态 离线
『第 14 楼』:  改进一下

@echo off
del IP_out.txt>nul
for /f "tokens=1,2,3" %%i in (ip.txt) do @call :output %%i %%j %%k
type IP_out.txt
pause&goto :eof

:output
set ip1=
set ip2=
call :ipconv "ip1" %1
call :ipconv "ip2" %2

echo %ip1%         %ip2%         %3>>IP_out.txt


goto :eof

:ipconv
rem 注意,此过程只能IP首位在127以下,即2147483647最大
if %~2 gtr 2147483646 (echo 数字太大,转呼过程2&call :ipconv2 %1 %2&goto :eof)
set ou=

:ipconv1
set varname=
set tmpIP=
set _IP_a=
set _IP_b=
set _IP_c=
set _IP_d=

set "varname=%~1"
set tmpIP=%2

set /a _IP_a=tmpIP^>^>24
if defined ou set /a _IP_a=_IP_a+128
set /a _IP_b=(tmpIP^>^>16)^&255
set /a _IP_c=(tmpIP^>^>8)^&255
set /a _ip_d=tmpIP^&255

set %varname%=%_IP_a%.%_IP_b%.%_IP_c%.%_IP_d%
goto :eof

:ipconv2
rem 增加此过程处理IP首位在127以上的代码

set var=%~2
set varf=%var:~0,-9%

rem ****** 去掉截串后前导 "0" 就可以了
set varb=1%var:~-9%-1000000000
rem ******

set /a varf=%varf%-2
set /a varb=%varb%-147483648
set /a var=%varf%*1000000000+%varb%
set ou=128
call :ipconv1 %~1 %var%

goto :eof



精简
[你的+我的+他的]=>[大家的]    个人网志   
2009-1-3 23:13
查看资料  发送邮件  发短消息 网志  OICQ (37659560)  编辑帖子  回复  引用回复
netbenton
银牌会员

批处理编程迷


积分 1916
发帖 752
注册 2008-12-28
来自 广西
状态 离线
『第 15 楼』:  换种算法看看

@echo off&setlocal enabledelayedexpansion

>IP_out.txt cd.

::此段采用 pooronce君 的代码
for /f "tokens=1,2,3" %%i in (ip.txt) do @call :output %%i %%j %%k
type IP_out.txt
pause&goto :eof

:output
set ip1=
set ip2=
call :ipconv "ip1" %1
call :ipconv "ip2" %2
echo %ip1%         %ip2%         %3>>IP_out.txt
goto :eof
::此段采用 pooronce君 的代码


:ipconv
set var=%~2
set vecho=

:agin
set varf=!var:~0,-6!
set varb=!var:~-6!

if defined varf (
set /a vs0=!varf!/256
set /a vy0=!varf!^%%256
set /a varb=!vy0!*1000000+4!varb!-4000000
)

set /a vs1=!varb!/256
set /a vy1=!varb!^%%256

if defined vecho (set vecho=!vy1!.!vecho!) else (set vecho=!vy1!)
set /a var=!vs0!*1000000+!vs1!

if not "!var!"=="0" goto :agin
set %~1=%vecho%

goto :eof

   此帖被 +4 点积分        点击查看详情   
评分人:【 pooronce 分数: +4  时间:2009-1-4 10:57




精简
[你的+我的+他的]=>[大家的]    个人网志   
2009-1-3 23:31
查看资料  发送邮件  发短消息 网志  OICQ (37659560)  编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: