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某些判断的主要原因有两个:
- JS有非空、非0即为真的特征。
- 接位非的本质是+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次方计算时,可节省一点点运算力。
好,就这些吧。我是姜友华,下次见。
网友评论