React

by b1ncer

HTML

<div id="app"></div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

.done {
  color: rgba(0, 0, 0, 0.3);
  text-decoration: line-through;
}

input {
  margin-right: 5px;
}

React

//"172.168.5.1" => 2896692481

//const format = ip => parseInt(ip.split('.').reduce((prev, curr) => prev + parseInt(curr.trim()).toString(2).padStart(8, '0'), ''), 2)

//适用:点分十进制 IP ,不考虑其他进制。参考 - https://zh.wikipedia.org/wiki/IPv4#地址格式
//不允许前导 0 。参考 - https://www.jiuzhang.com/qa/5716/

const toLegalIpInt = (str) => {
	//not string
  if (typeof str !== 'string') {
  	throw new Error('str must be String.')
  }
  
  //'0'
  if (str === '0') {
  	return 0
  }
  
  //'012'
  if (str[0] === '0') {
  	throw new Error('not a legal ip number.')
  }
  
  const res = ~~str
  
  if (res === 0) {
  	throw new Error('not a legal ip number.')
  }
  
  if (res > 255 || res < 0) {
  	throw new Error('a valid ip number must be 0~255')
  }
  
  return res
}

const toBinaryString = ip => {
	if (typeof ip !== 'string') {
  	throw new Error('ip must be String.')
  }

	const ipArr = ip.split('.')
  if (ipArr.length !== 4) {
  	throw new Error('not a valid ip address.')
  }
  
  return ipArr.reduce((prev, curr) => prev + toLegalIpInt(curr.trim()).toString(2).padStart(8, '0'), '')
}

const format = ip => parseInt(toBinaryString(ip), 2)

const Hello = ({ip}) => <div>{format(ip)}</div>

ReactDOM.render(<Hello ip="172.168.5.1" />, document.querySelector("#app"))

//unit tests tools

const toBe = (desc, fn) => (a, b) => {
	if(fn(a) !== b) throw new Error(`${desc} failed to be: ${a} - ${b}`)
}

const toThrow = (desc, fn) => a => {
	try {
  	fn(a)
    throw true
  } catch (e) {
  	if (e === true) {
    	throw new Error(`${desc} failed to throw: ${a}`)
    }
  }
}

function testAll() {
	
  //test toLegalIpInt
  const test1 = toBe('test toLegalIpInt to be', toLegalIpInt)
  const test2 = toThrow('test toLegalIpInt to throw', toLegalIpInt)
  test1('0', 0)
  test1('255', 255)
  test1('123', 123)

  test2('01')
  test2('256')
  test2('-1')
  test2('1 87')
  test2('.-5 ')
  test2(true)
  test2(' 0 ')

  //test format
  const test3 = toBe('test format to be', format)
  const test4 = toThrow('test...