WangBooth's Logbook

王布斯的网络日志

0%

需求背景

你有没有发现,从Maven仓库下载文件的时候,除了我们需要的jar包之外,还有个.asc文件,这个文件就是jar包的数字签名,咱可以通过这个数字签名来验证jar包是否确实是Oracle官方发布的包:

对于我们的客户,生产环境上运行的程序,有些是从公司 gitlab-ci 上编译出来的,有些是开发者个人电脑上编译出来的,还有的是客户自己改代码后编译出来的,程序出问题后,到底是谁的责任呢?比如,executor-proxy-provider.jar 可以直接接触到客户生产环境的数据,万一这个文件被人恶意篡改,把客户数据删掉了,咋整…

所以,咱也需要将公司对外的jar包做个签名,客户拿到jar包后,可以根据签名文件来确认是不是官方的包。

GPG签名原理

参考下这个链接:https://www.ruanyifeng.com/blog/2013/07/gpg.html

大体流程是:

  1. 使用GPG生成一对密钥,公钥和私钥
  2. 使用私钥对文件进行签名,并生成签名文件
  3. 将文件、该文件对应的签名文件 以及 公钥,同时对外公布
  4. 用户使用公钥和签名文件,对该文件进行签名验证

Maven使用GPG签名

参考下官方链接:https://maven.apache.org/plugins/maven-gpg-plugin/usage.html

大体流程是:

  1. 公司内部统一生成一对公钥和私钥文件:public.gpgprivate.gpg
    私钥private.gpg将用于对发布包进行签名,所以必须由专人保管且只有公司统一的专用服务器可以使用(如gitlab-ci使用的容器),私人电脑不得使用该私钥对发布包进行签名;
    公钥public.gpg将用于客户验证发布包的签名,需要与公钥本身的指纹(可通过gpg --fingerprint 生成)一同公开在公司官网;

  2. 在公司统一的专用打包服务器上通过gpg --import private.gpg来导入私钥;

  3. 在项目pom中添加maven-gpg-plugin插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <project>
    ...
    <build>
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-gpg-plugin</artifactId>
    <version>3.0.1</version>
    <executions>
    <execution>
    <id>sign-artifacts</id>
    <phase>verify</phase>
    <goals>
    <goal>sign</goal>
    </goals>
    </execution>
    </executions>
    </plugin>
    </plugins>
    </build>
    ...
    </project>
  4. 在项目assembly中将maven-gpg-plugin插件生成的签名文件(.asc)包含进来

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <fileSets>
    ...
    <fileSet>
    <directory>${project.parent.basedir}/dubhe-server-provider/target</directory>
    <outputDirectory>${assembly.name}/jars</outputDirectory>
    <includes>
    <include>*.jar</include>
    <include>*.jar.asc</include>
    </includes>
    </fileSet>
    ...
    </fileSets>
  5. 使用 mvn verify进行打包,此时jar包对应的签名文件(.asc)会自动生成,与jar包在同一级目录下

  6. 客户(或者交付运维人员)在拿到部署包后,可通过以下步骤对jar包进行签名验证:
    7.1 从官网下载公钥文件public.gpg
    7.2 通过 gpg --import public.gpg 导入公钥
    7.3 通过 gpg --fingerprint 公钥ID 查看公钥指纹,确保该指纹与官网公布的公钥指纹一致
    7.4.通过 gpg --verify dubhe-server-provider-4.3.1.jar.sig dubhe-server-provider-4.3.1.jar来验证该文件签名是否是Good signature

  7. 开发测试平时打包,可按原先流程通过mvn package打包发布测试环境,不会进行签名,当然,这种包也不能对外发布。

gitlab-ci 配置

gitlab上的ci使用了k8s来做runner,目前公司内部通用的ci脚本一般是拉代码-打包-推送这个过程,我们需要在打包过程中加入GPG签名步骤,ci需要改动的点如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
image: docker:git
services:
- docker:dind

variables:
PROJECT_NAME: dubhe-node
DOCKER_DRIVER: overlay

stages:
- build
- upload

build:
image: docker.dtwave-inc.com/library/maven:3.5.4-jdk-8-gunpg-alpine
variables:
MAVEN_OPTS: "-Dmaven.repo.local=/build-cache/.m2/repository"
stage: build
script:
- gpg -v --batch --import <(echo "$GPG_PRIVATE_KEY")
- "mvn clean verify -U -DskipTests -Dgpg.passphrase=$GPG_PRIVATE_KEY_PWD -DSHUXI_VERSION=$CI_COMMIT_TAG"
- cp dist/$PROJECT_NAME*$CI_COMMIT_TAG.tgz /build-cache
only:
- tags

upload:
image: docker.dtwave-inc.com/library/mc
stage: package
dependencies:
- build

script:
- mc mb dtwave-inc/shuxi-dev/backend/${PROJECT_NAME}/${CI_COMMIT_TAG}/
- mc cp /build-cache/${PROJECT_NAME}*${CI_COMMIT_TAG}.tgz dtwave-inc/shuxi-dev/backend/${PROJECT_NAME}/${CI_COMMIT_TAG}/
- rm -rf /build-cache/${PROJECT_NAME}*${CI_COMMIT_TAG}.tgz
only:
- tags

改动点1:

Build时使用maven:3.5.4-jdk-8-gunpg-alpine镜像
maven:3.5.4-jdk-8-gunpg-alpine 镜像比原先的 maven:3.5.4-jdk-8-alpine镜像多安装了一个gunpg,用于GPG签名。

改动点2:

Build时先通过gpg加载私钥
gpg -v --batch --import <(echo "$GPG_PRIVATE_KEY")
GPG私钥是保存在gitlab的环境变量GPG_PRIVATE_KEY中的,该变量只允许gitlab项目管理员或者分组管理员编辑。

改动点3:

使用mvn verify来打包
mvn clean verify -U -DskipTests -Dgpg.passphrase=$GPG_PRIVATE_KEY_PWD -DSHUXI_VERSION=$CI_COMMIT_TAG
原先使用mvn install ...改为mvn verify ...,同时传入变量gpg.passphrase=$GPG_PRIVATE_KEY_PWD,用于指定使用GPG私钥的密码,该密码是存放在gitlab的环境变量GPG_PRIVATE_KEY_PWD 中的,只允许gitlab项目管理员或者分组管理员编辑。

gitlab管理员配置

在项目配置或者分组配置下,设置变量:

GPG_PRIVATE_KEY 为GPG私钥,默认情况下,GPG私钥是以二进制方式存储的,可通过gpg --armor --output private-key.txt --export-secret-keys来生成ASCII码文本,然后将私钥文本填入该变量的值中。私钥务必保证其安全性,只有管理员可见。

GPG_PRIVATE_KEY_PWD为使用GPG私钥的密码,在生成GPG密钥对的时候设置的此密码,需将密码填入该变量中。为防止私钥被滥用,该密码也需保证安全性,只有管理员可见。

今天读了吴军《硅谷来信》第三季第144封信,讲述了奥斯特里茨战争晋楚城濮之战两个战争历史,获胜方都是在打仗之前就有了足够宏远的战略目标,以及非常明细的战略实施计划和Plan B,最终才得以取胜。

战略拆分为以下几要素:

  • 自己当前的位置
  • 自己的目标
  • 抵达目标的步骤
  • 将来的愿景

对于前3点,我觉得自己在针对某些短期的小目标时,能提前清晰地规划出来,但最后一点「将来的愿景」我并没有切身体会过。常有的感觉是,某件事辛辛苦苦做了两个月终于做出来了,然后庆祝一下,然后就感觉很空虚,不知道该干嘛了,这应该就是没有设立更大的目标的缘故,不知道自己实现了当前的目标后该干什么了。

为什么会这样呢?

仔细回想一下,在设定一个短期目标的时候,一旦这个短期目标确定,我便会沉迷于筹划实现这个目标的细节中,然后仔细排出计划,经常是还没等计划通盘考虑完就马上动手实施了,最后常常是边实施变改计划,最终把目标实现,过程中还时不时熬夜干,把目标实现后,突然对未来就空白了。

给自己定个5年的目标是不错,但这种目标常常是不清晰的,时刻需要微调的,而短期目标之所以能定出来,应该是在这个模糊的长期目标的方向上自己下意识想出来的。所以我想,在定一个短期目标的时候,是不是可以把这个短期目标看成是自己长期模糊目标的一个步骤,强行给短期目标添加一个背景,然后逼着自己列一个更大的目标出来,最后分解成各个小目标落实。

试试看。

我们公司研发的软件在交付给客户之前,需要通过客户服务器上的MAC地址来生成对应的license,以防止客户将软件复制给其他人使用,但其实在虚拟化环境中,服务器的MAC地址是可以轻易修改的,单单通过MAC地址这一项标识物不足以防止软件被复制传播。

今天看到这篇文章里在确定服务器的唯一标识时,用到了硬件CPU、主板、Bios、MAC地址、显卡、声卡等ID,我觉得在ToC领域防止软件被复制传播已经足够了,修改CPUID掩码稍微有些门槛;但在ToB领域,还不足够,因为花10w块去破解100w的软件,成本是划得来的,有些企业是愿意干的。

所以我觉得在ToB领域,防止软件被恶意复制使用的方式,可以配合有下面这几种方式来加强许可策略:

  1. 软件本身定期联网向厂商的中心服务器上报信息,如果长期收不到中心服务器的回应,软件可以限制运行。当然,上报和回应的信息需要作加密,同时需要有法务部门配合,促使非授权客户购买license。
  2. 对于不具备联外网的客户环境,一开始可以不开具无限期的license,每年派维护人员线下更换新的license,可以放在每年的定期巡检工作中执行掉;
  3. 写出一个经常出BUG的软件,让客户不得不主动找你(玩笑,但也是现状)

不过,道高一尺魔高一丈,只要成本允许,license被破解是不可避免的事情,ToB的产品可以尽可能保持产品的功能迭代速度,即便老版本被人破解掉了,新版本的新特性也很可能会让客户心动付费的。

再烂的一年也值得总结。

每年年末总结,都觉得这一年过得好快。2021年更是如此。

1. 值得开心的事

1.1 搬入自己的房子

这一年最值得庆祝的事情,就是住进了自己的房子里,虽然这房子还是抵押给银行的,但毕竟是完全凭借俩人自己的能力攒钱、从朋友手里借钱付的首付,也算是圆了自己不啃老买房的梦。

房子是2019年10月份开始看,一开始还是不愿意开口找朋友借钱的,但后面开了口之后发现朋友们还是非常愿意给我借钱的,首付很快就凑好了。不过原房主是个奇葩,各种原因导致直到12月31号那天才正式把产证给办好,也算是2019年完成的一件大事吧。

今年年初疫情,再加上家里定做的家具还有味道,4月份才搬进去,住自己的家,踏实~~~

1.2 娃两岁了

娃今年身高长得真快,原来贴在桌子和墙边的防撞条,已经变矮了。

有自己的逻辑,模仿能力很强,学东西也非常快,唱歌、看绘本,很快就能记住。

周末有条件我都会带着娃开车出去浪一圈,弄得每过个周末娃的作息就会乱…

孩子的童年值得多记录一下,2021年计划多拍些照片、拍些 Vlog,给娃、给自己都留些记忆。

1.3 老婆整牙了

牙齿一直是老婆的心病,我倒觉得牙齿不整齐没啥影响,但心病就是这样,靠讲道理是很难释然的。今年最后一个月正好附近的牙科有优惠活动,把牙给整了。
疼肯定是要疼一段时间的,未来2-3年也要不停地收拾牙套,对她来说都是值得的。

一时间能想起的就这几件非常值得开心的事儿了,也是缺少记录,翻了翻手机照片,记录的内容太少了。

2. 难处理的事

我记得蔡崇信有说过类似的话:没有什么难过的事,倒是有一些难处理的事。

难过,就有情绪色彩了,这些人可以不带情绪地处理问题,是值得我学习的。

2020年也有几件难处理的事情。

2.1 降薪

年初上班时,老板病怏怏地躺在床上开着钉钉直播给大家公布了降薪的消息,由于买房还欠了朋友的钱,原本计划年终奖+涨薪能让我尽快把钱还完的,结果年终只拿了几千块,工资还降了…之后通过银行的低利息贷款,贷了点才把钱都还完,好在贷款可以3年后再还,也算是把还钱这件难处理的事儿给处理掉了。

企业降薪也是迫不得已的事情,今年年底又给涨回去了一点,能稍微宽裕一些了。

有些朋友因为降薪换了个公司合作,薪资当然也涨了不少,各有所向,换工作对我现在来说,还是有一定成本的。

2.2 工作上的安排

上半年的工作基本上属于硬扛,公司没融到钱,团队没法扩充,下半年组织架构上的调整比较失败,把前半年的成果估计都抹平了,2021年需要在团队人数上达到一个目标值,要敢于要人,死皮赖脸地要人!

3. 其他琐碎的事情

2020年也没坚持做啥事,运动方面倒是比2019年要加强了一些,但年底体检结果跟2019年比还是更差了…

2021年的展望

持续为他人输出价值,是2021年,或者说是今后10年,我做事的大方向。

不论价值大不大,都需要持续输出!

回想这3年,先是生了孩子,然后买车买房,基本的生活设施都已具备了,当然还有很大的优化空间,但今后一定不能盯着钱看,而是要盯着自己给他人带来多少价值

考工作赚钱,只要我稍微用点心,10年后肯定衣食不愁。但想要将自己的财富、影响力提升一个段位,就必须为更多的人带来价值。

技术方面的输出

除了工作之外,还必须能为公司之外的人带来价值。

  1. 2021年输出100篇技术文章,包括 LeetCode.Life、通用技术分享等;
  2. 发挥不要脸的体质,拉到500个粉丝,以微信公众号粉丝、视频号粉丝为度量;

工作上的输出

  1. 做一个可靠的支撑者,服务更多的同事,不甩锅,不打太极,不油腻,能帮忙的一定帮;
  2. 将同事转化为朋友,让对方信任我;
  3. 2021年加上80%同事的微信;

家庭成员身上的输出

  1. 调动家人一起记录生活,一起拍 Vlog,在拍 Vlog 的过程中达到学习、锻炼的目标;
  2. 为老婆输出一部新手机;
  3. 上半年为孩子输出一个培训班,可以与家人之外的人沟通交流;下半年上个幼儿园或者多个培训班;
  4. 家里添一些家具,比如投影仪、儿童学习桌椅等,后续更新。

2021,量化自己的输出!

我身边有许多杰出青年很不屑于用抖音和快手,提起「抖快」这类短视频应用往往表露出鄙视的表情,就跟城里人看到一个刚进城的乡下人一样。有一次我问老孟(我的大学同学),

我:你在美国用 TikTok 吗?
老孟:我不用,那玩意儿容易上瘾。

「那玩意儿」四个字让我感受到老孟对 TikTok 的反感(顺便说一下,TikTok 是字节跳动面向美国市场推出的美国版的抖音,国内正常途径是无法使用 TikTok 的)。

你可以不刷抖音,不玩快手,但你离不开微信。

微信视频号已经推出一段时间了,抖音和快手的玩家早已盯上微信视频号这块肥肉,不信你打开微信视频号看一看,完全跟抖快是一副尿性。相信大家的朋友圈很快就要被这些短视频给攻破了。

为什么有些人非常讨厌这些短视频,而同时又有那么多人沉迷于这些短视频呢?

其实是算法在作祟。

最近读了一本书:《短视频内容算法:如何在算法推荐时代引爆短视频》,作者叫张佳,并不是大众熟知的人物。这本书本是针对正在从事短视频创作或者即将从事短视频创作的人或企业看的, 通过讲述抖音短视频的内容创作算法以及内容分发算法,来帮助创作者更高效地实现内容营销;但作为普通人,或者说是观众,通过这本书也能一窥短视频算法的究竟,从而得知为什么总是给我推荐反感的视频,或者为什么我会沉迷其中无法自拔。

img

1\

观众丧失了”观看视频”的控制权

不论是快手、抖音还是微信视频号,这些短视频应用在播放视频时都有一个细节,你可能没意识到,但我说出来你一定会恍然大悟,那就是:这些短视频默认都不展示进度条。

一条短视频在播放的过程中,我们要么一直看下去,要么觉得不喜欢,划掉它去看下一个;几乎没有人会刻意暂停一个视频,甚至找到进度条将视频往回拖一段重新看。

没有进度条,你的大脑就必须跟着视频一直走,停不下来,任由信息灌输进来,容不得你深入思考。用作者的总结就是:我们失去了”单位时间内获取信息量”的控制权。

为什么进度条会有如此巨大的魔力呢?我觉得,进度条其实代表的是时间,没有进度条,就意味着我们无法控制时间,同时也让我们忘却时间。观众在观看视频时注意力的失控,根源就在于时间纬度上的失控。

2\

创作者丧失了”内容创作”的控制权

对于普通人,偶尔拍几个小视频记录下美好的生活,会显得十分惬意;但对于靠短视频谋生的创作者们,他们创作的内容,必须要有人看才行,今天拍出来的视频如果没人看,那明天就会饿肚子了。

在微信公众号上进行文字创作的时候,作者只需要通过优雅的文字将自己大脑中的画面描述出来即可;读者们可以细细品味文字的美,并且想象出文字描绘的画面。而视频创作并不能靠观众自己想象,而是必须将观众想看到的画面呈现出来,一旦视频画面与观众想象的不吻合,观众便会拒绝这个视频。

由于观众无法控制进度条,即便视频内容后半段极其吸引人,也会因为前半段不符合观众预期而被划掉。

所以,不光观众丧失了对视频的控制权,创作者也不得不放弃天马行空的想法,创作出每一帧都符合观众预期的画面。说白了,创作者要创作观众脑子里的画面,而不是自己脑子里的画面。

3\

如何创作出有流量的故事?

作者借助心理学、认知语言学等等一系列理论知识讲述了人类的基本认知与基本欲望,然后在此基础上教大家如何创作出有流量且吸引人的故事,我大致总结一下:如何创作出有流量的故事?在符合某一类人群的认知的基础上,创作出满足此类人群某些欲望的、且存在信息差的故事。

认知,其实容易理解。不同的人对同一件事的认识和理解是不一样的,比如你讲了一个实习生在生产环境 sudo rm -rf / 的故事,计算机从业者都能懂,但对于大部分英语专业的学生来说,完全不知所云;

欲望,不必解释。作者讲述了史蒂文·赖斯的人类 16 种基本欲望理论,回头去看抖音上的爆款视频,都至少满足了人类这 16 种欲望中的其中一个;

信息差,可以理解为:我知道我不知道的信息,以及 我不知道我不知道的信息。视频内容必须包含某些观众想知道但不知道的信息才能吸引人。

本章中,作者还讲述了故事创作的五要素以及短视频吸引力六法则,对于从事短视频创作的人来说,值得细细研究!

4\

短视频分发算法的原理是什么?

作者通过爬取大量的抖音数据后,总结了短视频分发算法原理,我概括为一句话:算法在识别出人和内容的基础上,将人与内容相连接

更专业一点的解释是:

  1. 算法需要给视频打上标签,比如这个视频是关于计算机的,或者关于养生的,又或者是关于某个城市的等等;
  2. 算法需要给观众打上标签,比如这个人是男生、程序员、单身、秃头等等;
  3. 算法需要将视频与观众匹配,比如将关于计算机的视频推送给程序员,将关于养生的视频推送给秃头的人等等。

作者解释了算法给视频打标签这一细节,其实并不是通过视频画面来给视频打标签的,而是通过视频的作者、视频标题、描述、评论信息、以及哪些人点过赞等等文字信息来给视频打标签的,为什么这么做呢?一方面是由于通过视频画面抽帧的方式来分析视频内容,技术并没有非常成熟;另一方面,在算法面前,你生产的内容是什么并不重要,你的内容被谁喜欢了才重要。举个例子,某个视频被 10 个程序员点赞了,那算法就会把这个视频推给更多的程序员,它并不关心这个视频的内容到底是不是跟程序员相关的。

img

此外,算法为了进行自我验证,会有一个冷启动的过程。简单来讲,算法会对一个陌生的视频先进行小范围的推广,比如推给 A、B、C 三类人群,每类人群推送 100 人;一段时间后,算法发现 B 类人群中有 80 个人点赞了这个视频,而 A 类和 C 类人群里点赞的寥寥无几,那算法就会继续往 B 类人群中再投放 200 人,继续观察,如果 B 类人群中又有 150 人点赞了,那么算法就会认为这个视频符合 B 类人群的口味,冷启动结束,这两天会使劲往 B 类人群身上推这个视频;而如果这次 B 类人群里只有 30 个人点赞,算法就会认为自己当初误判了,B 类人群并不是真的喜欢这个视频,冷启动结束,再也不推这个视频了(是的,再也不推了,因为算法忙着去找下一个优质视频了,在视频来源充足的情况下,是不会再眷恋这个视频了)。

作者将短视频的分发算法讲清楚后,又详细讲解了该如何迎合算法冷启动的过程,感兴趣的朋友可以仔细研究。这里重点说下普通人,也就是观众,如何来利用算法,让算法更好地给自己推荐符合自己口味的内容。

首先,让算法认识你。在个人介绍里简单描述下自己的爱好,比如爱看 NBA 或者喜欢汽车,这个描述信息尽量用计算机能轻易识别的文字来写,比如一个科比的粉丝,自我介绍写成”我是科蜜”,就不如写成”NBA 科比”这样对计算机友好;

然后,每当遇到自己喜欢的视频,点个赞,告诉算法,这个就是我喜欢的类型,没错,你看我都点赞了;

遇到自己反感的视频呢,不要急着划走,点一下”不喜欢”,明确告诉算法,这个我就是不喜欢。

日积月累,算法便会更加了解你,从而变得更加体贴了,如果它还敢给你推反感的视频,那基本上就能放弃这个算法了,也就是放弃这个平台了。

5\

从微信近期在视频号上的一系列动作上看,短视频领域确实十分火热了,超清晰的手机摄像头、简单的视频编辑 APP 以及高速网络带宽,都为短视频提供了非常好的基础;但另一方面,短视频里也充斥着大量乱七八糟、低俗、无聊的垃圾视频,让很多杰出青年望而却步。

我认为,未来不仅需要更好的算法来满足更好的推荐,也需要更多有意思的创作者来产出更好的内容,各位杰出青年值得尝试!

扫一扫,关注下我的视频号,我会时不时来个直播~

img

点击”阅读原文”,可以跳到京东购买这本书。

图|经 PIL 处理后的照片

手机里的照片和视频越来越多,已经有几十 GB 了,需要把内容备份出来。

但是备份到自己电脑上吧,也不太合适,本身电脑的硬盘也不够大;单独买个移动硬盘是可行的,只要硬盘不坏不丢就好。

网盘目前还是能用的,可以把手机里的内容上传到网盘上来做备份。网盘有个最大的顾虑,就是安全问题,万一泄漏了网盘密码就不好了。

所以,上传到网盘上的内容,我想先加密下,再传到网盘上,这样即使网盘的密码泄漏了,还有文件的密码可以保护一下的。

生成缩略图

为了更快地从网盘上找到想要的加密图片,我把图片压缩到很小,只能看到个图片轮廓,通过缩略图来确认自己想看的最终原图:

thumbnail.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
from PIL import Image
import getopt, sys
import os
import cv2

img_type_list = ["jpg", "jpeg", "bmp", "gif", "tiff", "png", "raw", "psd"]
vedio_type_list = ["mp4", "mpeg", "mpg", "avi", "mov", "wmv", "mkv", "rmvb", "flv"]

def video2pic(video, img):
print("video2pic: {} to {}".format(video, img))
cap = cv2.VideoCapture(video)
# cap.set(1, int(cap.get(7)/2))
cap.set(1,2)
rval, frame = cap.read()
if rval:
cv2.imwrite(img, frame)
cap.release()

def thumbnail(in_file,out_file,size):
print("thumbnail: {} to {}, size: {}".format(in_file, out_file, str(size)))
im = Image.open(in_file)
im.thumbnail(size)
im.save(out_file)

def usage():
pass

def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "ht:i:o:s:", ["help", "in=", "out=", "size="])
except getopt.GetoptError as err:
print(str(err))
usage()
sys.exit(2)

_in = None
_out = None
_size = 96

for o, a in opts:
if o in ("-h", "--help"):
usage()
sys.exit()
elif o in ("-i", "--in"):
_in = a
elif o in ("-o", "--out"):
_out = a
elif o in ("-s", "--size"):
_size = int(a)
else:
assert False, "unhandled option"

if (None == _in) or (not os.path.exists(_in)):
print("in is not exists")
sys.exit(2)
if (None == _out):
print("out is not exists")
sys.exit(2)
if not os.path.exists(_out):
print("mkdir out dir")
os.mkdir(_out)

size = (_size, _size)


if os.path.isdir(_in):
files = os.listdir(_in)
for f in files:
src_file_path = _in+"/"+f

if os.path.isfile(src_file_path):
file_type = src_file_path.split(".")[-1].lower()
if src_file_path.split(".")[-1].lower() in vedio_type_list:
thumbnail_file_path = _out+"/"+f+".jpg"
video2pic(src_file_path, thumbnail_file_path)
thumbnail(thumbnail_file_path, thumbnail_file_path, size)
elif src_file_path.split(".")[-1].lower() in img_type_list:
thumbnail_file_path = _out+"/"+f
thumbnail(src_file_path, thumbnail_file_path, size)
else:
print("not img or vedio file: " + src_file_path)

else:
print("in need be a dir.")

if __name__ == "__main__":
main()

文件加密

encrypt.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/sh
# $1 is src dir
# $2 is the passwd

mkdir -p $1"/encrypt"

for i in `ls $1|grep -v encrypt`;
do
echo $i;
tar -zcf - $1"/"$i |openssl des3 -salt -k $2 |dd of=$1"/encrypt/"$i".tgz.des3";
echo $i.tgz.des3;
done

for i in `ls $1|grep -v encrypt`;
do
a=`md5 $i`;
echo $a
echo $a >> $1"/encrypt/md5.txt";
b=`md5 $1"/encrypt/$i.tgz.des3"`;
echo $b
echo $b >> $1"/encrypt/md5.txt";
done

文件解密

decrypt.sh

1
2
3
4
5
6
7
#!/bin/sh
# $1 is src file
# $2 is the passwd

echo $1

dd if=$1 |openssl des3 -d -k $2 |tar zxf -

目录结构