位运算的作用

2021-08-19  本文已影响0人  Jiangyouhua

Hi,大家好,我是姜友华。
学任何一种程序语言时,都会学到位运算,但在程序开发时,我却极少用到,让我觉得这个东西有一点像屠龙术。最近工作,用到了异或加密,因为用得极少,所以记录下。

主要内容:
我所用到的与、或、非、异或、位移。

1. 按位与(&):用于位清零。

如果要将所申请的内存低8位置0,可以将内存的值跟0x100进行按位与运算。这是我在学Metal看到的

/// swift
  let alignedUniformsSize = (MemoryLayout<Uniforms>.size + 0xFF) & -0x100

2. 按位或(|):用于多项选择。

这个用的比较多一点。如系统设置有n个权限,各权限依次定义为2的1-n次方(增1、改2、删4、查8 )。用户权限可以多选,选择时将权限值总计,应用时判断权限用按位或。

//print(1 << 8)
/// swift
// 多个权限。
let insert = 1
let delete = 2
let update = 4
let select = 8

// 赋予权限
let userAuth = insert + select

// 判断权限
if (userAuth | insert) == userAuth {
    print("User has insert operation permission")
}

if (userAuth | delete) == userAuth {
    print("User has delete operation permission")
}

if (userAuth | update) == userAuth {
    print("User has update operation permission")
}

if (userAuth | select) == userAuth {
    print("User has select operation permission")
}

输出的结果是:

User has insert operation permission
User has select operation permission

接位非(~):用于JS的一些判断。

现在应该没人用了,可用在JS某些判断的主要原因有两个:

  1. JS有非空、非0即为真的特征。
  2. 接位非的本质是+1取反。
print(~3 == -(3+1))
print(~2 == -(2+1))
print(~1 == -(1+1))
print(~0 == -(0+1))
print(~(-1) == -(-1+1))
print(~(-2) == -(-2+1))
print(~(-3) == -(-3+1))

结果显示结论是正确的。

true
true
true
true
true
true
true

按上面的结果可见,整数按位非只有-1的值为0。同时使用js的indexOf时,没找到则会返回-1,如是下面应用成立。

/// javascript
let name = "Jiang youhua"

if (name.indexOf("Jiang") > -1) {
  console.log(true)
} else {
  console.log(false)
}

if (name.indexOf("ABC") > -1) {
  console.log(true)
} else {
  console.log(false)
}

if (~name.indexOf("Jiang")) {
  console.log(true)
} else {
  console.log(false)
}

if (~name.indexOf("ABC")) {
  console.log(true)
} else {
  console.log(false)
}

结果为

true
false
true
false

由此可见,这种应用是取巧,判断过程让人费解,所以不建议使用。

异或(^):简单加密

在https不流行的时代,用户登录是以明文的方式传送,这有极高的风险,所以需要加密,异或常用于这里。用异或加密解密极其简单,只需要对每字符进行异或运算即可。

/// swift
extension String{
    // 异或加密。
    func xor(_ key: UInt32) -> String {
        return String(self.unicodeScalars.map { scalar in
            Character(Unicode.Scalar(scalar.value ^ key)!)
        })
    }
    
    // 异或加密。
    func xorEn(_ key: UInt32) -> String {
        let key = UTF8.CodeUnit(key)
        let bytes = utf8.map({ $0 ^ key})
        return String(bytes: bytes, encoding: .utf8) ?? ""
    }
    
    func xorAll(_ key: String) -> String {
        let a: [UInt8] = Array(self.utf8)
        let b: [UInt8] = Array(key.utf8)
        let n = max(a.count, b.count)
        return String(bytes: (0..<n).map { i in
            let x: UInt8 = a.count > i ? a[i] : 0
            let y: UInt8 = b.count > i ? b[i] : 0
            return x ^ y
        }, encoding: .utf8) ?? ""
    }
}

let key: UInt32 = 123
let username = "姜友华".xor(key)
let password = "Jiang youhua".xorEn(key)
let str = "hijklmn"
let code = "abcdefg".xorAll(str)
print(username)
print(password)
print(code)
print(username.xor(key))
print(password.xorEn(key))
print(code.xorAll(str))

输出结果如下:

妧厰匵
1����[������
    �   �   �   
姜友华
Jiang youhua
abcdefg

前3行是加密的,后3行是解密的。

位移(<<,>>)

位移的作用,暂时用过的,只有在代替2的n次方计算时,可节省一点点运算力。

好,就这些吧。我是姜友华,下次见。

上一篇 下一篇

猜你喜欢

热点阅读