Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@sakamotoryouta

JSでIPアドレスをビット演算子で計算する

'192.168.11.0' みたいなのを、32bit数値にする

IPアドレスをCIDRで色々やったりする必要がありました。
最初は以下のようなコードを書いてました。
うろ覚え・・・

function convertBinaryIp(ip) {
    const dividedIp = ip.split('.');

    return dividedIp.reduce((accumulator, v, idx) => {
      const bit = `00000000${parseInt(ip[i], 10).toString(2)}`;
      accumulator + bit.slice(-8);

      return accumulator;
    }, '');
  }

このコードで行くと、文字列で10101010000~~みたいなのが返ってきます。
なので、その後の計算も文字列にたいしてsplit()したりしてました。

数値Onlyでやったほうが効率的

いちいち文字列の10101000111~~みたいな形式にするの非効率だよと教えて頂きました。
さらに、どうやって数値Onlyでやるかみたいなアドバイスも頂けたので処理を書き換えました。

function convertBinaryIp(ip) {
    const dividedIp = ip.split('.').reverse();
    const byte = 8;

    return dividedIp.reduce((accumulator, v, idx) => {
      const binary = (parseInt(v, 10) << (byte * idx)) >>> 0;
      return accumulator + binary;
    }, 0);
  }

この関数をconvertBinaryIp('192.168.11.0')みたいな感じで実行してあげれば、
3232238336のような数値が返ってきます。
この数値は2進数に直すと、11000000101010000000101100000000です。

11000000 => 192

10101000 => 168

00001011 => 11

00000000 => 0

この3232238336という数値を使えば、他のIPとの大小比較とかCIDRの範囲内か?とかもチェックできます。

CIDRの時に使用する、
上位24ビットをそのまま取得して、下位8ビットは0にするというような場合の式は以下です。

(ipアドレス & (~((1 << (32 - 24)) - 1))) >>> 0;

以上。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?