news 2026/10/16 3:48:21

CTF图片隐写分析实战:从Look题看Misc完整排查思路

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CTF图片隐写分析实战:从Look题看Misc完整排查思路

1. 从一道十一月赛题看隐写分析的完整思路

“百度杯”CTF比赛十一月场里有一道叫“Look”的题目,圈内人习惯把它归到Misc方向下的图片隐写类。这类题目的典型特征是:给一张看起来平平无奇的图片,没有额外提示,没有附件说明,全靠选手自己从像素、文件结构、元数据里把flag挖出来。很多刚接触CTF的朋友拿到这种题会懵——图片能有什么秘密?不就是一张图吗?但恰恰是这种“看起来没问题”的东西,最容易藏东西。

这篇文章我会把“Look”这类图片隐写题的完整分析链路拆开讲清楚:从拿到文件的第一秒该做什么,到用什么工具、按什么顺序排查,再到每一种隐写手法背后的原理和对应的提取方法。不管你是刚入门的CTF新手,还是想系统梳理Misc图片题套路的选手,这篇内容都能直接拿去当操作手册用。我不会只告诉你“用某某工具”,而是把为什么用这个工具、什么时候该换思路、哪些坑我亲自踩过,全部摊开来说。

先明确一点:图片隐写不是玄学,它本质上是利用了图片文件格式的冗余空间、像素数据的可操作性,或者人类视觉系统的局限性。理解了这三条,你面对任何一张图都知道该往哪个方向想。下面我按实战顺序,从最基础的排查开始,一层一层往里剥。

2. 图片隐写题的整体排查框架

2.1 为什么先看文件本身而不是直接上工具

很多人拿到图片第一反应是丢进某个在线解码网站或者直接跑脚本,这个习惯不太好。正确的第一步应该是看文件本身——文件大小、文件类型、文件头尾是否正常。原因很简单:如果一张图被追加了数据,文件大小会异常;如果文件头被篡改,直接打开可能报错或者显示异常;如果图片末尾有附加内容,用十六进制编辑器一眼就能看出来。

我一般会先用系统自带的文件信息查看,或者命令行下的file命令确认文件真实类型。有些题目会把一张压缩包改后缀成.jpg,你以为是图片,其实里面是个zip。这种情况在CTF里非常常见,尤其是Misc方向。

file look.jpg # 输出可能是:JPEG image data, JFIF standard... # 如果输出是 Zip archive data,那恭喜你,直接改后缀解压就行

如果确认是真正的图片文件,接下来看文件大小。一张正常拍摄或生成的图片,大小和分辨率是成比例的。如果一张 100x100 的图有 2MB,那几乎可以肯定里面塞了东西。这时候用binwalk或者手动查看十六进制,往往能在文件末尾发现附加数据。

注意:不要一上来就用在线工具。在线工具适合快速验证,但很多题目会检测文件是否被修改过,或者在线工具本身有大小限制。养成用本地工具的习惯,关键时刻不掉链子。

2.2 图片隐写的四大类手法

把图片隐写的手法归归类,其实就四大类,每一类都有对应的排查手段:

手法类型核心原理典型表现排查工具
文件结构类利用文件格式冗余或附加数据文件大小异常、末尾有额外数据binwalk、hex编辑器
像素数据类修改像素值的最低有效位视觉无差异、LSB平面有规律StegSolve、zsteg
元数据类在EXIF、注释字段藏信息图片属性里有异常文字exiftool、strings
视觉编码类利用人眼对特定图案不敏感需要调整对比度或通道才能看到StegSolve、PS

“Look”这道题从名字上就有暗示——“看”。但“看”不是让你盯着原图看,而是让你用不同的方式去看。可能是换个通道看,可能是放大看,可能是调整色阶看。这个思路在后面会反复用到。

2.3 工具准备清单

工欲善其事,必先利其器。图片隐写常用的工具就那么几个,但每个都要会用、知道什么时候用:

  • StegSolve:Java写的图片分析工具,可以逐通道查看、调整位平面、做颜色过滤。图片隐写题的万能瑞士军刀。
  • zsteg:专门针对PNG和BMP的隐写检测工具,能自动跑多种LSB组合。
  • binwalk:检测文件内嵌的其他文件,对附加数据特别有效。
  • exiftool:查看和编辑图片元数据,EXIF里藏flag是经典套路。
  • 010 Editor / HxD:十六进制编辑器,手动分析文件结构必备。
  • Python + PIL:写自定义脚本处理像素数据,应对非标准隐写。

这些工具不需要全部精通,但至少要知道每个工具解决什么问题。比如你怀疑是LSB隐写,直接上zsteg跑一遍;怀疑是附加数据,binwalk扫一下;怀疑是元数据,exiftool看一眼。排查顺序对了,效率能提高好几倍。

3. 核心细节解析与实操要点

3.1 文件结构排查:binwalk和十六进制分析

拿到“Look”这张图,第一步我会跑binwalk。这个工具的原理是扫描文件中的特征签名,识别是否嵌入了其他文件格式。很多CTF题会把flag藏在图片末尾追加的数据里,或者把多个文件拼接在一起。

binwalk look.jpg

如果输出里出现了Zip archive data、PNG image、PDF document之类的字样,说明图片里嵌了东西。这时候可以用binwalk -e自动提取,但自动提取有时候会失败,尤其是数据被加密或者偏移量不对的时候。更稳妥的方式是用十六进制编辑器手动定位。

打开十六进制编辑器,直接跳到文件末尾。JPEG文件正常以FF D9结尾,如果FF D9后面还有数据,那这些数据就是附加内容。PNG文件以IEND块结尾,后面如果有数据也是附加的。把这些数据复制出来,另存为新文件,往往就能得到隐藏的内容。

实操心得:有些题目会在附加数据前加一个假的结束标记,让你以为文件到那里就结束了。比如JPEG里出现多个FF D9,真正的结束标记是最后一个。遇到这种情况,从后往前找,或者用binwalk的详细模式看每个签名位置。

还有一种情况是文件头被修改。比如把PNG的文件头改成JPEG的,导致图片打不开或者显示异常。这时候需要对照文件格式规范,把文件头改回来。PNG的文件头是89 50 4E 47 0D 0A 1A 0A,JPEG是FF D8 FF。改对了,图片就能正常显示,隐藏的信息也可能随之出现。

3.2 像素数据排查:LSB隐写的原理与检测

LSB(Least Significant Bit)隐写是图片隐写里最常见的手法,没有之一。它的原理很简单:图片的每个像素由RGB三个通道组成,每个通道的值是0-255。把每个值的最低位(也就是二进制最后一位)替换成要隐藏的信息,对视觉的影响几乎为零,但提取出来就是完整的数据。

举个例子,一个像素的红色通道值是10110110,最低位是0。如果我要藏一个bit1,就把这个值改成10110111,也就是从182变成183。肉眼根本看不出区别,但提取的时候只看最低位,就能还原出隐藏的信息。

检测LSB隐写,StegSolve是最直观的工具。打开图片后,选择Analyse -> Data Extract,然后勾选不同的位平面和通道组合。如果某个组合下出现了有规律的图案或者文字,那就是LSB隐写的位置。

zsteg则更适合批量检测。它内置了多种LSB提取模式,包括不同的通道顺序、位顺序、扫描方向等。直接跑:

zsteg look.png

输出里会列出所有检测到的可疑数据。如果看到类似flag{...}或者有意义的字符串,基本就确定了。zsteg还支持指定参数提取,比如zsteg -E "b1,rgb,lsb,xy" look.png可以按指定模式提取数据。

注意:LSB隐写不一定是按RGB顺序、从左到右、从高位到低位。有些题目会打乱顺序,比如按BGR、从右到左、从低位到高位。zsteg的多种模式就是应对这种情况的。如果标准模式跑不出来,试试其他组合。

3.3 元数据与注释字段排查

图片的元数据区是另一个容易被忽视的藏身之处。JPEG的EXIF字段可以存拍摄设备、时间、GPS信息,也可以存自定义注释。PNG的tEXt块可以存文本信息。这些地方藏flag,不需要修改任何像素数据,文件看起来完全正常。

用exiftool查看:

exiftool look.jpg

输出会列出所有元数据字段。如果看到Comment、Description、Title之类的字段里有可疑字符串,直接提取就行。有些题目会把flag拆成几段放在不同字段里,需要拼起来。

strings命令也能快速扫一遍:

strings look.jpg | grep -i flag

这个命令会提取文件里所有可打印字符串,然后过滤包含flag的行。简单粗暴,但对明文藏flag的题目特别有效。

实操心得:有些题目会把flag用Base64或者其他编码处理后再放进元数据。看到一串看起来像Base64的字符,先解码试试。另外,PNG的tEXt块有时候会有多个,用pngcheck或者exiftool -a可以看全部。

3.4 视觉编码与通道分析

有些隐写不修改文件结构,也不藏元数据,而是直接在像素值上做文章,但用的不是LSB,而是更复杂的编码方式。比如把信息编码成颜色通道的差异、特定区域的亮度变化、或者需要调整对比度才能看到的图案。

StegSolve的通道查看功能在这里特别有用。依次查看R、G、B、Alpha通道,以及各种颜色组合。有时候单独看某个通道,隐藏的文字或图案就会显现出来。还可以用Frame Browser逐帧查看GIF,或者用Stereo模式看立体图。

另一种常见手法是颜色过滤。比如把某个颜色范围的像素高亮显示,隐藏的信息就会浮现。StegSolve的Color Filter功能可以按颜色筛选,配合不同的过滤模式,能发现很多肉眼看不到的东西。

如果这些自动工具都跑不出来,那就需要写脚本手动分析了。Python的PIL库可以读取每个像素的值,按自定义规则提取信息。比如按行扫描,把每个像素的某个通道值转换成二进制,再拼成字符。

from PIL import Image img = Image.open('look.png') width, height = img.size pixels = img.load() bits = '' for y in range(height): for x in range(width): r, g, b = pixels[x, y][:3] bits += str(r & 1) # 提取红色通道最低位 # 把bits按8位一组转换成字符 chars = [chr(int(bits[i:i+8], 2)) for i in range(0, len(bits), 8)] print(''.join(chars))

这段代码是最基础的LSB提取,实际题目可能需要调整通道、位顺序、扫描方向等参数。但核心思路就是这样:遍历像素,提取特定位,拼接成数据。

4. 实操过程与核心环节实现

4.1 第一步:确认文件类型与基本信息

假设我们拿到的文件是look.jpg。先跑一遍基础检查:

file look.jpg ls -la look.jpg

如果file命令输出的是JPEG image data,说明文件头正常。如果输出的是data或者Zip archive,那就有问题,需要进一步分析。文件大小也要留意,如果明显偏大,说明可能有附加数据。

接着用identify命令(ImageMagick工具集)查看图片的详细参数:

identify -verbose look.jpg

这个命令会输出图片的格式、分辨率、颜色深度、通道数等信息。如果颜色深度异常(比如正常应该是8位,显示16位),或者通道数不对,都可能是隐写的线索。

4.2 第二步:binwalk扫描与附加数据提取

binwalk look.jpg

假设输出如下:

DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 0 0x0 JPEG image data, JFIF standard 30256 0x7630 Zip archive data, at least v2.0 to extract

这说明在偏移量30256处有一个zip文件。用dd命令提取:

dd if=look.jpg of=hidden.zip bs=1 skip=30256

然后解压hidden.zip,看看里面是什么。如果zip有密码,可能需要用其他方式破解,或者密码就藏在图片的其他地方。

注意:binwalk的自动提取-e参数有时候会把整个文件都提取出来,包括图片本身。手动用dd更精准,尤其是当附加数据有特定偏移量的时候。

4.3 第三步:StegSolve逐通道排查

打开StegSolve,加载图片。先看Image Combiner,试试不同的通道组合,比如R-G、G-B、R-B。有时候两个通道相减,隐藏的信息就会显现。

然后进Analyse -> Data Extract,这是LSB提取的核心功能。勾选不同的位平面(Bit Plane 0到7),选择不同的通道(R、G、B、Alpha),观察预览窗口。如果某个组合下出现了清晰的文字或图案,那就是它了。

我一般会按这个顺序试:

  1. RGB通道,Bit 0,按行扫描
  2. RGB通道,Bit 0,按列扫描
  3. 单个通道,Bit 0
  4. 其他位平面

如果标准顺序跑不出来,再试BGR、从右到左、从下到上等变体。StegSolve的Bit Order和Pixel Order选项可以调整这些参数。

4.4 第四步:zsteg自动化检测

对于PNG图片,zsteg是效率最高的工具。直接跑:

zsteg -a look.png

-a参数会尝试所有已知的提取模式。输出会很长,但如果有flag,通常会在前面几行就出现。如果输出里有meta相关的行,也要留意,可能是元数据里藏了东西。

zsteg的输出格式一般是:

b1,rgb,lsb,xy .. text: "flag{...}" b2,r,lsb,xy .. text: "some other data"

前面的b1,rgb,lsb,xy表示提取模式:第1位、RGB通道、LSB、XY顺序。后面的text就是提取到的内容。如果看到有意义的字符串,直接复制出来就行。

4.5 第五步:自定义脚本处理非标准隐写

如果所有现成工具都跑不出来,那就需要写脚本了。非标准隐写可能涉及:

  • 按特定数学公式修改像素值
  • 把信息编码成像素之间的差值
  • 利用图片的Alpha通道藏信息
  • 把信息分散在多个位平面

写脚本之前,先明确几个问题:信息藏在哪个通道?按什么顺序读取?每个像素取几位?有没有加密或编码?

以“Look”这道题为例,如果题目名字暗示“看”,那可能隐藏的信息需要特定的查看方式。比如把图片放大到一定程度,或者调整对比度,才能看到隐藏的文字。这时候用PS或者GIMP调整色阶、曲线,可能比写脚本更快。

还有一种情况是图片本身包含多个图层或者帧。GIF文件可以用convert命令拆帧:

convert look.gif frame_%d.png

然后逐帧检查。有些题目会把flag分散在不同帧里,需要全部提取出来拼接。

4.6 第六步:综合分析与flag提取

走到这一步,基本能确定隐写的位置和方式了。把提取到的数据整理一下,看看是不是完整的flag格式。CTF的flag通常是flag{...}或者ctf{...}的形式。如果提取到的是一串乱码,可能需要先解码,比如Base64、Hex、URL编码等。

echo "提取到的字符串" | base64 -d echo "提取到的字符串" | xxd -r -p

如果flag被拆成多段,分别藏在不同的地方,那就需要把所有片段找齐再拼接。这种题目考验的是排查的全面性,不能漏掉任何一个可能的藏身点。

5. 常见问题与排查技巧实录

5.1 图片打不开或者显示异常怎么办

这种情况通常是文件头被修改或者文件结构被破坏。先用十六进制编辑器查看文件头,对照标准格式修复。JPEG的标准文件头是FF D8 FF E0或FF D8 FF E1,PNG是89 50 4E 47。如果文件头不对,改回来再试。

如果文件头正常但还是打不开,可能是文件中间的数据被修改了。用pngcheck检查PNG的块结构,或者用jpeginfo检查JPEG的完整性。这些工具会告诉你具体哪个位置出了问题。

5.2 LSB提取出来是乱码怎么办

先确认提取参数是否正确。常见的错误包括:通道顺序搞反了(RGB vs BGR)、位顺序搞反了(MSB vs LSB)、扫描方向搞反了(XY vs YX)。用StegSolve手动试几种组合,找到有规律的那个。

如果参数没问题但还是乱码,可能是数据被加密或者编码了。试试常见的解码方式:Base64、Hex、二进制转ASCII、反转字符串等。有些题目会在LSB数据前面加一个标识头,比如Salted__表示是OpenSSL加密的数据,那就需要密码才能解密。

5.3 binwalk提取出来的文件打不开

binwalk自动提取有时候会多提取或者少提取数据。用-e参数时,它会尝试提取所有识别到的文件,但偏移量可能不准确。手动用dd按binwalk输出的偏移量提取,通常更可靠。

如果提取出来的zip打不开,可能是数据不完整或者被加密了。检查zip的文件头PK\x03\x04是否存在,如果不存在,说明偏移量不对。用十六进制编辑器手动搜索PK签名,找到正确的位置。

5.4 常见问题速查表

问题现象可能原因解决方法
图片打不开文件头被改十六进制修复文件头
文件大小异常附加数据binwalk扫描,dd提取
视觉无异常但怀疑隐写LSB隐写StegSolve、zsteg检测
元数据有可疑字符串编码后藏flagBase64/Hex解码
工具跑不出结果非标准隐写写Python脚本自定义提取
提取数据乱码参数错误或加密调整参数,尝试解码
多个可疑位置信息分散全部提取后拼接

5.5 独家避坑技巧

技巧一:不要忽略图片的Alpha通道。很多LSB隐写题只关注RGB,但Alpha通道同样可以藏信息。尤其是PNG图片,Alpha通道的LSB经常被用来藏flag。StegSolve和zsteg都支持Alpha通道检测,别忘了勾上。

技巧二:注意图片的调色板。对于PNG-8或者GIF这种使用调色板的格式,隐写可能藏在调色板的索引值里,而不是像素值本身。这时候需要读取调色板数据,分析索引的规律。Python的PIL库可以获取调色板信息。

技巧三:试试图片的反色和旋转。有些题目会把flag以极低对比度的方式嵌入图片,正常看几乎看不见。用StegSolve的反色功能,或者调整对比度,可能就显现出来了。旋转90度、180度也值得一试,尤其是当图片内容看起来不对称的时候。

技巧四:留意图片的文件名和题目描述。“Look”这个题目名字本身就是提示——让你“看”。怎么看?换个方式看。题目描述里如果有“仔细观察”、“放大看看”之类的词,也是在暗示视觉层面的隐写。不要只盯着技术手段,题目的文字信息同样重要。

技巧五:多工具交叉验证。一个工具跑不出来不代表没有隐写,可能是工具不支持这种格式或手法。StegSolve、zsteg、binwalk、exiftool都跑一遍,互相印证。如果所有工具都跑不出来,再考虑写脚本。

6. 工具选型与效率优化

6.1 不同场景下的工具选择

图片隐写题的工具选择,取决于你面对的是什么格式、什么类型的隐写。我整理了一个决策流程:

  • JPEG图片:优先用binwalk查附加数据,exiftool查元数据,StegSolve查LSB。JPEG的LSB隐写相对少见,因为JPEG是有损压缩,修改像素值会被压缩算法破坏。但CTF题目经常用无损方式重新保存,所以也不能完全排除。
  • PNG图片:zsteg是首选,支持多种LSB模式。StegSolve作为补充,手动调整参数。PNG还可能有tEXt块藏信息,用exiftool或pngcheck查看。
  • GIF图片:先拆帧,逐帧检查。GIF的调色板和帧延迟都可能藏信息。用convert拆帧,然后用StegSolve或脚本分析每一帧。
  • BMP图片:BMP格式简单,没有压缩,LSB隐写非常常见。zsteg和StegSolve都能处理。BMP的文件头也可能被修改,注意检查。

6.2 自动化脚本的编写思路

当现成工具不够用的时候,写脚本是必经之路。一个通用的图片隐写检测脚本,应该包含以下功能:

  1. 读取图片,获取像素数据
  2. 支持多种提取模式(通道、位平面、扫描顺序)
  3. 自动尝试常见组合,输出可疑结果
  4. 支持数据解码(Base64、Hex等)
from PIL import Image import base64 def extract_lsb(img_path, channel=0, bit=0, order='xy'): img = Image.open(img_path) width, height = img.size pixels = img.load() bits = '' if order == 'xy': coords = [(x, y) for y in range(height) for x in range(width)] else: coords = [(x, y) for x in range(width) for y in range(height)] for x, y in coords: pixel = pixels[x, y] if isinstance(pixel, int): val = pixel else: val = pixel[channel] bits += str((val >> bit) & 1) # 按8位分组转字符 chars = [] for i in range(0, len(bits) - 7, 8): byte = bits[i:i+8] chars.append(chr(int(byte, 2))) return ''.join(chars) # 尝试不同组合 for ch in range(3): for b in range(8): result = extract_lsb('look.png', ch, b) if 'flag' in result.lower(): print(f'Channel {ch}, Bit {b}: {result}')

这个脚本可以扩展成自动遍历所有通道和位平面,找到包含flag的组合。实际比赛中,这种脚本能节省大量手动尝试的时间。

6.3 效率优化的几个关键点

第一,先跑自动化工具,再手动分析。zsteg和binwalk能解决80%的题目,先跑一遍,有结果就直接用,没结果再手动。不要一上来就写脚本,浪费时间。

第二,建立自己的工具库和脚本库。把常用的提取脚本保存下来,遇到类似题目直接改参数就能用。CTF题目有很多套路是重复的,积累多了效率自然高。

第三,学会看十六进制。很多隐写题的线索就在文件结构的细节里,比如异常的块长度、多余的空字节、不正常的偏移量。养成用十六进制编辑器看文件的习惯,能发现很多工具发现不了的东西。

第四,记录每次解题的步骤和参数。尤其是成功的提取参数,下次遇到类似题目可以直接复用。我自己的笔记里就记了几十种LSB提取的组合,遇到新题先翻笔记,往往能快速定位。

7. 从“Look”这道题延伸出的通用方法论

“Look”这道题的核心考点其实不是某个具体的技术点,而是一种思维方式:当一张图片看起来完全正常的时候,你要知道从哪里开始怀疑,按什么顺序排查,用什么工具验证。这种思维方式比记住某个工具的用法更重要。

我个人的经验是,图片隐写题的排查顺序应该是:文件结构 -> 元数据 -> 像素数据 -> 视觉编码。这个顺序是从外到内、从简单到复杂。先看文件本身有没有问题,再看元数据有没有线索,然后分析像素数据,最后才考虑需要调整视觉才能看到的内容。大部分题目在前两步就能解决,只有少数难题需要走到第三步和第四步。

另外,不要忽视题目本身的提示。题目名字、描述、甚至比赛的主题,都可能暗示隐写的方式。“Look”这个名字就是在告诉你,这道题的关键在于“看”的方式。换个通道看、放大看、调整对比度看,都是“看”的不同方式。理解了题目的意图,解题方向就清晰了。

最后说一点:图片隐写题考察的是细致和耐心。很多时候flag就藏在某个你忽略的细节里,比如一个不起眼的元数据字段、一个异常的像素值、一个多余的字节。养成逐项排查的习惯,不放过任何一个可疑点,这才是做好Misc题目的根本。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 3:47:50

Delphi StringGrid 剪贴板复制粘贴完整方案与陷阱解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 3:47:24

WPF DataGrid多行表头实现:合并表头、HeaderRows及避坑指南

简介:一份面向WPF开发者的Telerik DataGrid多行表头示例工程,以实际项目存档为基础,演示如何通过RadGridView实现多级表头、嵌套列组与自定义列布局,适合需要构建报表、数据分析或复杂表格界面的初级至中级开发人员学习参考。工程…

作者头像 李华
网站建设 2026/10/16 3:46:29

磁盘I/O瓶颈排查与优化:从监控指标到系统调优实战指南

咱们直接聊正题。做后台开发或者运维的同学,大概率都经历过这种场景:系统CPU不高、内存充足,但接口就是慢,数据库查询就是卡,页面转圈圈。查了半天,最后定位到磁盘I/O上——要么是大量随机读写把磁盘拖垮了…

作者头像 李华
网站建设 2026/10/16 3:46:04

2022年CSP-J复赛真题及题解: T3 逻辑表达式

2022年CSP-J复赛真题及题解: T3 逻辑表达式 题目描述 逻辑表达式是计算机科学中的重要概念和工具,包含逻辑值、逻辑运算、逻辑运算优先级等内容。 在一个逻辑表达式中,元素的值只有两种可能: 0 0 0(表示假)和 1 1 1(表示真)。元素之间有多种可能的逻辑运算,本题中只…

作者头像 李华
网站建设 2026/10/16 3:45:38

零基础用AI开发OPC网关:从Modbus到OPC UA的完整实践

本来没打算写这个复盘,但这阵子总有朋友私信问我同一个问题:一个连 PLC 都没摸过、串口都没调过的人,真的能靠 AI 写出一个能用的 OPC 网关吗?我的答案是能,而且过程比多数人想象得顺。这里说的 OPC 网关,不…

作者头像 李华
网站建设 2026/10/16 3:45:34

Spring MVC HandlerMapping 源码深度解析:路由机制与自定义实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华