BING
斯是陋室,唯吾芳馨
衍生

IP 地址如何转化为最小的数字?

共 2,424 字,需阅读 6 分钟2018/09/13 上午6,980 次阅读

#存储

我们首先要知道计算机是怎么存储数据的。

#如何存储 0 和 1

在计算机中所有的数据都被存储为一连串的二进制信息,0 和 1。

内存条中间有一块块方块,每个方块上就有很多存 0 和 1 的机关,可以把一个机关想象成一个圆点,一个圆点就是一个电池,那么就有了下面几个环节。

假设我们每个圆点都是一个小电池,当我们要存储时,先选定一列圆点,开始每行充电,如果是 1 就充电,是 0 就不充电。由于这样是无法存储电量的,充电的速度是几纳秒,耗电的速度是几毫秒,计算机采取的做法是在耗完电之前再充一次,这里就依赖 CPU 的赫兹数值,CPU 的多少赫兹就代表每秒可以充多少次电,即代表着CPU的性能高低。

#如何存储数字

我们平时所说的数值一般都是十进制的,但计算机只能存储 0 和 1,所以需要将十进制的数转为二进制让计算机进行储存。

但也有一些特殊情况,如果想存 -3 就需要使用补码(计算机无法存储负号); 如果想存 0.75 就需要使用浮点数(计算机无法存储小数点)。

#存储单位

比特 bit

比特,bit,位,计算机中最小的存储单位。

01 就是一个二进制数字,也叫二进制位,这么一个二进制数字占用的空间单位就是 1bit。

字节 Byte

8个二进制位为一个字节(B),即 1B = 8bit

十进制数字的 6 转换为二进制为 00000110,由八个二进制位组成(不足则以0补位)。

Kilo Byte

1 Kilo Byte (KB) = 1024 B

其他类推

  • 1 Mega Byt (MB) = 1024 KB
  • 1 Giga Byte (GB) = 1024 MB
  • 1 Tera Byt (TB) = 1024 GB
  • 1 Peta Byt (PB) = 1024 TB
  • 1 Exa Byt (EB) = 1024 PB
  • 1 Zetta Byt (ZB) = 1024 EB
  • 1 Yotta Byt (YB) = 1024 ZB
  • 1 Bronto Byt (BB) = 1024 YB
  • 1 Nona Byt (NB) = 1024 BB
  • 1 Dogga Byt (DB) = 1024 NB
  • 1 Corydon Byt (CB) = 1024 DB
  • 1 Xero Byte (XB) = 1024 CB

为什么是 1024

目前计算机都是二进制的,让它们计算单位,只有2的整数幂时才能非常方便计算机计算,因为电脑内部的电路工作有高电平和低电平两种状态,所以就用二进制来表示信号(控制信号和数据),以便计算机识别。

而人习惯于使用10进制,所以存储器厂商们才用1000作进率。这样导致的后果就是实际容量要比标称容量少,不过这是合法的。1024是2的10次方,因为如果取大了,不接近10的整数次方,不方便人们计算;取小了,进率太低,单位要更多才能满足需求,所以取2的10次方正好。

#IP 地址

IP 地址看起来是由以 "." 分割的四段十进制数字组成,每一段的数字转为二进制都是一个 8 位二进制数字。

看一个很常见的 IP 地址:

123.125.114.144

01111011.01111101.01110010.10010000

所以 IP 地址一共是由32位二进制数字组成的。

点分十进制表示法只是为了让人好记忆,并不能用于电脑运算; 数据库中跟 IP 地址有的字段一般都会存成整数,这样便于查询,也可以提高查询速度。

So,怎么把 IP 地址转换为一个最小的十进制正整数用于存储?

#怎么算

笨办法

          
  • 1
  • 2
  • 3
  • 4
function ipToNumber(ip) { const [a, b, c, d] = ip.split('.').map(i => Number(i)) return a*256*256*256 + b*256*256 + c*256 + d }

16进制字符

每8位转成16进制字符,拼接后转整数。

          
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
function ipToNumber(ip) { return parseInt(ip.replace(/\d+\.?/ig, item => { item = parseInt(item) return (item > 15 ? '' : '0') + item.toString(16) }), 16) }

位移

          
  • 1
  • 2
  • 3
  • 4
  • 5
function ipToNumber(ip) { return ip.split('.').reduce((ipInt, octet) => { return (ipInt << 8) + parseInt(octet, 10) }, 0) >>> 0 }

参考资料: (一) (二) (三)

署名 - 非商业性使用 4.0 国际 https://surmon.me/article/118
2 / 2 条看法
访客身份
在下有一拙见,不知...
  • 狮子
    狮子🇨🇳CNShanghaiMac OSChrome

    强势围观

  • ww
    Ww🇨🇳CNShanghaiWindowsChrome

    啦啦啦