理解位运算及使用场景

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

最近在看 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 发布的第二款编程语言。

    500 引用 • 1396 回帖 • 255 关注
  • apue
    1 引用 • 7 回帖

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    315 引用 • 547 回帖
  • 招聘

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

    188 引用 • 1057 回帖
  • 996
    13 引用 • 200 回帖 • 2 关注
  • 叶归
    14 引用 • 62 回帖 • 25 关注
  • ZooKeeper

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

    61 引用 • 29 回帖 • 10 关注
  • 创业

    你比 99% 的人都优秀么?

    81 引用 • 1395 回帖
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    43 引用 • 44 回帖
  • 大数据

    大数据(big data)是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。

    89 引用 • 113 回帖 • 2 关注
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    181 引用 • 400 回帖
  • SMTP

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。

    4 引用 • 18 回帖 • 643 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    127 引用 • 1708 回帖 • 1 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 3 关注
  • 负能量

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

    89 引用 • 1251 回帖 • 389 关注
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 94 关注
  • Office

    Office 现已更名为 Microsoft 365. Microsoft 365 将高级 Office 应用(如 Word、Excel 和 PowerPoint)与 1 TB 的 OneDrive 云存储空间、高级安全性等结合在一起,可帮助你在任何设备上完成操作。

    5 引用 • 34 回帖
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 184 关注
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 116 关注
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 45 关注
  • OneDrive
    2 引用 • 1 关注
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    173 引用 • 414 回帖 • 357 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 398 关注
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    19 引用 • 23 回帖 • 745 关注
  • Follow
    4 引用 • 12 回帖 • 10 关注
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    91 引用 • 59 回帖
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖 • 1 关注
  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 519 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖