OpenHarmony实现一次开发多端部署分布式新闻客户端页面

分布式新闻客户端(ArkTS)

介绍

本篇Codelab基于栅格布局、设备管理和多端协同,实现一次开发,多端部署的分布式新闻客户端页面。主要包含以下功能:

  1. 展示新闻列表以及左右滑动切换新闻Tab。
  2. 点击新闻展示新闻详情页。
  3. 点击新闻详情页底部的分享按钮,发现周边处在同一无线网络下的设备并进行可信认证连接。
  4. 可信认证后,再次点击分享按钮,选择已连接的设备进行跨设备启动UIAbility。

最终效果图如下:

相关概念

  • 栅格布局:一种通用的辅助定位工具,解决多尺寸多设备的动态布局问题。
  • 设备管理:模块提供分布式设备管理能力。
  • 跨设备启动UIAbility:多端上的不同UIAbility/ServiceExtensionAbility同时运行、或者交替运行实现完整的业务。
  • Tabs组件:通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。

相关权限

本篇Codelab使用了设备管理及跨设备实现多端协同能力,需要手动替换full-SDK,并在配置文件module.json5文件requestPermissions属性中添加如下权限:

  • 分布式设备认证组网权限:ohos.permission.ACCESS_SERVICE_DM。
  • 设备间的数据交换权限:ohos.permission.DISTRIBUTED_DATASYNC。

约束与限制

  1. 本篇Codelab部分能力依赖于系统API,需下载full-SDK并替换DevEco Studio自动下载的public-SDK。具体操作可参考指南《如何替换full-SDK》。
  2. 本篇Codelab使用的部分API仅系统应用可用,需要提升应用等级。具体可参考指南《访问控制授权申请指导》。

环境搭建

软件要求

  • DevEco Studio版本:DevEco Studio 4.0 Beta2。
  • OpenHarmony SDK版本:API version 10。

硬件要求

  • 开发板类型:润和RK3568开发板。
  • OpenHarmony系统:4.0 Beta1。

环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. 获取OpenHarmony系统版本:标准系统解决方案(二进制)。以4.0 Beta1版本为例:

  2. 搭建烧录环境。
    1. 完成DevEco Device Tool的安装
    2. 完成RK3568开发板的烧录
  3. 搭建开发环境。
    1. 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
    2. 开发环境配置完成后,请参考使用工程向导创建工程(模板选择“Empty Ability”)。
    3. 工程创建完成后,选择使用真机进行调测。

代码结构解读

本篇Codelab只对核心代码进行讲解。

├──entry/src/main/ets                   // 代码区
│  ├──common
│  │  ├──constants
│  │  │  └──CommonConstants.ets         // 常量类
│  │  └──utils
│  │     └──Logger.ets                  // 日志工具类
│  ├──entryability
│  │  └──EntryAbility.ets               // 程序入口类
│  ├──model
│  │  └──RemoteDeviceModel.ets          // 设备管理类
│  ├──pages
│  │  ├──Index.ets                      // 新闻列表页
│  │  └──NewsDetail.ets                 // 新闻详情页
│  ├──view
│  │  ├──DetailFooter.ets               // 详情页页脚
│  │  ├──DetailHeadContent.ets          // 新闻详情
│  │  ├──DeviceListDialog.ets           // 设备列表弹窗
│  │  ├──NewsList.ets                   // 新闻列表
│  │  └──NewsTab.ets                    // 新闻页签
│  └──viewmodel
│     └──NewsDataModel.ets              // 新闻数据处理
└──entry/src/main/resources             // 资源文件目录

构建新闻列表页

新闻列表页由页签区域和新闻列表区域组成,页签区域为自定义布局TabBuilder,新闻列表区域为Tabs组件嵌套List组件,并适配不同尺寸设备对应的栅格。新闻列表页能够左右滑动或点击页签切换新闻Tab,并设置点击新闻跳转至新闻详情页。

// NewsTab.ets
@Component
export default struct NewsTab {
  @State currentIndex: number = 0;
  @State currentBreakpoint: string = CommonConstants.BREAKPOINT_SM;
  private newsItems: NewsData[] = [];

  // 自定义页签栏
  @Builder TabBuilder(title: Resource, index: number) {
    Row() {
      Text(title)
        .fontSize(this.currentIndex === index ? $r('app.float.lager_font_size') : $r('app.float.middle_font_size'))
        .fontWeight(this.currentIndex === index ? CommonConstants.FONT_WEIGHT_500 : FontWeight.Normal)
        .fontColor(this.currentIndex === index ? $r('app.color.tab_font_select') : $r('app.color.font_color_gray'))
    }
    .layoutWeight(1)
    .margin({
      right: $r('app.float.news_tab_margin_right'),
      left: (this.currentBreakpoint === CommonConstants.BREAKPOINT_SM && index === 0) ?
        $r('app.float.news_tab_margin_left') : 0
    })
    .height(this.currentIndex === index ? $r('app.float.news_tab_current_height') : $r('app.float.news_tab_height'))
  }

  build() {
    ...
    Tabs() {
      ForEach(CommonConstants.ALL_TITLE, (title: string, index: number) => {
        TabContent() {
          // 新闻内容列表
          NewsList({ newsItems: NewsDataModel.getNewsByType(this.newsItems, title) })
        }
        .tabBar(this.TabBuilder(NewsDataModel.getTypeByStr(title), index))
      }, (title: string, index: number) => index + JSON.stringify(title))
    }
    .barHeight($r('app.float.news_tab_bar_height'))
    .barWidth(CommonConstants.FULL_COMPONENT)
    .barMode(this.currentBreakpoint === CommonConstants.BREAKPOINT_SM ? BarMode.Scrollable : BarMode.Fixed)
    .onChange((index: number) => {
      this.currentIndex = index;
    })
    ...
  }
}

// NewsList.ets
@Component
export default struct NewsList {
  private newsItems: NewsData[] = [];

  build() {
    List() {
      ForEach(this.newsItems, (item: NewsData, index: number) => {
        ListItem() {
          // 栅格布局
          GridRow({
            columns: {
              sm: CommonConstants.FOUR_COLUMN,
              md: CommonConstants.EIGHT_COLUMN,
              lg: CommonConstants.TWELVE_COLUMN
            },
            breakpoints: {
              value: [
                CommonConstants.SMALL_DEVICE_TYPE,
                CommonConstants.MIDDLE_DEVICE_TYPE,
                CommonConstants.LARGE_DEVICE_TYPE
              ]
            },
            gutter: { x: $r('app.float.grid_row_gutter') }
          }) {
            GridCol({
              span: {
                sm: CommonConstants.FOUR_COLUMN,
                md: CommonConstants.EIGHT_COLUMN,
                lg: CommonConstants.EIGHT_COLUMN
              },
              offset: {
                sm: CommonConstants.ZERO_COLUMN,
                md: CommonConstants.ZERO_COLUMN,
                lg: CommonConstants.TWO_COLUMN
              }
            }) {
              NewsItem({ newsItem: item, isLast: index === this.newsItems.length - 1 })
            }
          }
        }
      }, (item: NewsData, index: number) => index + JSON.stringify(item))
    }
    .height(CommonConstants.FULL_COMPONENT)
  }
}

构建新闻详情页

新闻详情页

新闻详情页由新闻内容区域和页脚区域组成,其中新闻内容区域为Scroll组件嵌套栅格组件展示新闻详情,页脚区域为栅格布局,包含TextInput组件和三个按钮图标。

// DetailHeadContent.ets
build() {
  Column() {
    ...
    // 可滚动的容器组件
    Scroll() {
      // 栅格布局
      GridRow({
        columns: {
          sm: CommonConstants.FOUR_COLUMN,
          md: CommonConstants.EIGHT_COLUMN,
          lg: CommonConstants.TWELVE_COLUMN
        },
        breakpoints: {
          value: [
          CommonConstants.SMALL_DEVICE_TYPE,
          CommonConstants.MIDDLE_DEVICE_TYPE,
          CommonConstants.LARGE_DEVICE_TYPE
          ]
        },
        gutter: { x: $r('app.float.grid_row_gutter') }
      }) {
        GridCol({
          span: {
            sm: CommonConstants.FOUR_COLUMN,
            md: CommonConstants.EIGHT_COLUMN,
            lg: CommonConstants.EIGHT_COLUMN
          },
          offset: {
            sm: CommonConstants.ZERO_COLUMN,
            md: CommonConstants.ZERO_COLUMN,
            lg: CommonConstants.TWO_COLUMN
          }
        }) {
          ...
        }
        ...
      }
    }
    .padding({
      bottom: $r('app.float.news_detail_padding_bottom')
    })
    .scrollBar(BarState.Off)
  }
  .margin({
    left: $r('app.float.news_detail_margin'),
    right: $r('app.float.news_detail_margin')
  })
  .height(CommonConstants.FULL_COMPONENT)
  .alignItems(HorizontalAlign.Start)
}

// DetailFooter.ets
build() {
  Column() {
    // 分割线
    Divider()
      .color($r('app.color.detail_divider_color'))
      .width(CommonConstants.FULL_COMPONENT)

    // 栅格布局
    GridRow({
      columns: {
        sm: CommonConstants.FOUR_COLUMN,
        md: CommonConstants.EIGHT_COLUMN,
        lg: CommonConstants.TWELVE_COLUMN
      },
      breakpoints: {
        value: [
        CommonConstants.SMALL_DEVICE_TYPE,
        CommonConstants.MIDDLE_DEVICE_TYPE,
        CommonConstants.LARGE_DEVICE_TYPE
        ]
      },
      gutter: { x: $r('app.float.grid_row_gutter') }
    }) {
      GridCol({
        span: {
          sm: CommonConstants.FOUR_COLUMN,
          md: CommonConstants.EIGHT_COLUMN,
          lg: CommonConstants.EIGHT_COLUMN
        },
        offset: {
          sm: CommonConstants.ZERO_COLUMN,
          md: CommonConstants.ZERO_COLUMN,
          lg: CommonConstants.TWO_COLUMN
        }
      }) {
        ...
      }
      .margin({
        left: this.currentBreakpoint === CommonConstants.BREAKPOINT_SM ? $r('app.float.footer_margin_sm') :
          $r('app.float.footer_margin_other'),
        right: this.currentBreakpoint === CommonConstants.BREAKPOINT_SM ? $r('app.float.footer_margin_sm') :
          $r('app.float.footer_margin_other')
      })
    }
    .backgroundColor($r('app.color.bg_color_gray'))
    .height($r('app.float.footer_height'))
    .width(CommonConstants.FULL_COMPONENT)
    .onBreakpointChange((breakpoints) => {
      ...
    })
  }
}

分享按钮弹窗

页脚点击分享按钮,弹出自定义弹窗DeviceListDialog,用于多端协同拉起应用。DeviceListDialog由两个标题栏和两个List组件构成,其中List组件使用ForEach循环渲染设备数据。

// DeviceListDialog.ets
build() {
  Column() {
    Row() {
      ...
    }
    .height($r('app.float.choose_device_row_height'))
    .width(CommonConstants.FULL_COMPONENT)
    .padding({
      left: $r('app.float.dialog_padding'),
      right: $r('app.float.dialog_padding')
    })

    // 信任设备列表
    List() {
      ForEach(this.trustedDeviceList, (item: deviceManager.DeviceInfo, index: number) => {
        ListItem() {
          ...
        }
      }, (item: deviceManager.DeviceInfo) => JSON.stringify(item.deviceId))
    }

    Row() {
      ...
    }
    .height($r('app.float.choose_device_row_height'))
    .width(CommonConstants.FULL_COMPONENT)
    .padding({
      left: $r('app.float.dialog_padding'),
      right: $r('app.float.dialog_padding')
    })

    // 发现设备列表
    List() {
      ForEach(this.discoverDeviceList, (item: deviceManager.DeviceInfo, index: number) => {
        ListItem() {
          ...
        }
      }, (item: deviceManager.DeviceInfo) => JSON.stringify(item.deviceId))
    }

    Row() {
      ...
    }
    .height($r('app.float.dialog_button_row_height'))
    .padding({
      top: $r('app.float.dialog_button_padding_top'),
      bottom: $r('app.float.dialog_button_padding_bottom'),
      left: $r('app.float.dialog_padding'),
      right: $r('app.float.dialog_padding')
    })
    .width(CommonConstants.FULL_COMPONENT)
  }
  .borderRadius($r('app.float.dialog_border_radius'))
  .backgroundColor($r('app.color.device_dialog_background'))
  .width(CommonConstants.FULL_COMPONENT)
}

多端协同拉起应用

创建设备管理器

应用创建时创建一个设备管理器实例,注册设备状态监听和获取信任的设备列表。其中deviceManager类需使用full-SDK。

// EntryAbility.ets
onCreate(want: Want) {
  ...
  // 创建设备管理器
  RemoteDeviceModel.createDeviceManager(this.context);
}

// RemoteDeviceModel.ets
async createDeviceManager(context: common.UIAbilityContext): Promise<void> {
  if (this.deviceManager !== undefined) {
    return;
  }
  await new Promise((resolve: (value: Object | PromiseLike<Object>) => void, reject:
    ((reason?: RejectError) => void)) => {
    deviceManager.createDeviceManager(context.abilityInfo.bundleName, (err, value) => {
      if (err) {
        reject(err);
        logger.error('createDeviceManager failed.');
        return;
      }
      this.deviceManager = value;
      // 注册设备状态监听
      this.registerDeviceStateListener();
      // 获取信任设备列表
      this.getTrustedDeviceList();
      resolve(value);
    })
  })
}

发现设备

用户点击新闻详情页底部的分享按钮,调用startDeviceDiscovery()方法,发现周边处在同一无线网络下的设备并添加设备至已发现的设备列表。

// RemoteDeviceModel.ets
startDeviceDiscovery(): void {
  if (this.deviceManager === undefined) {
    logger.error('deviceManager has not initialized');
    this.showToast($r('app.string.no_device_manager'));
    return;
  }
  this.deviceManager.on('deviceFound', (data) => {
    if (data === null) {
      return;
    }
    // 监听设备发现
    this.deviceFound(data);
  })
  this.deviceManager.on('discoverFail', (data) => {
    logger.error(`discoverFail data = ${JSON.stringify(data)}`);
  })
  this.deviceManager.on('serviceDie', () => {
    logger.error('serviceDie');
  })

  let info: deviceManager.SubscribeInfo = {
    subscribeId: SUBSCRIBE_ID,
    mode: CommonConstants.INFO_MODE,
    medium: 0,
    freq: CommonConstants.INFO_FREQ,
    isSameAccount: false,
    isWakeRemote: true,
    capability: 0
  };
  // 添加设备至发现列表
  this.discoverList = [];
  AppStorage.setOrCreate(CommonConstants.DISCOVER_DEVICE_LIST, this.discoverList);

  try {
    this.deviceManager.startDeviceDiscovery(info);
  } catch (err) {
    logger.error(`startDeviceDiscovery failed error = ${JSON.stringify(err)}`);
  }
}

进行可信认证连接

在已发现的设备列表中选择设备,调用authenticateDevice()方法进行可信认证,输入PIN码,连接设备,将设备改为信任状态,添加至已信任设备列表。

// RemoteDeviceModel.ets
authenticateDevice(device: deviceManager.DeviceInfo, context: common.UIAbilityContext): void {
  if (this.deviceManager === undefined) {
    logger.error('deviceManager has not initialized');
    this.showToast($r('app.string.no_device_manager'));
    return;
  }

  for (let i: number = 0; i < this.discoverList.length; i++) {
    if (this.discoverList[i].deviceId !== device.deviceId) {
      continue;
    }
    let extraInfo: AuthExtraInfoInterface = {
      targetPkgName: context.abilityInfo.bundleName,
      appName: context.applicationInfo.name,
      appDescription: context.applicationInfo.description,
      business: CommonConstants.ZERO
    };
    let authParam: deviceManager.AuthParam = {
      'authType': CommonConstants.ONE,
      'extraInfo': extraInfo
    };
    try {
      // 可信认证
      this.deviceManager.authenticateDevice(device, authParam, (err) => {
        if (err) {
          logger.error(`authenticateDevice error. Code is ${err.code}, message is ${err.message}`);
          return;
        }
      })
    } catch (err) {
      logger.error(`authenticateDevice failed error = ${JSON.stringify(err)}`);
    }
  }
}

跨设备启动UIAbility

可信认证后,用户再次点击分享按钮,选择已信任设备列表中的设备,调用startAbilityContinuation()方法进行拉起应用,在另一设备中触发aboutToAppear()方法渲染当前的新闻详情页,实现跨设备启动UIAbility。

// DeviceListDialog.ets
function startAbilityContinuation(deviceId: string, newsId: string, context: common.UIAbilityContext): void {
  let want: Want = {
    deviceId: deviceId,
    bundleName: context.abilityInfo.bundleName,
    abilityName: CommonConstants.ABILITY_NAME,
    parameters: {
      newsId: newsId
    }
  };
  // 拉起应用
  context.startAbility(want).catch((err: Error) => {
    Logger.error(`startAbilityContinuation failed error = ${JSON.stringify(err)}`);
    prompt.showToast({
      message: $r('app.string.start_ability_continuation_error')
    });
  })
}

// NewsDetail.ets
aboutToAppear() {
  let newsId: string | undefined = AppStorage.get<string>('wantNewsId');
  if (newsId === undefined) {
    this.newsData = (router.getParams() as Record<string, NewsData>)['newsItem'];
    return;
  }
  // 读取跨设备传递的参数信息
  this.newsData = this.newsItems.filter((item: NewsData) => (item.newsId === newsId))[0];
}

总结

您已经完成了本次Codelab的学习,并了解到以下知识点:

  1. 构建分布式新闻客户端页面。
  2. 实现应用的一次开发,多端部署。
  3. 使用跨设备启动UIAbility拉起应用。

为了帮助大家更深入有效的学习到鸿蒙开发知识点,小编特意给大家准备了一份全套最新版的HarmonyOS NEXT学习资源,获取完整版方式请点击→HarmonyOS教学视频

HarmonyOS教学视频

鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程

鸿蒙生态应用开发白皮书V2.0PDF:

获取完整版白皮书方式请点击→《鸿蒙生态应用开发白皮书V2.0PDF

在这里插入图片描述

鸿蒙 (Harmony OS)开发学习手册

一、入门必看

  1. 应用开发导读(ArkTS)
  2. .……

在这里插入图片描述


二、HarmonyOS 概念

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

在这里插入图片描述

三、如何快速入门?《鸿蒙基础入门学习指南》

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. .……

在这里插入图片描述


四、开发基础知识

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. .……

在这里插入图片描述


五、基于ArkTS 开发

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 7.网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. .……

在这里插入图片描述


更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙 (Harmony OS)开发学习手册

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/479788.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

产生死锁的四大条件

死锁 由于两个或两个以上的线程相互争夺对方的资源&#xff0c;而同时不释放自己的资源&#xff0c;导致所有线程同时被阻塞 产生死锁的四大条件 互斥条件&#xff1a;一个资源在同一时刻只能由一个运算单元&#xff08;进程、线程或协程&#xff09;占用&#xff08;排它性&…

停车场引导与道闸系统工程解析

停车场引导和道闸系统工程是一个综合性的智能车辆管理系统&#xff0c;它结合了现代电子信息技术&#xff0c;旨在实现安全、高效、自动化的停车管理。以下是该系统的主要组成部分及其功能&#xff1a; 1. 车牌识别技术&#xff1a;这是现代停车场管理的核心&#xff0c;能够自…

华清远见作业第五十三天——ARM(第七天)

代码 key_inc.h #ifndef __KEY_INC_H__ #define __KEY_INC_H__ #include "stm32mp1xx_gic.h" #include "stm32mp1xx_exti.h" #include "stm32mp1xx_rcc.h" #include "stm32mp1xx_gpio.h"void key1_it_config();void key2_it_config(…

C++概述

目录 一、C关键字&#xff08;63个&#xff09; 二、C几个关键点&#xff1a; 三、C语言缺陷一&#xff1a;命名冲突 四、C新概念&#xff1a;命名空间&#xff08;namespace&#xff09; 五、命名空间的嵌套&#xff1a; 六、展开命名空间&#xff1a;&#xff08;using …

【收藏】什么是API测试?这是我见过的最全的测试指南!

在最近的部署中&#xff0c;当我被问到“什么是API测试&#xff1f;”时&#xff0c;我正与客户一起制定API测试策略。那时我突然意识到&#xff0c;要描述API测试居然是一件如此具有挑战性的事情&#xff0c;即使你如实地描述了它&#xff0c;也往往听起来很无聊和复杂。 好吧…

FloodFill算法——岛屿数量

文章目录 题目解析算法解析代码解析 题目解析 岛屿数量 题目依旧是熟悉的配方&#xff0c;熟悉的味道&#xff0c;还是那个0还是那个1还是那个二维矩阵&#xff0c;这时候BFS和DFS闻着味就来了&#xff0c;我们来看一下这个题目&#xff0c;这个题目也很容易理解如下图有一个…

【No.14】蓝桥杯贪心法|最少硬币问题|活动安排问题(4)|翻硬币|快乐司机|防御力|答疑(C++)

算法优点 容易理解&#xff1a;生活常见 操作简单&#xff1a;在每一步都选局部最优 效率高&#xff1a;复杂度常常是O(1)的 算法缺点 局部最优不一定是全局最优 贪心算法&#xff08;Greedy algorithm&#xff09;&#xff0c;又称贪婪算法。是一种在每一步选择中都采取在…

教你在PC客户端中集成镭速高速传输插件

企业一直以来对文件传输的速度和安全性都有着严苛的要求&#xff0c;传统的FTP/HTTP传输方式因速度慢、易受网络延迟影响、数据包丢失等问题而不再适应现代企业的需求。镭速高速传输插件应运而生&#xff0c;为企业提供了一个快速、安全的文件传输新选择。本文将详细介绍如何在…

代码随想录算法训练营第day54|392.判断子序列 、 115.不同的子序列

目录 392.判断子序列 115.不同的子序列 392.判断子序列 力扣题目链接(opens new window) 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字…

【WEEK4】 【DAY3】整合SSM框架之功能实现—修改、删除数据【中文版】

2024.3.20 Wednesday 接上文【WEEK4】 【DAY2】整合SSM框架之功能实现—总览、添加数据【中文版】 目录 7.6.修改功能7.6.1.修改BookController.java7.6.2.修改allBook.jsp7.6.3.新建updateBook.jsp7.6.4.修改MyBatis-config.xml7.6.5.运行 7.7.删除功能7.7.1.修改BookContro…

unicloud快速上手,unicloud项目创建以及项目创建注意事项

uniCloud快速上手 本项目地址https://gitee.com/qayrup/unicloud-demo 创建unicloud项目 新建一个uni项目,并选择启用unicloud,选择阿里云或腾讯云 阿里云和支付宝云都支持一个月免费的云,如果只想体验啥的,可以选择这两个, 但是需要注意,支付宝云需要配置跨域,否则很多云函…

ModuleNotFoundError: No module named ‘Crypto‘的解决办法

Crypto模块是什么 在Python中&#xff0c;Crypto模块&#xff08;有时也被称为pycrypto&#xff09;是一个强大的加密库&#xff0c;它提供了各种加密算法的实现&#xff0c;包括AES、DES、RSA等。 在Python 3中&#xff0c;由于pycrypto库与新版本的Python3不兼容&#xff0…

DES加密原理及python脚本

一、加密 1、秘钥处理 ​ DES算法会先对64位密钥进行处理生成48位子密钥后再参与到算法的轮操作中&#xff0c;在每一轮的迭代过程中&#xff0c;使用不同的子密钥。其中的处理包括置换选择、循环左移、压缩置换。 1.1 置换选择 DES秘钥有64位&#xff0c;其中每8位有一个校…

[HackMyVM]靶场 XMAS

kali:192.168.56.104 靶机:192.168.56.126 注意在/etc/hosts 添加 192.168.56.126 christmas.hmv # cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 kali2 192.168.223.131 dc-2 192.168.223.134 wordy 192.168.56.105 midn…

【嵌入式开发 Linux 常用命令系列 4.3 -- git add 时单独排除某个目录或者文件】

文章目录 git add 时单独排除某个目录或者文件使用 .gitignore 文件使用命令行排除文件或目录 git add 时单独排除某个目录或者文件 在使用 git add 命令时&#xff0c;如果你想要排除特定的目录或文件&#xff0c;可以使用 .gitignore 文件或使用路径规范来指定不想添加的文件…

智能T0算法交易促进年化收益

T0交易越来越得到普及&#xff0c;越来越多的人在关注T0交易。按照交易主体来看&#xff0c;一种是人工T0交易&#xff0c;另一种是自动化智能T0算法交易。人工T0交易会受制于操作员的计算能力、反应速度以及主观判断等因素的影响&#xff0c;稳定性不如智能自动化T0算法交易。…

搭建自己的博客-拾壹博客

写在前面 唠叨两句 作为一个技术开发人员&#xff0c;没有一个自己的博客&#xff0c;人生注定缺少点什么东西&#xff0c;是不是&#xff1f;最近研究了一些博客搭建&#xff0c;本文是使用开源项目”拾壹博客“进行搭建。 推荐等级 所需技术难度&#xff1a;4星 后续自定义…

GPU云服务器与自建GPU服务器的对比

GPU云服务器是一种基于GPU的计算服务&#xff0c;广泛应用于深度学习、图形图像处理和科学计算等领域。其快速、稳定、灵活的特点使其备受青睐。与标准的CVM云服务器一样&#xff0c;GPU云服务器提供方便快捷的管理方式&#xff0c;通过其强大的计算性能&#xff0c;能够快速处…

直播行业网络安全建设

一、引言 直播行业近年来蓬勃发展&#xff0c;吸引了大量用户和资本的关注。然而&#xff0c;随着行业的壮大&#xff0c;网络安全问题也日益凸显。构建一个安全、稳定的直播行业网络对于保障用户权益、维护行业秩序具有重要意义。本文将详细探讨直播行业安全网络的构建与保障…

zookeeper分布式锁原理剖析

在ZooKeeper的CLI中&#xff0c;create命令用于在指定路径上创建一个新的节点。以下是create命令的参数解释&#xff1a; -s&#xff1a;顺序节点标志。如果指定了该选项&#xff0c;则创建的节点将是顺序节点。顺序节点的名称将以“path”后跟一个连字符和递增的数字序列结尾…