wenmo8 发布的文章

前言

DVWA
(Damn Vulnerable Web Application)靶场是一个旨在帮助安全人员和开发人员学习和提高网络安全技能的开源项目。它是一个故意存在多种安全漏洞的 PHP/MySQL 网络应用程序,通常用于学习和测试各种网络攻击技术

工具下载链接:
https://pan.quark.cn/s/49ef556eb32b

搭建教程

1. 事前准备

本文是这windows下进行靶场搭建,虚拟机下也是一样,都需要提前准备和
phpstudy和靶场文件

2. 靶场安装

先将下载的文件解压到该文件夹下并改名为
DVWA
方便后续使用

在该文件夹下复制并且粘贴一份
config.inc.php.dist

记事本打开
config.inc.php.dist
文件,密码修改为
123456
,然后保存

将此文件后缀删除

在phpstudy面板创建数据库,记得与上面文件里的内容对应

此时就可以正常访问了,账号密码为文件设置的账号密码,记得一致

3. 靶场环境搭建

登录后界面如下

创建数据库

4. 初始化靶场

打开这个文件

复制如下内容到里面

$_DVWA[ 'recaptcha_public_key' ]  = '6LdK7xITAAzzAAJQTfL7fu6I-0aPl8KHHieAT_yJg';
$_DVWA[ 'recaptcha_private_key' ] = '6LdK7xITAzzAAL_uw9YXVUOPoIHPZLfw2K1n5NVQ'; 

回到浏览器刷新页面可以看到如下界面

打开
php.ini
这个文件

搜索
allow_
改成On

回到浏览器创建数据库

然后需要重新登录

账号:admin
密码:password

然后登录就可以了

需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。

方案一:将方法参数存成JSON字符串,然后JSON反序列化成对象,然后反射调用

目标方法时这样的:

CommandResp sendXXX(BaseCommandApiDTO<XXX> baseCommandApiDTO);

方式一:FastJson

Class mainBody = Class.forName(entity.getMainBodyType());
ParameterizedTypeImpl parameterizedType = new ParameterizedTypeImpl(new Type[]{mainBody}, null, BaseCommandApiDTO.class);
Object obj = JSON.parseObject(entity.getMsgText(), parameterizedType);

CommandResp resp = ReflectUtil.invoke(serviceObj, methodName, obj);

方式二:Jackson

public class ObjectMapperHolder {
    private static final ObjectMapper objectMapper = new ObjectMapper();
    public static ObjectMapper getObjectMapper() {
        objectMapper.registerModule(new Jdk8Module());
        objectMapper.registerModule(new JavaTimeModule());
        return objectMapper;
    }
}


ObjectMapper mapper = ObjectMapperHolder.getObjectMapper();
JavaType javaType = mapper.getTypeFactory().constructParametricType(BaseCommandApiDTO.class, mainBody);
Object obj = mapper.readValue(entity.getMsgText(), javaType);

CommandResp resp = ReflectUtil.invoke(serviceObj, methodName, obj);

实践中发现,这两种方式容易导致OOM

方案二:直接将参数对象存到数据库中

数据库对应字段设置BLOB类型(这里设置的是MEDIUMBLOB) ,对应的java字段类型是byte[]

//  写入对象
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(baseCommandApiDTO);
oos.flush();
byte[] data = bos.toByteArray();

//  读取对象
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(entity.getMsgObj()));
Object obj = ois.readObject();

最后的最后,优化建议:

1、尽量不要在数据库中存json字符串,如果非要存,建议字段类型设置为json,这样可以节省空间。因为你无法控制json字符串的长度,所以长度设置是个问题,另外json反序列化比较占内存。

2、长度很大的字段(比如blob类型的)建议单独存一张关联表

局域网搜索

pings 所有设备找到在线设备并登录网页

:: 作者:mao 时间:2024 11.30
@echo off
chcp 65001 >nul
:: 启用延迟环境变量扩展
setlocal enabledelayedexpansion

:: 检查是否提供了必要的参数
if "%~1"=="" (
    echo ================================
    echo 用法: %~nx0 网段 起始范围 结束范围
    echo 例如: %~nx0 192.168.1 10 30
    echo ================================
    exit /b
)

:: 将参数赋值给变量
set "network=%1"
set "start=%2"
set "end=%3"

:: 验证范围有效性
if %start% GTR %end% (
    echo ================================
    echo 错误: 起始范围不能大于结束范围。
    echo ================================
    exit /b
)

:: 启动测试
echo ================================
echo 正在测试 IP 范围: %network%.%start% 到 %network%.%end% 的主机...
echo ================================

:: 循环遍历范围并测试每个主机
for /l %%i in (%start%,1,%end%) do (
    set "currentIP=%network%.%%i"
    ping -n 3 -w 500 !currentIP! >nul
    if errorlevel 1 (
        echo [警告] !currentIP! 不可达
    ) else (
        echo [信息] !currentIP! 在线
    )
)

:: 测试完成提示
echo ================================
echo 测试完成!
echo ================================
pause

进行对网页的破解

通过暴力破解hydra Burp Suite python来达到破解网站密码,使用f12进行对网站的调试得到合适的表单格式和url

进入文件管理系统

更改ubuntu的root密码
在另一台Linux上生成加密过后的密码

[root@spo-st ~]# python -c 'import crypt; import getpass; pw = getpass.getpass("New password: "); print(crypt.crypt(pw, crypt.mksalt(crypt.METHOD_SHA512)))'
New password:
$6$vMn8LgRVE5f0cAsK$Df1E9n0pBxUSVA6SbrSzVx.pasNnEjtY98fWlMBsLgHHCdrjoAydvOx/CFUChm5rc7VUboxxarS5gHiAVnAOR/


进入shadow文件,更改对应root部分并保存

添加新用户并提权

sudo adduser <新用户名>
sudo usermod -aG sudo <新用户名>

ubuntu组网

客户端操作

一定要知道自己的架构
两个frp版本要一致,架构可不同
root@hi3798mv100:/etc/apt# dpkg --print-architecture
armhf
root@hi3798mv100:/etc/apt# wget https://github.com/fatedier/frp/releases/download/v0.51.3/frp_0.51.3_linux_arm.tar.gz
tar -xzvf frp_0.51.3_linux_arm.tar.gz
cd frp_0.51.3_linux_arm
supermao@hi3798mv100:~/frp_0.51.3_linux_arm$ cat frps.ini
[common]
server_addr = 公网ip
server_port = 7000
token = cyb666
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

[hik]
type = tcp
local_ip = 192.168.0.118
local_port = 80
remote_port = 7899


./frpc -c ./frpc.ini

服务端操作


[root@spo-st frp_0.51.3_linux_amd64]# cat frps.ini
[common]
bind_port = 7000
token = cyb666

./frps -c ./frps.ini

客户端设置自启动

[Unit]
Description=FRP Client Service
After=network.target

[Service]
ExecStart=/home/supermao/frp_0.51.3_linux_arm/frpc -c /home/supermao/frp_0.51.3_linux_arm/frpc.ini
Restart=always

[Install]
WantedBy=multi-user.target

Stable Diffusion 是一个基于扩散模型的图像生成模型,可以用于生成高质量图像。其传统实现主要基于 PyTorch,最常用的开源实现是
CompVis/stable-diffusion
和 Hugging Face 的
diffusers
库。

如果你需要一个可以直接调用 Stable Diffusion 的接口,可以选择以下方法:


1.
使用 Hugging Face Diffusers

Hugging Face 的
diffusers
库提供了简单易用的接口,你可以通过以下代码调用:

from diffusers import StableDiffusionPipeline

# 加载模型(需要互联网)
pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4")
pipe.to("cuda")  # 如果有 GPU,请使用 CUDA

# 生成图片
prompt = "a fantasy landscape, epic mountains and sunset"
image = pipe(prompt).images[0]

# 保存图片
image.save("output.png")

如果没有 GPU,可以改为 CPU 模式:

pipe.to("cpu")

需要注意,运行此代码需要安装
diffusers
库和依赖:

pip install diffusers transformers accelerate torch


2.
直接使用开源 Stable Diffusion 代码

CompVis/stable-diffusion
是最初的官方实现。安装完成后,可以使用以下命令行方式生成图像:

  1. 克隆项目并安装依赖:
    git clone https://github.com/CompVis/stable-diffusion.git
    cd stable-diffusion
    conda env create -f environment.yaml
    conda activate ldm
    
  2. 下载模型权重(需要去 Hugging Face 授权)并放置在
    models/ldm/stable-diffusion-v1
    文件夹中。
  3. 运行图像生成脚本:
    python scripts/txt2img.py --prompt "a cat sitting on a table" --plms --n_samples 1 --n_iter 1 --H 512 --W 512
    


3.
调用 Stable Diffusion 的 Web API

如果不想在本地配置环境,可以使用提供 Stable Diffusion 的 API 服务。例如:

使用
Replicate

Replicate 是一个提供 Stable Diffusion 接口的平台,你可以通过简单的 API 调用生成图片。

以下是 Python 示例代码:

import replicate

# 设置 Replicate API Token
os.environ["REPLICATE_API_TOKEN"] = "your_replicate_api_token"

# 调用 API
model = replicate.models.get("stability-ai/stable-diffusion")
output = model.predict(prompt="a beautiful painting of a sunset over the ocean")

# 下载生成的图片
image_url = output[0]
print("Image URL:", image_url)


4.
其他 Stable Diffusion Web UI

可以考虑使用 Web UI,如
AUTOMATIC1111/stable-diffusion-webui
,它提供了功能丰富的图形界面,也支持通过 API 调用生成图像。

安装后可以运行以下 API 请求:

curl -X POST http://127.0.0.1:7860/sdapi/v1/txt2img \
-H "Content-Type: application/json" \
-d '{
    "prompt": "a dog playing in the park",
    "steps": 20
}'

这会返回生成图像的 Base64 编码,或者直接存储生成图片。




是的,基于开源 Stable Diffusion 代码,采样是生成图像的关键过程之一。Stable Diffusion 使用的是
扩散模型(Diffusion Model)
,其生成图像的过程包括两个主要阶段:

  1. 前向扩散过程(Forward Diffusion Process)
  2. 逆向扩散过程(Reverse Diffusion Process)

采样通常指的是逆向扩散过程,尤其是如何从随机噪声中逐步恢复清晰的图像。这一过程涉及到多个采样步骤,每一步都会减少图像中的噪声,直到最终生成清晰的图像。这个过程使用的是
采样算法
,例如 DDIM(Denoising Diffusion Implicit Models)和 PLMS(Pseudo Numerical Methods for Diffusion Models)等。


1.
采样过程概述

在 Stable Diffusion 中,采样的目标是从噪声(通常是高斯噪声)中反向推导出最终的图像。这个过程实际上是通过对扩散模型进行推理(inference)来完成的。它涉及以下步骤:

  • 输入:
    一个随机噪声图像(通常是高斯噪声)。
  • 模型:
    基于条件输入(如文本提示)和噪声图像的当前状态,模型预测下一个去噪步骤。
  • 采样步骤:
    反向扩散过程根据每一步的去噪结果来调整图像,直到图像趋近于清晰。

在采样过程中,模型通常会迭代多次,每次去噪一小部分。每次迭代的输出将作为下一步输入,直到最终图像产生。

2.
采样方法(Sampling Methods)

Stable Diffusion 中使用了几种不同的采样方法,其中最常见的包括
DDIM

PLMS
。以下是这些方法的简单介绍:

a.
DDIM (Denoising Diffusion Implicit Models)

DDIM 是一种非马尔可夫扩散模型,能够在更少的步骤中生成高质量的图像。它相较于传统的扩散模型在生成图像时更高效,并且能够控制生成的样式和细节。

b.
PLMS (Pseudo Numerical Methods for Diffusion Models)

PLMS 是另一种采样方法,它在生成过程中使用伪数值方法。PLMS 可以提供较为平滑的图像生成过程,减少一些常见的伪影问题。

c.
LMS (Laplacian Pyramid Sampling)

LMS 是一种增强型采样方法,通常用于提升图像质量并减少噪点,特别是在低分辨率下。


3.
开源 Stable Diffusion 中的采样实现

Stable Diffusion 的开源实现使用了 PyTorch 库,并通过不同的采样方法来生成图像。以下是典型的采样过程中的代码段:

a.
采样代码(以
diffusers
库为例)

在 Hugging Face 的
diffusers
库中,采样过程是在
StableDiffusionPipeline
中处理的。你可以通过设置
num_inference_steps
(推理步数)来控制采样过程中的迭代次数。

from diffusers import StableDiffusionPipeline

# 加载 Stable Diffusion 模型
pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4")
pipe.to("cuda")

# 设置提示词和采样参数
prompt = "a fantasy landscape, epic mountains and sunset"
num_inference_steps = 50  # 采样步数(迭代次数)
guidance_scale = 7.5  # 引导尺度,用于调整图像与提示词的匹配度

# 生成图像
image = pipe(prompt, num_inference_steps=num_inference_steps, guidance_scale=guidance_scale).images[0]

# 保存生成的图像
image.save("output.png")

b.
手动实现采样过程

在更底层的 Stable Diffusion 实现(例如在
CompVis/stable-diffusion
中),采样的过程通常是在
ldm.models.diffusion.ddim

ldm.models.diffusion.plms
文件中处理的。以下是一个简化的采样流程:

import torch
from torchvision import transforms
from ldm.models.diffusion.ddim import DDIMSampler

# 假设你已经加载了模型和权重
model = load_model_from_config('stable-diffusion-config.yaml')
sampler = DDIMSampler(model)

# 生成随机噪声
z = torch.randn([batch_size, channels, height, width]).cuda()

# 进行逆向扩散过程(采样过程)
for step in range(num_steps):
    # 计算噪声的去噪
    noise_pred = model(x_t, t)
    
    # 更新图像
    x_t = update_image(x_t, noise_pred)
    
    # 每一步都去噪
    if step % sampling_frequency == 0:
        save_intermediate_image(x_t)

# 最终生成的图像
final_image = transform_to_image(x_t)


4.
采样步骤和参数

  • 采样步数(num_inference_steps):
    控制反向扩散的迭代次数。步数越多,生成的图像质量越高,但计算成本也更大。通常在 25 到 50 步之间进行调整。

  • 引导尺度(guidance_scale):
    控制图像与提示词之间的相关性。较高的引导尺度会使生成的图像更加贴近提示词,但可能减少创意;较低的引导尺度则可能使生成结果更具创意,但与提示词的相关性较弱。


5.
采样方法的效果对比

  • DDIM
    方法可以在较少的步骤中得到质量不错的图像,非常适合高效生成。
  • PLMS
    在平滑图像的过程中表现更好,减少了图像的伪影,但可能需要更多的步骤来达到理想效果。


总结

在 Stable Diffusion 的开源实现中,采样过程是一个核心环节,直接影响图像生成的质量和效率。通过调整采样的步数、引导尺度以及选择不同的采样方法,可以在图像质量和生成速度之间找到平衡。你可以通过修改
num_inference_steps

guidance_scale
或选择不同的采样器(如 DDIM 或 PLMS)来调节生成过程。


根据你上传的文件结构,若要修改 Stable Diffusion 模型的行为,可以从以下文件和文件夹入手,具体取决于你想要修改的功能:


1. 修改核心模型逻辑

  • 路径:
    ldm/models/...


    • 如果需要直接修改模型的架构,例如调整模型结构、权重加载逻辑或生成逻辑,可以查看
      ldm
      文件夹下的代码。
    • 核心文件可能是与
      ldm
      相关的子模块(如
      autoencoder
      ,
      diffusion
      ,
      unet
      等)。

    例如:


    • ldm/models/autoencoder.py
      :处理潜在空间编码解码的逻辑。
    • ldm/models/diffusion/...
      :控制扩散过程的采样、反推和生成过程。
    • ldm/models/unet.py
      :UNet 模型的定义,这里是扩散模型的核心结构。


2. 修改推理和采样逻辑

  • 路径:
    scripts/txt2img.py

    • 如果想修改 Stable Diffusion 如何生成图片(例如更改采样器、分辨率等),应该修改
      scripts/txt2img.py
      文件。
    • 常见修改:
      • 替换采样方法(如 PLMS 改为 DDIM)。
      • 增加或修改输入参数(如
        --prompt
        的处理逻辑)。
      • 修改输出图片的路径、格式等。


3. 修改配置文件

  • 路径:
    configs/...

    • 配置文件通常包含模型参数、训练超参数等。如果需要更改模型的配置,可以查看
      configs
      文件夹下的文件。
    • 示例修改内容:
      • 调整网络层的配置。
      • 修改分辨率、潜在空间大小等参数。
      • 替换权重路径。


4. 添加或调整功能

  • 路径:
    main.py

    scripts/...

    • 如果想添加新的功能或命令行接口,可以修改
      main.py

      scripts
      文件夹下的文件。
    • 例如:
      • 增加一个新脚本
        txt2img_advanced.py
        ,实现自定义生成逻辑。

      • main.py
        中定义额外的入口点。


5. 模型权重加载逻辑

  • 路径:
    ldm/util.py

    scripts/txt2img.py

    • 如果需要更改权重加载逻辑(例如加载不同的模型权重或新增模型),可以查看
      ldm/util.py
      中的代码,特别是加载
      .ckpt
      权重相关的部分。


推荐修改顺序

  1. 明确你的需求
    :确定是要调整模型结构、生成逻辑,还是扩展功能。
  2. 阅读
    scripts/txt2img.py

    main.py

    :理解目前的生成流程,明确需要调整的部分。
  3. 定位到核心模块
    :深入
    ldm
    文件夹,分析
    autoencoder
    ,
    diffusion

    unet
    的实现。
  4. 测试和验证
    :逐步修改代码并验证效果,避免大范围修改后难以排查问题。


大型语言模型(LLMs)如GPT可以生成文本、回答问题并协助完成许多任务。然而,它们是被动的,这意味着它们仅根据已学到的模式对接收到的输入作出响应。LLMs无法自行决策;除此之外,它们无法规划或适应变化的环境。

主动式AI(代理式)的出现正是为了解决这一问题。与生成式AI LLMs不同,主动式AI(代理式)能够采取主动行动、设定目标并从自身的经验中学习。它是前瞻性的,能够随着时间的推移调整其行动,处理需要持续解决问题和决策的复杂任务。从被动到主动的这一转变,为许多行业的技术发展开辟了新的可能性。

在本系列文章中,我们将深入探讨主动式AI(代理式)与生成式AI的区别,研究它们如何影响行业及科技的未来。在这篇首篇文章中,我们将首先探索区分这两种AI的核心特点。

什么是主动式AI(代理式)

主动式AI(代理式)是指能够自主决策并采取行动以完成特定目标的AI系统。这类AI模型不仅仅是生成内容,还能与环境互动、响应变化并在最少的人类指导下完成任务。例如,具有主动式(代理式)能力的虚拟助理不仅可以提供信息,还可以安排约会、管理提醒或执行其他操作以帮助用户实现目标。同样,无人驾驶汽车也是主动式AI(代理式)的典范,因为它们能够实时决策,安全地在道路上导航并独立到达目的地。

什么是生成式AI

生成式AI是一种专注于创建新内容(如文本、图像、音乐甚至视频)的人工智能。它通过学习海量数据中的模式、风格或结构来生成基于所学内容的原创作品。例如,像ChatGPT这样的生成式AI能够根据问题生成独特的文本回复,而像DALL-E这样的图像生成模型则可以根据文本描述生成图像。简单来说,生成式AI就像一位数字艺术家或作家,通过所学内容创作出新的作品。

上图展示了主动式AI(代理式)如何通过包含“思考/研究”和“修订”等阶段的迭代循环工作流程运作。这种适应性过程涉及持续的自我评估和改进,使主动式AI(代理式)能够生成更高质量、优化的输出。通过采取多步测试和完善的方式,主动式AI(代理式)可以独立运作,从每个阶段中学习,并完成需要持续评估和调整的任务。

相比之下,生成式AI遵循一个简单的单步工作流程:从“开始”直接到“结束”。这意味着AI会立即给出响应,而不会重新审视或完善其输出。其过程是线性的,生成的结果通常只能满足初始提示的基本要求,但无法应对边缘情况或进行迭代测试。这也体现了生成式AI在处理更复杂或适应性任务时的局限性。

主动式AI(代理式)与生成式AI的特性

下文探讨主动式AI(代理式)与生成式AI的独特特性,重点突出了它们在智能、自主性和决策方式上的不同方法。

主动式AI(代理式)

• 自主性:主动式AI(代理式)可以独立行动,无需人类的持续输入。它能够自主决策并完成任务,例如一台无需人类控制的机器人,根据环境决定下一步的行动。

• 目标导向行为:主动式AI(代理式)带着明确的目标运作。它不会随机响应,而是积极朝着特定目标努力。例如,无人驾驶汽车的每一次转向或刹车都是为了安全地将你送达目的地。

• 适应与学习:主动式AI(代理式)会从其行动和经验中学习。如果遇到问题或失败,它会进行调整。例如,一个推荐电影的AI会根据你的偏好改进推荐内容。

• 复杂决策能力:主动式AI(代理式)不仅能做出简单的选择,还能评估多个选项并考虑后果。例如,控制股票交易算法的AI会分析海量数据、预测趋势并根据这些信息决定买卖股票。

• 环境感知:为了做出明智的选择,AI需要理解其环境。它通过传感器或数据来感知环境。例如,机器人使用摄像头“看到”障碍物,然后绕行。

生成式AI

• 有限自主性:生成式AI的自主性有限。它不能独立行动,需要人类输入来生成响应。它根据接收到的输入生成输出,但无法自主采取行动或在没有外部提示的情况下运作。

• 任务导向行为:生成式AI是任务导向的,但仅限于被动响应。它根据特定的提示或任务生成相关内容(如文本或图像),但不会追求长期目标或具有总体目标。每个任务都基于即时输入完成。

• 基本决策能力:生成式AI从事基本的决策。它根据学到的模式选择输出,但不会评估多个选项或考虑后果。例如,在生成文本时,它选择最可能的下一个词或短语,但不会做出复杂、分层的决策。

• 缺乏学习与适应能力:生成式AI不能实时学习或适应。一旦训练完成,它只能基于训练期间学到的模式运作,除非用更新的数据重新训练,否则不会改变或改进其性能。

• 缺乏环境感知:生成式AI没有环境感知能力。它处理的是数据(如文本或图像),但无法感知或解释物理环境。它无法理解周围的情况,只能对输入做出反应,缺乏外部意识。

案例分析:主动式AI(代理式)工作流程的实际应用

尽管生成式AI与主动式AI(代理式)的理论差异显而易见,但只有在实际应用中才能真正体现主动式AI(代理式)的潜力。

Andrew Ng 分享了一项研究,展示了主动式工作流程在编码任务中的优势。他的团队在HumanEval编码基准上测试了两种方法。任务是:“给定一组整数,返回所有偶数位置元素的和。”

在第一种方法中,采用零样本提示(zero-shot prompting),AI直接尝试解决问题。GPT-3.5的准确率为48%,而GPT-4则表现更好,达到67%。尽管如此,这些结果并不算特别出色。

快速术语:

• 零样本提示:不提供额外指导或分步提示,直接要求AI解决问题。

• 主动式工作流程:将任务分解为多个阶段(如理解、编码、测试和调试),让AI逐步迭代和改进。

然而,当团队应用主动式工作流程(将任务分解为理解问题、部分编码、测试和修正错误等步骤)时,GPT-3.5的表现甚至超越了GPT-4。Ng指出,GPT-4在采用主动式工作流程时也表现更强。这表明,通过分步方法,尤其是对于较旧的模型,可以利用主动式工作流程超越更先进的模型采用传统方法的结果。

结论

随着AI在我们的生活和工作中变得越来越重要,理解主动式AI(代理式)与生成式AI的差异显得至关重要。生成式AI在文本生成、响应提示生成文本或图像等任务中非常有用,但它受限于遵循指令而缺乏真正的自主性。而主动式AI(代理式)则更进一步——它能够设定目标、自主决策并适应变化的环境,能够在无需人类持续指导的情况下承担复杂任务。

通过使用主动式工作流程等方法,AI系统能够更加高效,通过迭代步骤不断提升性能,并从每个阶段中学习。这一转变为先进应用打开了大门,也让旧模型得以持续改进并保持相关性。在本系列的后续文章中,我们将深入探讨主动式AI(代理式)的实际运作方式及其重新塑造行业和推动创新的潜力。