尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

逆向顶象5代验证码:图片还原算法与Python实现

逆向顶象5代验证码:图片还原算法与Python实现
📅 发布时间:2026/6/30 18:59:43

1. 项目概述与核心价值

最近在搞一个自动化项目,对接某个第三方服务时,毫无意外地撞上了顶象的验证码。这玩意儿,尤其是他们的第五代产品,在金融、电商这些对安全要求高的场景里,出场率相当高。我遇到的还不是简单的滑块,而是那种带背景干扰、需要点选特定文字的“点选验证码”,以及一种动态扭曲的“图标验证码”。直接上OCR或者常规的CNN模型,识别率惨不忍睹,因为验证码图片在传输到前端渲染之前,已经被“打散”和“混淆”了。

这就引出了我们这次要聊的核心:图片还原。逆向分析顶象5代验证码,最关键、最基础的一步,就是把前端收到的、看似杂乱无章的图片数据,还原成一张人眼或者机器能正常识别的、完整的验证码图片。这不仅是绕过验证的第一步,更是理解其防御机制、评估其安全强度的关键。网上关于顶象逆向的资料不少,但大多集中在某个特定类型的JS代码混淆破解上,对于底层图片数据的还原原理和通用方法,讲得透彻的不多。

所以,我花了些时间,系统地逆向分析了顶象5代几种主流验证码类型(包括滑块、点选、图标等)的图片生成与传输逻辑,并整理出了一套相对通用的图片还原方法。这篇文章,我会把这些逆向分析的思路、核心的还原算法,以及可以直接运行的Python源码分享出来。无论你是做安全研究、爬虫开发,还是单纯对前端反逆向技术感兴趣,相信都能从中获得一些实用的思路和代码。

2. 顶象5代验证码图片混淆机制深度解析

要还原图片,首先得知道它是怎么被“弄乱”的。顶象5代的防御思路很清晰:不直接传输完整的、渲染好的图片。如果直接传一张PNG或者JPEG,那太容易被截获和识别了。他们的策略是,将一张完整的验证码图片,拆解成多个碎片(或称为图元),然后对这些碎片的信息进行编码、混淆,再通过多个网络请求或一段数据包发送给前端。前端拿到这些数据后,再根据另一套隐藏在混淆JS中的逻辑,在Canvas上动态地“拼图”,最终呈现出验证码。

2.1 核心混淆技术拆解

通过对多个顶象5代验证码案例的抓包和JS逆向分析,我总结出其图片混淆主要依赖于以下几种技术组合:

  1. 图元(Sprite)切割与散列:这是最基础的。服务器端有一张包含所有可能字符、图标或滑块背景的“大图”(雪碧图)。当需要生成验证码时,服务端会从这张大图中,随机选取需要的图元(比如几个汉字、几个图标),并计算每个图元在大图中的坐标和尺寸。关键来了,这些坐标和尺寸信息不会明文传输。

  2. 信息编码与置换:坐标(x, y)、宽高(w, h)这类数字信息,会被转换成一种自定义的编码。常见的做法是进行某种形式的进制转换(如十进制转一个自定义字符集的字符串),或者与一个随机生成的偏移量进行运算。更复杂的情况下,这些信息会被打散,分别存放在不同的数据字段或请求中。

  3. Canvas绘图指令混淆:前端还原图片的核心是调用Canvas的drawImageAPI。顶象会对调用drawImage的参数进行动态混淆。你可能在JS代码里看不到直接的ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh),而是看到一堆变量计算,最终参数可能来源于多个数组的拼接、字符串的解码,或者一个复杂函数的返回值。

  4. 多阶段加载与依赖:一张验证码的完整数据可能分多个请求加载。比如,先加载一个包含配置信息的JSON,里面有一些加密的坐标信息;再加载一张或多个雪碧图;最后,一段动态执行的JS逻辑,利用配置信息和雪碧图进行绘制。这种分离增加了直接抓取完整图片的难度。

2.2 不同类型验证码的混淆特点

虽然核心思想一致,但不同类型的验证码在实现细节上有差异:

  • 滑块验证码:重点在于背景图和缺口图(滑块)的生成。背景图通常是完整的,但缺口位置信息被混淆;滑块图本身可能是一个从背景图中扣出的碎片,其形状(非矩形)和位置信息被编码。还原的关键在于定位缺口坐标和重建滑块形状。
  • 点选文字验证码:最常见。一张背景图上有多个汉字,需要按顺序点击其中几个。混淆点在于:a) 所有候选文字的坐标都被混淆;b) 需要点击的“正确文字”的顺序或索引被加密。还原后,我们不仅要知道每个字在哪,还要知道哪几个是目标。
  • 图标点选验证码:与文字点选类似,但图元是图标。图标的雪碧图可能更复杂,图标数量更多。混淆方式可能包括图标的ID映射、坐标变换等。

注意:顶象的JS代码混淆强度很高,变量名、函数名通常被压缩成单字母,逻辑控制流也被平坦化或虚拟化,直接阅读几乎不可能。我们的逆向重点不应放在“读懂每一行JS”,而应放在“定位关键数据流和函数调用”。

3. 逆向分析的关键步骤与工具链

逆向分析是一个系统工程,不能只盯着一个点。下面是我总结的一套标准操作流程(SOP),适用于大多数顶象5代验证码场景。

3.1 环境准备与数据捕获

工欲善其事,必先利其器。你需要一个可控的分析环境。

  1. 浏览器与开发者工具:首选 Chrome 或新版 Edge。其开发者工具(F12)是核心。

    • Sources面板:用于调试JavaScript,设置断点。
    • Network面板:捕获所有网络请求,这是数据的源头。务必勾选“Preserve log”(保留日志)并禁用缓存。
    • Console面板:执行临时JS代码,探测对象。
  2. 抓包工具:虽然浏览器自带的Network面板很强,但像Fiddler Everywhere或Charles这类专业抓包工具,在过滤、重发、断点调试请求/响应方面更强大。它们可以作为浏览器的代理,捕获所有进出流量。

  3. 代码格式化与解混淆工具:面对压缩成一团的JS,你需要一个格式化工具。Chrome Sources面板自带的“Pretty print”({}图标)是第一步。对于更复杂的混淆(如obfuscator.io),可以尝试一些在线的或本地的JS反混淆工具,但不要抱太大希望,顶象的混淆通常能抵御自动反混淆。

3.2 核心逆向流程:从请求到渲染

我的分析通常遵循以下步骤,形成一个闭环:

第一步:定位图片渲染入口打开目标网站,触发验证码。在Network面板中,筛选Img、Media或XHR/Fetch请求,寻找看起来像图片的请求(可能后缀是.jpg/.png,也可能是无后缀的接口)。同时,注意观察那些返回JSON或类似数据结构的请求,它们很可能包含了图片的元信息(坐标、索引等)。

第二步:追踪Canvas绘图调用在Sources面板中,搜索关键词drawImage或canvas。由于代码被混淆,直接搜索可能找不到。更有效的方法是:在验证码加载过程中,在Console中执行document.getElementsByTagName('canvas')找到Canvas元素,然后监听其上下文。或者,在drawImage这个原生API上设置断点(在Sources面板的“Event Listener Breakpoints” -> “Canvas” -> “drawImage”),这是最致命的一招。一旦断点触发,调用堆栈(Call Stack)就会清晰地告诉你,是哪一段混淆的JS代码最终调用了绘图。

第三步:逆向数据流在drawImage的断点处停下来后,观察其参数。这些参数(sx, sy, sw, sh, dx, dy, dw, dh)现在应该是具体的数字。然后,在调用堆栈中,逐层向上回溯(Step Out, Step Over),观察这些数字是如何计算出来的。它们可能来源于某个数组的索引、某个字符串的解码结果、或者某个函数的返回值。你的目标就是找到这些参数的“源头数据”,也就是从网络请求中获取到的原始混淆数据。

第四步:关联网络数据与本地变量将Network面板中捕获到的关键请求响应数据(通常是JSON),与你在JS调试中看到的“源头数据”进行对比。你可能需要将响应内容复制出来,在Console里写一小段代码,模拟JS中的解码逻辑,看是否能得到与断点处观察到的参数一致的数字。这个过程需要反复尝试和推测。

第五步:推导还原算法一旦你成功地将网络数据(如{“a”: “KJ3H”, “b”: “8FDE”, ...})与最终的绘图参数(如sx=120, sy=45)关联起来,你就掌握了还原算法。这个算法可能是一个简单的Base64解码+位移,也可能是一个查表映射,或者一个自定义的字符串到数字的转换函数。

实操心得:不要试图一次性理解整个JS文件。我们的目标是“黑盒”理解其输入(网络数据)和输出(绘图参数)之间的关系。用断点把程序“定住”,然后像法医一样观察现场(变量状态),再倒推过程。记录下每一个成功的关联,用注释和草图记录下来。

4. 通用图片还原算法实现与源码解读

基于上面的逆向分析,我们可以抽象出一个通用的还原流程,并用Python实现。这里我以最常见的“点选文字验证码”为例,假设我们已通过逆向,得知了其数据格式和还原算法。

4.1 算法流程设计

假设我们逆向分析后,发现数据结构和还原逻辑如下:

  1. 网络请求得到一个JSON,其中有一个字段data,是一个字符串数组,如["a1b2", "c3d4", "e5f6"...],每个字符串对应一个文字图元的信息。
  2. 每个字符串(如"a1b2")需要被解码。前两个字符(a1)通过一个自定义的字符映射表转换成数字,作为雪碧图中的x坐标;后两个字符(b2)同理,作为y坐标。
  3. 所有文字图元都来自同一张雪碧图sprite.png,每个图元的大小是固定的,例如 40x40 像素。
  4. 前端Canvas的绘制位置(dx, dy)是根据另一个算法计算出来的,但为了还原一张完整的、包含所有候选字的图片,我们可以简单地将所有图元按解码后的坐标从雪碧图中裁剪出来,然后平铺在一张新的大图上。

4.2 Python源码实现详解

下面是根据上述假设逻辑编写的Python还原脚本。你需要根据实际逆向结果修改decode_position函数和参数。

import json from PIL import Image import re import os class DingXiangImageReconstructor: """ 顶象验证码图片还原器(示例类) 此类根据逆向分析得到的规则,将混淆的坐标数据还原为图片。 实际使用时,你需要根据具体目标调整解码函数、雪碧图路径和尺寸。 """ def __init__(self, sprite_path, tile_width=40, tile_height=40): """ 初始化还原器 :param sprite_path: 雪碧图(包含所有图元的大图)的路径 :param tile_width: 每个图元(如文字)的宽度 :param tile_height: 每个图元的高度 """ self.sprite_img = Image.open(sprite_path).convert('RGBA') self.tile_w = tile_width self.tile_h = tile_height # 假设一个自定义的字符到数字的映射表(这是逆向分析的关键结果之一) # 例如:'a'->0, 'b'->1, ..., '1'->26, '2'->27 ... # 这里用一个简化版示例,实际映射可能更复杂。 self.char_map = {} chars = 'abcdefghijklmnopqrstuvwxyz0123456789' for i, c in enumerate(chars): self.char_map[c] = i def decode_position(self, code_str): """ 解码混淆的坐标字符串。 示例:将"a1b2"解码为(x=0*?+1?, y=1*?+2?),这里需要根据实际算法调整。 这是一个示例函数,实际算法可能涉及进制转换、异或、加减偏移量等。 :param code_str: 混淆的坐标字符串,如"a1b2" :return: (x, y) 在雪碧图中的坐标 """ # 假设 code_str 长度为4,前两位编码x,后两位编码y if len(code_str) != 4: raise ValueError(f"编码字符串长度异常: {code_str}") x_code, y_code = code_str[:2], code_str[2:] # 示例算法:将每个字符映射为数字,然后组合。例如“a1” -> (0, 1) -> 0 * 36 + 1 = 1 # 这里的36是字符集大小。实际算法需逆向确定。 def decode_pair(pair): if pair[0] in self.char_map and pair[1] in self.char_map: return self.char_map[pair[0]] * len(self.char_map) + self.char_map[pair[1]] else: # 如果字符不在映射表,可能是数字直接表示,这里需要灵活处理 try: return int(pair, 16) # 尝试当作16进制数 except: return int(pair) # 尝试当作10进制数 x_index = decode_pair(x_code) y_index = decode_pair(y_code) # 假设索引值需要乘以图元尺寸得到实际像素坐标(也可能就是直接坐标) x = x_index * self.tile_w y = y_index * self.tile_h return x, y def reconstruct_from_json(self, json_data_path, output_path): """ 从保存的JSON数据文件中读取混淆数据,并还原图片。 :param json_data_path: 保存网络响应JSON的文件路径 :param output_path: 还原出的图片保存路径 """ with open(json_data_path, 'r', encoding='utf-8') as f: data = json.load(f) # 假设JSON结构为 {"challenge": "xxx", "data": ["a1b2", "c3d4", ...]} code_strings = data.get('data', []) if not code_strings: print("未找到有效的坐标数据。") return # 计算画布大小:假设我们按5列平铺 cols = 5 rows = (len(code_strings) + cols - 1) // cols # 向上取整 canvas_width = cols * self.tile_w canvas_height = rows * self.tile_h # 创建一张新的透明背景图 canvas = Image.new('RGBA', (canvas_width, canvas_height), (255, 255, 255, 0)) for idx, code in enumerate(code_strings): try: # 1. 解码坐标 sprite_x, sprite_y = self.decode_position(code) # 2. 从雪碧图中裁剪对应图元 tile = self.sprite_img.crop((sprite_x, sprite_y, sprite_x + self.tile_w, sprite_y + self.tile_h)) # 3. 计算平铺位置 col = idx % cols row = idx // cols paste_x = col * self.tile_w paste_y = row * self.tile_h # 4. 粘贴到画布 canvas.paste(tile, (paste_x, paste_y)) print(f"已处理图元 {idx}: 编码{code} -> 雪碧图位置({sprite_x},{sprite_y}) -> 画布位置({paste_x},{paste_y})") except Exception as e: print(f"处理图元编码 {code} 时出错: {e}") continue # 保存还原后的图片 canvas.save(output_path) print(f"图片还原完成,已保存至: {output_path}") # 可选:显示图片 # canvas.show() def reconstruct_from_api(self, api_response_json, output_path): """ 直接传入API响应的JSON字典进行还原。 适用于实时处理。 :param api_response_json: 字典格式的API响应数据 :param output_path: 输出图片路径 """ # 逻辑与 reconstruct_from_json 类似,只是数据来源不同 code_strings = api_response_json.get('data', []) # ... [此处省略重复的还原逻辑,同上] ... # 实际编码中应复用核心还原代码,避免重复。 # 使用示例 if __name__ == '__main__': # 1. 初始化,传入雪碧图和图元尺寸(这些信息需要从网页资源或JS中获取) reconstructor = DingXiangImageReconstructor( sprite_path='./captcha_sprite.png', # 你下载的雪碧图 tile_width=40, tile_height=40 ) # 2. 从文件还原(适用于分析阶段) reconstructor.reconstruct_from_json( json_data_path='./captcha_data.json', # 你抓包保存的JSON数据 output_path='./reconstructed.png' ) # 3. 或者,从内存中的字典还原(适用于集成到爬虫) # fake_api_response = {"challenge": "xxx", "data": ["a1b2", "c3d4", "e5f6", "g7h8"]} # reconstructor.reconstruct_from_api(fake_api_response, './reconstructed_live.png')

4.3 关键代码段解析与适配

  • decode_position函数:这是整个还原器的灵魂,也是你需要根据具体目标进行修改的部分。示例中给出了一个简单的“字符映射+线性组合”的算法。现实中,算法可能包括:

    • Base64解码:混淆字符串可能是Base64编码后的二进制数据再转成的字符串。
    • 自定义进制转换:比如一个36进制的字符串(a-z0-9)转换为十进制数字。
    • 异或(XOR)解密:与一个固定或动态的密钥进行异或运算。
    • 位移操作:解码后的数字需要左移或右移特定位数。
    • 查表法:字符串直接作为一个键,去查询一个在JS中定义好的、巨大的坐标映射字典。 你需要通过断点调试,对比输入字符串和输出坐标,来反推这个函数的具体形式。可以多收集几组数据,用Python尝试不同的解码组合,直到所有数据都能被正确映射。
  • 雪碧图(sprite.png)的获取:这个文件通常是一个静态资源,在验证码页面加载时通过一个单独的图片请求获取。你可以在Network面板的Img类型请求中找到它,直接下载即可。注意,雪碧图可能会更新,但频率通常不高。

  • 图元尺寸(tile_width,tile_height):这个信息可以通过观察还原后的图片是否对齐来调整,更准确的方法是在JS调试中,查看drawImage的sw和sh参数(源图裁剪的宽高),这通常就是图元的固定尺寸。

注意事项:这个还原器生成的是将所有候选图元平铺出来的图片,便于查看和后续的OCR识别。它并不完全等同于前端Canvas上最终的渲染效果(前端可能有随机位置、旋转、叠加等)。但对于识别来说,平铺图已经包含了所有必要信息。

5. 针对不同验证码类型的还原策略调整

上面的示例主要针对点选文字。对于其他类型,核心框架不变,但还原策略需要微调。

5.1 滑块验证码还原要点

滑块验证码通常包含两张关键图片:背景大图和滑块小图(缺口形状)。

  1. 背景图:通常是完整传输的(但可能被切割成多个碎片再拼接)。还原重点在于找到所有碎片(可能通过多个请求)并按照正确的顺序拼接。数据中可能包含每个碎片的索引和布局信息。

  2. 滑块缺口图:这个图是透明的PNG,形状就是缺口。它的还原更关键。你需要找到生成这个缺口形状的算法。数据中可能包含:

    • 缺口在背景图中的位置(gapX,gapY),这个坐标被混淆。
    • 缺口轮廓的路径数据(如果形状不规则),可能是一组被编码的坐标点。
    • 还原后,你需要根据缺口位置和形状,在背景图上模拟“抠图”,生成滑块小图,或者直接计算出缺口的位置用于轨迹模拟。
  3. Python实现调整:除了继承之前的坐标解码,你可能需要增加一个reconstruct_slider_gap函数,专门处理缺口形状的生成。如果缺口是简单的矩形或圆角矩形,那么只需要解码出位置和大小;如果是不规则多边形,则需要解码路径数据,并用PIL的ImageDraw模块绘制出来。

5.2 图标点选验证码还原要点

图标验证码与文字点选极为相似,主要区别在于:

  1. 雪碧图更复杂:图标雪碧图可能包含数十甚至上百个图标,排列更密集。
  2. 映射关系:数据中的编码字符串,可能先映射到一个图标ID,再由ID映射到雪碧图上的坐标。即:编码 -> 图标ID -> (x, y)。你需要逆向出这两层映射关系。
  3. Python实现调整:在decode_position函数中,可能需要先解码出图标ID,然后通过一个预定义的id_to_position字典来查找坐标。这个字典可以通过分析JS中定义图标的数组或对象来获得。

5.3 动态扭曲验证码处理

有些验证码的图元(如文字)在绘制时会有随机的旋转、缩放、透视变换。这些变换参数也可能被编码在传输的数据中。

  • 应对策略:在还原平铺图后,识别算法(如CNN)需要对这些形变有一定的鲁棒性。或者,在还原过程中,我们可以尝试解码出变换参数,并在用PIL粘贴图元时,预先对图元进行相应的仿射变换(Image.transform)。但这会大大增加逆向和还原的复杂度,通常更经济的方法是增强识别模型的抗变换能力。

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

在实际操作中,你肯定会遇到各种各样的问题。下面是我踩过的一些坑和解决方案。

6.1 数据抓取不全或格式不符

  • 问题:按照脚本运行,但code_strings为空,或者解码后坐标明显不对(如负数、巨大数值)。
  • 排查:
    1. 确认数据源:再次检查Network面板,确认你抓取的JSON就是包含坐标数据的那个请求。有时会有多个相似请求。
    2. 检查数据路径:JSON的结构可能不是data字段。可能是imgArr、block、pieces等。用浏览器的Console对抓到的JSON对象进行展开查看,找到真正的数组所在路径。
    3. 验证解码算法:用你逆向推测的解码算法,手动计算一两组数据,与在drawImage断点处看到的真实坐标对比。如果对不上,说明算法有误。

6.2 雪碧图加载失败或尺寸不对

  • 问题:还原出的图片一片空白,或者图元错位。
  • 排查:
    1. 确认雪碧图版本:验证码的雪碧图可能会变。确保你下载的雪碧图与当前请求是同一版本。可以通过对比文件哈希或观察图片内容来判断。
    2. 核对图元尺寸:在drawImage断点处,仔细记录sw和sh的值,确保与代码中的tile_width/height一致。
    3. 检查坐标计算:确认你的解码函数输出的坐标(x, y)是雪碧图中的左上角起始坐标。有时算法给出的可能是图元中心的坐标,需要减去一半宽高进行转换。

6.3 JS混淆强度高,无法定位关键函数

  • 问题:代码被混淆得一塌糊涂,搜索drawImage也找不到,或者调用栈极其复杂。
  • 技巧:
    1. Hook原生API:在Console中执行以下代码,可以Hook住drawImage,打印出每次调用的参数和堆栈,这是终极武器。
      (function() { var originalDrawImage = CanvasRenderingContext2D.prototype.drawImage; CanvasRenderingContext2D.prototype.drawImage = function() { console.log('drawImage called:', arguments); console.trace(); // 打印调用堆栈 return originalDrawImage.apply(this, arguments); }; })();
      执行后,再触发验证码,Console会输出所有绘图信息。
    2. 关注网络请求的触发时机:在疑似包含图片数据的XHR请求上设置“XHR/Fetch Breakpoint”,然后跟栈,找到处理这个请求响应数据的函数。
    3. 寻找特征常量:有时,虽然代码混淆了,但一些固定的数字(如图元尺寸40)或字符串常量可能保留。可以尝试在格式化后的代码中搜索这些常量,定位到相关代码区域。

6.4 还原出的图片用于识别率仍然不高

  • 问题:图片还原出来了,但丢给Tesseract或自定义CNN模型,识别效果还是不好。
  • 分析与解决:
    1. 前端后处理:顶象在前端Canvas绘制时,可能还添加了额外的干扰,如随机颜色微调、高斯模糊、添加噪点等。这些操作是在图元绘制到Canvas之后进行的,我们的还原过程只还原了“图元拼接”,没有模拟这些后处理。解决方案:考虑使用前端无头浏览器(如Puppeteer)直接截图Canvas区域,这是最“保真”但最重的方法。或者,在还原图片后,用OpenCV/PIL模拟添加一些常见的噪声和滤波,让训练数据更接近真实前端效果。
    2. 字体问题:文字验证码可能使用了特殊字体。确保你的OCR训练集或字库包含了该字体。更好的方法是,用还原出的大量图片自制训练集,训练一个专用于该验证码的识别模型。
    3. 图标分类:对于图标验证码,本质上是一个多分类问题。你需要收集所有可能的图标(可以从雪碧图中完整裁剪出来),建立图标库,然后对还原出的图标图元进行特征匹配或分类。

6.5 代码集成与稳定性

  • 问题:脚本在本地测试成功,但集成到自动化流程中不稳定。
  • 建议:
    1. 异常处理:像上面的示例代码一样,在每个关键步骤(解码、裁剪、粘贴)都用try...except包裹,并记录日志,避免单次失败导致整个流程崩溃。
    2. 参数可配置化:将雪碧图路径、图元尺寸、解码映射表等写成配置文件,方便适配不同网站或验证码版本的更新。
    3. 模拟浏览器环境:有些验证码的JS逻辑依赖于浏览器环境变量(如window,document)。如果你的还原脚本需要执行部分JS解码逻辑(使用PyExecJS等),要确保环境模拟足够真实。

逆向分析是一个不断对抗和升级的过程。顶象的验证码也在持续迭代。今天有效的方法,明天可能就会失效。因此,理解其核心思想和掌握通用的分析、调试、逆向方法,比拥有一份固定的源码更重要。这套图片还原方法,为你提供了一把打开大门的钥匙,门后的世界(完整的验证码破解),还需要结合行为轨迹模拟、深度学习识别等技术,但那已经是另一个层面的挑战了。希望这篇长文和附带的源码,能成为你应对顶象5代验证码时,一份扎实的参考资料。

相关新闻

  • GANsformers:在StyleGAN2中嵌入注意力机制提升局部几何一致性
  • AI驱动跨浏览器兼容性测试:从自动化到智能化的实践指南
  • 生成式AI不是模仿创作,而是重构创造的数学范式

最新新闻

  • pytest-order插件详解:控制测试用例执行顺序的实战指南
  • Qwen3-Omni双模块架构:Thinker-Talker物理隔离实现234ms低延迟多模态推理
  • Python自动化测试框架对比:unittest与pytest核心原理与工程实践
  • 大模型MoE架构原理与工程实践:理解专家激活率与显存优化
  • 大模型Fast-Slow双轨推理:认知节奏的工程化实现
  • PCIe 5.0 AIC金手指Layout避坑指南:从CEM规范到10层板实战布线

日新闻

  • 【计算机毕业设计案例】基于 Spring Boot+Vue 的电影售票系统设计与实现 前后端分离架构下影院在线购票管理平台(程序+文档+讲解+定制)
  • 到底 TMD 用哪个: npm, pnpm, Yarn, Bun, Deno? 傻瓜, 当然用 npm 啦
  • Google限制Meta使用Gemini模型 凸显AI授权竞争白热化

周新闻

  • Windows字体自定义终极方案:No!! MeiryoUI完全指南
  • Deepin Boot Maker:告别命令行,3分钟制作Linux启动盘的智能解决方案
  • Plain Craft Launcher 2:重新定义你的Minecraft游戏体验

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号