理解位运算及使用场景

本贴最后更新于 3482 天前,其中的信息可能已经事过景迁

最近在看 APUE,函数 umask 的例子用到了位运算,认为这是个非常适合使用位运算的场景,有必要笔记一下。例子代码基于 golang,因为最近在学习 golang.

位运算

先来看下位运算的定义:程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。摘自百度百科

比如,&运算本来是一个逻辑运算符,但整数与整数之间也可以进行&运算。举个例子,6 的二进制是 110,11 的二进制是 1011,那么 6 & 11 的结果就是 2,它是二进制对应位进行逻辑运算的结果(0 表示False1 表示 True,空位都当 0 处理),下面的代码是用 go 实现的:

func base() { a := 6 // 0110 b := 11 // 1011 // ---- // & 0010 => 2 // | 1111 => 15 // ^ 1101 => 13 // &^ 0100 => 4 fmt.Println(a & b) fmt.Println(a | b) fmt.Println(a ^ b) fmt.Println(a &^ b) }

四个位运算符说明如下:

0110 & 1011 = 0010 AND 都为1。 0110 | 1011 = 1111 OR 至少一个为1。 0110 ^ 1011 = 1101 XOR 只能一个为1。 0110 &^ 1011 = 0100 AND NOT 清除标志位。

应用场景-Umask

只是位运算的话理解起来挺容易的,但是这种位运算有毛用呢?适于用什么场景?下面我用 Unix 系统的 umask 概念来实践下位运算。关于 umask 的概念请参阅 http://linux.vbird.org/linux_basic/0220filemanager.php#umask。简单来讲,Unix 系统对于文件的权限用 9 个权限位来控制:

[-][rwx][r-x][r--] 1 234 567 890
  • r:可读 4
  • w:可写 2
  • x:可执行 1
  • -:表示此权限被去除

第一位是用来表示是文件还是目录,先不用管它,主要是后面 9 位。我们经常在授权是用的到 644,755 都是用 r,w.x 这三个值相加得出的。为什么值分别是 4,2,1 呢,我们把 go 语言 sys 包中的源码拿出来看看就明白了:

const ( S_IRUSR = 0x100 //用户可读 S_IWUSR = 0x80 //用户可写 S_IXUSR = 0x40 //用户可执行 S_IRGRP = 0x20 //组可读 S_IWGRP = 0x10 //组可写 S_IXGRP = 0x8 //组可执行 S_IROTH = 0x4 //其它可读 S_IWOTH = 0x2 //其它可写 S_IXOTH = 0x1 //其它可执行 )

这是 sys 包中定义的一些常量,我们来打印下这些都是啥玩意

fmt.Printf("%9b %3d %s\n", S_IRUSR, S_IRUSR, "用户读") fmt.Printf("%9b %3d %s\n", S_IWUSR, S_IWUSR, "用户写") fmt.Printf("%9b %3d %s\n", S_IXUSR, S_IXUSR, "用户执行") fmt.Printf("%9b %3d %s\n", S_IRGRP, S_IRGRP, "组读 *") fmt.Printf("%9b %3d %s\n", S_IWGRP, S_IWGRP, "组写 *") fmt.Printf("%9b %3d %s\n", S_IXGRP, S_IXGRP, "组执行") fmt.Printf("%9b %3d %s\n", S_IROTH, S_IROTH, "其它读 *") fmt.Printf("%9b %3d %s\n", S_IWOTH, S_IWOTH, "其它写 *") fmt.Printf("%9b %3d %s\n", S_IXOTH, S_IXOTH, "其它执行") // 输出 100000000 256 用户可读 10000000 128 用户可写 1000000 64 用户可执行 100000 32 组可读 10000 16 组可写 1000 8 组可执行 100 4 其它可读 10 2 其它可写 1 1 其它可执行

看明白了吧,其实就是把九个权限位置分别标志为 1,用二进制可以很清楚的表示权限位,4,2,1 也就是这么来的。那么 umask 的就可以利用这个位运算,代码如下:

package main import ( "fmt" "golang.org/x/sys/unix" "os" ) func main() { unix.Umask(0) _, err := os.Create("foo") if err != nil { fmt.Println("Create Error") } unix.Umask(unix.S_IRGRP | unix.S_IWGRP | unix.S_IROTH | unix.S_IWOTH) _, err2 := os.Create("bar") if err2 != nil { fmt.Println("Create Error") } }

上面的代码可以看到,unix.S_IRGRP | unix.S_IWGRP | unix.S_IROTH | unix.S_IWOTH 就利用了位运算,程序先后创建了两个文件 foobar, 创建 bar 文件时,文件初始权限把其它中的可读可写去除了,所以我们用 ls -la foo bar 命令可以看到输出如下:

[vagrant@mydev ~]$ ls -la foo bar -rw-------. 1 vagrant vagrant 0 Oct 26 02:54 bar -rw-rw-rw-. 1 vagrant vagrant 0 Oct 26 02:54 foo

再用 9 个权限位的二进制图说明下:

100000000 256 用户可读 10000000 128 用户可写 1000000 64 用户可执行 100000 32 组可读 * 10000 16 组可写 * 1000 8 组可执行 100 4 其它可读 * 10 2 其它可写 * 1 1 其它可执行 --------- 110110 unix.S_IRGRP | unix.S_IWGRP | unix.S_IROTH | unix.S_IWOTH

umask 四个参数我用型号标出来了,那经过**| 位运算最终结果就是 110110**,言外之意就是 umask 把标志为 1 的权限位去除了。

最后我把权限位二进制打印代码贴出来

  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    498 引用 • 1395 回帖 • 248 关注
  • apue
    1 引用 • 7 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
请输入回帖内容 ...

推荐标签 标签

  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 531 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖
  • Hibernate

    Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。

    39 引用 • 103 回帖 • 726 关注
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 95 关注
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    133 引用 • 1124 回帖 • 112 关注
  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1063 引用 • 3455 回帖 • 161 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    76 引用 • 258 回帖 • 629 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖
  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖 • 2 关注
  • 招聘

    哪里都缺人,哪里都不缺人。

    188 引用 • 1057 回帖
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 648 关注
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 176 关注
  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 112 关注
  • Word
    13 引用 • 41 回帖
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 1 关注
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    174 引用 • 3852 回帖
  • Sandbox

    如果帖子标签含有 Sandbox ,则该帖子会被视为“测试帖”,主要用于测试社区功能,排查 bug 等,该标签下内容不定期进行清理。

    432 引用 • 1250 回帖 • 596 关注
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 158 关注
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    150 引用 • 257 回帖 • 1 关注
  • Wide

    Wide 是一款基于 Web 的 Go 语言 IDE。通过浏览器就可以进行 Go 开发,并有代码自动完成、查看表达式、编译反馈、Lint、实时结果输出等功能。

    欢迎访问我们运维的实例: https://wide.b3log.org

    30 引用 • 218 回帖 • 637 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    37 引用 • 157 回帖 • 3 关注
  • 电影

    这是一个不能说的秘密。

    122 引用 • 608 回帖
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    29 引用 • 202 回帖 • 31 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 203 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    89 引用 • 1251 回帖 • 408 关注
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 281 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖 • 3 关注