查找人类可读的文件


14

我正在尝试找到一种有效的方法来完成OverTheWire强盗挑战的5级

无论如何,我有一堆文件,只有一个文件符合以下条件:

  • 人类可读
  • 大小为1033字节
  • 不可执行

现在,我正在使用find命令,并且能够找到与最后两个条件匹配的文件:

find . -size 1033c ! -executable

但是,我不知道如何排除不可读的文件。我为该挑战找到的解决方案使用-readable测试参数,但我认为这不起作用。-readable仅查看文件的权限,而不查看其内容,而挑战说明则要求输入ASCII文件或类似名称。


1
您如何定义人类可读的?不是二进制?
terdon

2
文件命令是您的朋友:)
Romeo Ninov


3
人类是地球上最聪明的物种之一。他们也是唯一精通计算机的人。他们可以读取大多数文件,前提是他们能够找到类型并掌握加密密钥的加密密钥。
斯特凡Chazelas

1
警惕!
丹·博塞尔

Answers:


17

是的,您可以find用来查找正确大小的不可执行文件,然后用于file检查ASCII。就像是:

find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII

但是,问题并不像听起来那么简单。“人类可读”是一个非常模糊的术语。想必您是指文字。好的,但是什么样的文字呢?仅拉丁字符ASCII?完整Unicode?例如,考虑以下三个文件:

$ cat file1
abcde
$ cat file2
αβγδε
$ cat file3
abcde
αβγδε
$ cat file4
#!/bin/sh
echo foo

这些都是文本并且易于阅读。现在,让我们看看file它们的构成:

$ file *
file1: ASCII text
file2: UTF-8 Unicode text
file3: UTF-8 Unicode text
file4: POSIX shell script, ASCII text executable

因此,find上面的命令只能找到file1(就本例而言,假设这些文件有1033个字符)。您可以展开find以查找字符串text

find . -type f -size 1033c ! -executable -exec file {} + | grep -w text

使用-wgrep将仅打印在text独立单词中找到的行。那应该非常接近您想要的内容,但是我不能保证没有其他文件类型的描述也可能包含string text


4

尽管-exec通常用于处理找到的文件,但它也可以作为测试。因此,我们可以将其添加到您的其他条件中:

find . \
  -size 1033c \
  -not -executable \
  -exec sh -c 'file {} | grep "text$"' \;

记住,grep当没有找到模式时,返回非零值,并且sh -c "COMMAND"将返回评估结果(只要它是有效的)。因此,这只会打印file <filename>出某些以结尾结尾的文件text,例如“ UTF-8 Unicode文本”或“ ASCII文本”,而不是“带有转义序列的非ISO扩展ASCII文本”。

在一行中,它甚至比结束时还短xargs

find . -size 1033c -not -executable -exec sh -c 'file {} | grep "text$"' \;

请记住,您可以sh -c 'file {} | grep "text$"'用任何自定义命令替换。如果要检查非常复杂的内容,最好提供一个shell脚本并改用它:

find . -size 1033c -not -executable -exec is_human_readable.sh {} \;

从长远来看,它比Shell的历史记录更易于维护:

#!/bin/sh
file "$@" | grep "text$" > /dev/null

真好!但是请注意,匹配text$将排除被识别为shell脚本的内容。任何带有shebang的东西都被识别为脚本,并且这些都是人类可读的。
terdon

@terdon是对的,但是脚本往往是可执行的:D。话虽如此,一个适当的脚本也应该能够识别PDF。但是,另一方面,PDF是否包含人类可读的图像?某些文字的PNG 可读吗?大概。我想完成测试将是…具有挑战性的。
Zeta 2013年


1

您只需要使用:

find inhere -size 1033c

它将为您提供唯一包含密码的文件。


+ 1033c为什么返回更多文件?就像一个大于等于符号吗?
szeitlin

1

只需对目录内容运行以下命令:

$ file -- *
-file00: data
-file01: data
-file02: data
-file03: data
-file04: data
-file05: data
-file06: data
-file07: ASCII text
-file08: data
-file09: data
$ cat -- \-file07
<output>

0
find . -size 1033c ! -executable|xargs file|grep "ASCII text" |awk -F: '{print $1}'

请尝试使用此组合命令。它可以在我的站上工作。


0

你可以试试这个

find . -size 1033c ! -executable -exec file {} +

您的挑战不允许 grep。密码文件将报告为“ ASCII文本,行很长”


0

要过滤掉人类可读的文件名,可以使用[:print:]可打印字符类名。您可以在的手册中找到有关此类的更多信息grep

find . -type f -size 1033c -name "[[:print:]]*" ! -executable

再三考虑,“人类可读”的要求可能是指文件的内容,而不是文件的名称。换句话说,您将搜索文本文件。这有点棘手。正如@D_Bye在注释中建议的那样,然后应使用file命令确定文件内容类型。但是,file在管道之后运行不是一个好主意,因为这会使显示文件名的任务复杂化。这是我的建议:

find . -type f -size 1033c ! -executable -exec sh -c 'file -b $0 | grep -q text' {} \; -print

这是file-part的简要工作方式:

  • 所述-exec谓词执行sh -c 'file -b $0 | grep -q text' FILENAME为每个FILENAME满足所有上述条件(类型,大小,不可执行)。
  • 对于每个文件,shell(sh)运行以下简短脚本file -b $0 | grep -q text,并替换$0为文件名。
  • file程序确定每个文件的内容类型并输出此信息。该-b选项可防止打印每个测试文件的名称。
  • grep过滤来自file程序的输出,搜索包含“ text”的行。(亲自了解一下file命令的典型输出是什么样。)
  • 但是grep不输出过滤的文本,因为它具有-q(quiet)选项。它所要做的只是将其退出状态更改为0(代表“ true”-找到过滤的文本)或1(意味着“错误”-文本“ text”未出现在的输出中file)。
  • 来自的正确/错误退出状态grep将进一步传递sh给,find并作为整个“ -exec sh -c 'file $0 | grep -q text' {} \;”测试的最终结果。
  • 如果上述测试返回true-print则执行命令(即打印测试文件的名称)。

0
bandit4@bandit:~$ ls
inhere

bandit4@bandit:~$ file inhere/*


inhere/-file00: data
inhere/-file01: data
inhere/-file02: data
inhere/-file03: data
inhere/-file04: data
inhere/-file05: data
inhere/-file06: data
inhere/-file07: ASCII text
inhere/-file08: data
inhere/-file09: data

bandit4@bandit:~$ pwd 

/home/bandit4

bandit4@bandit:~$ cat /home/bandit4/inhere/-file07

koReBOKuIDDepwhWk7jZC0RTdopnAYKh
bandit4@bandit:~$ 

只需使用文件inhere / *和cat / home / bandit4 / inhere / -file07

0
find  -type f ! -executable -size 1033c

将从练习中获取文件


0
find . -type f -size 1033c ! -executable | xargs file | grep text

一班风机


0

我认为,以上大多数人使用find和grep来找到该强盗级别的密码的较长方法是最具描述性的命令。

find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII

但是,在更多地使用了“文件”命令之后,我意识到通过检查整个目录文件类型,以这种方式定位人类可读文件(在此级别中也称为ASCII)非常容易。inhere目录包含名称为“ -filexx”的文件,或者使用以下命令快速检查整个inhere目录file ./*

这是我的方法。

bandit4@bandit:~/inhere$ file ./*
./-file00: data
./-file01: data
./-file02: data
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: data

bandit4@bandit:~/inhere$ cat ./-file07
koReBOKuIDDepwhWk7jZC0RTdopnAYKh

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.