HarmonyOS Next开发学习手册——代码混淆

news2024/9/21 12:40:08

代码混淆简介

针对工程源码的混淆可以降低工程被破解攻击的风险,缩短代码的类与成员的名称,减小应用的大小。

DevEco Studio提供代码混淆的能力并默认开启,API 10及以上版本的Stage模型、 编译模式为release 时自动进行代码混淆。

使用约束

  • 仅支持Stage工程
  • 编译模式为release
  • 模块及模块依赖的HAR均未配置关闭混淆的规则-disable-obfuscation

混淆范围

在应用工程中,代码混淆支持以下格式文件混淆,混淆后的缓存文件保存在模块目录下的build/[…]/release目录下。

  • ArkTS文件
  • TS文件
  • JS文件

开启代码混淆

代码混淆已经被集成了到SDK中,可以在DevEco Studio中很方便地使用。

代码混淆目前只提供名称混淆的能力(因为其它混淆能力会劣化性能)。 开启代码混淆可以混淆以下名称:

  • 参数名和局部变量名
  • 顶层作用域的名称
  • 属性名称

代码混淆默认使能对参数名和局部变量名的混淆。顶层作用域名称和属性名称的混淆是默认关闭的,因为默认打开可能会导致运行时错误。这些混淆功能通过混淆选项来开启它们。

创建一个新工程的时候,配置文件build-profile.json5中会自动生成以下内容:

"arkOptions": {
  "obfuscation": {
    "ruleOptions": {
      "enable": true,
      "files": ["./obfuscation-rules.txt"],
    }
  }
}

创建一个新的library的时候,还会额外生成consumerFiles属性:

"arkOptions": {
  "obfuscation": {
    "ruleOptions": {
      "enable": true,
      "files": ["./obfuscation-rules.txt"],
    }
    "consumerFiles": ["./consumer-rules.txt"]
  }
}

混淆功能默认开启,若被关闭希望重新开启混淆需要满足条件: 属性ruleOptions.enable的值为true。

属性ruleOptions.files中指定的混淆配置文件会在构建HAP、HSP或HAR的时候生效。

属性consumerFiles中指定的混淆配置文件会在构建依赖这个library的模块时生效。 这些混淆配置文件的内容还会被合并到HAR包中的obfuscation.txt文件。

当构建HAP、HSP和HAR的时候,最终的混淆规则是当前构建模块的ruleOptions.files属性,依赖library的consumerFiles属性,以及依赖HAR包中的obfuscation.txt文件的合并。

如果构建的是HAR,HAR包中的obfuscation.txt是自身的consumerFiles属性, 依赖library的consumerFiles属性,以及依赖HAR包中的obfuscation.txt文件的合并。构建HAP、HSP不会生成obfuscation.txt。详细合并的策略可以查看混淆规则合并策略。

混淆规则配置文件

在创建工程或library的时候,DevEco Studio会自动生成obfuscation-rules.txt和consumer-rules.txt文件,

但是它们默认不会包含任何混淆规则。混淆规则可以写到这些文件中,或者其它自定义文件,

然后将文件路径放到ruleOptions.files和consumerFiles中,如下面的例子所示。

"buildOption": {
  "arkOptions": {
    "obfuscation": {
      "ruleOptions": {
        "enable": true,
        "files": ["./obfuscation-rules.txt", "./myrules.txt"], //myrules.txt放入配置文件build-profile.json5同级目录下
      }
      "consumerFiles": ["./consumer-rules.txt", "./my-consumer-rules.txt"]
    }
  }
}

配置混淆规则

混淆规则分为两种类型,一种是 混淆选项 ,一种是 保留选项 ;前者是提供顶层作用域名称、属性名称、文件名称等多种混淆功能配置开关,后者是提供各种混淆功能的白名单配置能力。

混淆选项

-disable-obfuscation

关闭所有混淆。如果使用这个选项,那么构建出来的HAP、HSP或HAR将不会被混淆。

-enable-property-obfuscation

开启属性混淆。 如果使用这个选项,那么所有的属性名都会被混淆,除了下面场景:

  • 被import/export直接导入或导出的类、对象的属性名不会被混淆。例如下面例子中的属性名data不会被混淆。
export class MyClass {
   data: string;
}
  • ArkUI组件中的属性名不会被混淆。例如下面例子中的message和data不会被混淆。
@Component struct MyExample {
    @State message: string = "hello";
    data: number[] = [];
    ...
}
  • 被 保留选项 指定的属性名不会被混淆。

  • SDK API列表中的属性名不会被混淆。SDK API列表是构建时从SDK中自动提取出来的一个名称列表,其缓存文件为systemApiCache.json,路径为工程目录下build/cache/{…}/release/obfuscation中

  • 在Native API场景中,so库对应的d.ts文件中声明的API不会被混淆。

  • 字符串字面量属性名不会被混淆。例如下面例子中的"name"和"age"不会被混淆。

let person = {"name": "abc"};
person["age"] = 22;

如果想混淆字符串字面量属性名,需要在该选项的基础上再使用-enable-string-property-obfuscation选项。例如

-enable-property-obfuscation
-enable-string-property-obfuscation

注意

1. 如果代码里面有字符串属性名包含特殊字符(除了a-z, A-Z, 0-9, _之外的字符),例如let obj = {“\n”: 123, “”: 4, " ": 5},建议不要开启-enable-string-property-obfuscation选项,因为可能无法通过保留选项来指定保留这些名字。

2. SDK API的属性白名单中不包含声明文件中使用的字符串常量值,例如示例中的字符串’ohos.want.action.home’未包含在属性白名单中

// SDK API文件@ohos.app.ability.wantConstant片段:
export enum Params {
  ACTION_HOME = 'ohos.want.action.home'
}
// 开发者源码示例:
let params = obj['ohos.want.action.home'];

因此在开启了-enable-string-property-obfuscation选项时,如果想保留代码中使用的SDK API字符串常量的属性不被混淆,例如obj[‘ohos.want.action.home’], 那么需要使用keep选项保留。

-enable-toplevel-obfuscation

开启顶层作用域名称混淆。如果使用这个选项,那么所有的顶层作用域的名称都会被混淆,除了下面场景:

  • 被import/export的名称不会被混淆。
  • 当前文件找不到声明的名称不会被混淆。
  • 被 保留选项 指定的顶层作用域名称不会被混淆。
  • SDK API列表中的顶层作用域名称不会被混淆。

-enable-filename-obfuscation

开启文件/文件夹名称混淆。如果使用这个选项,那么所有的文件/文件夹名称都会被混淆,除了下面场景:

  • oh-package.json5文件中’main’、'types’字段配置的文件/文件夹名称不会被混淆。
  • 模块内module.json5文件中’srcEntry’字段配置的文件/文件夹名称不会被混淆。
  • 被 -keep-file-name 指定的文件/文件夹名称不会被混淆。
  • 非ECMAScript模块引用方式(ECMAScript模块示例:import {foo} from ‘./filename’)
  • 非路径引用方式,例如例子中的json5不会被混淆 import module from ‘json5’

注意

由于系统会在应用运行时加载某些指定的文件,针对这类文件,开发者需要手动在[-keep-file-name]选项中配置相应的白名单,防止指定文件被混淆,导致运行失败。

上述需要手动配置白名单的情况,包括但不限于以下场景:

  • 当模块中包含Ability组件时。用户需要将src/main/module.json5中,'abilities’字段下所有’srcEntry’对应的路径配置到白名单中。
  • 当模块中包含Worker多线程服务时,用户需要将build-profiles.json5中,‘buildOption’-‘sourceOption’-'workers’字段下所有的路径配置到白名单中。

-enable-export-obfuscation

开启直接导入或导出的类或对象的名称和属性名混淆。如果使用这个选项,那么模块中的直接导入或导出的名称都会被混淆,除了下面场景:

  • 远程HAR(真实路径在oh_modules中的包)中导出的类或对象的名称和属性名不会被混淆。
  • 被 保留选项 指定的名称与属性名不会被混淆。
  • SDK API列表中的名称不会被混淆。

注意

  1. 混淆导入或导出的类中属性名称需要同时开启-enable-property-obfuscation与-enable-export-obfuscation选项。

  2. 编译HSP时,如果开启-enable-export-obfuscation选项,需要在模块中的混淆配置文件obfuscation-rules.txt中保留对外暴露的接口。

  3. HAP/HSP/HAR依赖HSP场景下,编译时如果开启-enable-export-obfuscation选项,需要在模块中的混淆配置文件obfuscation-rules.txt中保留HSP导入的接口。

// 代码示例(HSP中入口文件Index.ets):
export { add, customApiName } from './src/main/ets/utils/Calc'

// 保留接口名称配置示例:
// HSP以及依赖此HSP的模块中obfuscation-rules.txt文件配置: 
keep-global-name
add
customApiName

-compact

去除不必要的空格符和所有的换行符。如果使用这个选项,那么所有代码会被压缩到一行。

注意

release模式构建的应用栈信息仅包含代码行号,不包含列号,因此compact功能开启后无法依据报错栈中的行号定位到源码具体位置。

-remove-log

删除以下场景中对 console.*语句的调用,要求console.*语句返回值未被调用。

  1. 文件顶层的调用
  2. 代码块Block中的调用
  3. 模块Module中的调用
  4. switch语句中的调用

-print-namecache filepath

将名称缓存保存到指定的文件路径。名称缓存包含名称混淆前后的映射。

注意

每次全量构建工程时都会生成新的namecache.json文件,因此您每次发布新版本时都要注意保存一个该文件的副本。

-apply-namecache filepath

复用指定的名称缓存文件。名字将会被混淆成缓存映射对应的名字,如果没有对应,将会被混淆成新的随机段名字。

该选项应该在增量编译场景中被使用。

默认情况下,DevEco Studio会在临时的缓存目录中保存缓存文件,并且在增量编译场景中自动应用该缓存文件。

缓存目录:build/cache/{…}/release/obfuscation

-remove-comments

删除文件中的所有注释,包括单行、多行,及JsDoc注释。以下场景除外:

声明文件中,在-keep-comments中配置的类、方法、struct、枚举等名称上方的JsDoc注释。

注意

编译生成的源码文件中的注释默认会被全部删除,不支持配置保留。

保留选项

-keep-property-name [,identifiers,…]

指定想保留的属性名,支持使用名称类通配符。例如下面的例子:

-keep-property-name
age
firstName
lastName

注意

该选项在开启-enable-property-obfuscation时生效

哪些属性名应该被保留?

为了保障混淆的正确性,建议保留所有不通过点语法访问的属性。

例子:

var obj = {x0: 0, x1: 0, x2: 0};
for (var i = 0; i <= 2; i++) {
    console.log(obj['x' + i]);  // x0, x1, x2 应该被保留
}

Object.defineProperty(obj, 'y', {});  // y 应该被保留
console.log(obj.y);

obj.s = 0;
let key = 's';
console.log(obj[key]);        // s 应该被保留

obj.u = 0;
console.log(obj.u);           // u 可以被正确地混淆

obj.t = 0;
console.log(obj['t']);        // 在开启字符串字面量属性名混淆时t和't'会被正确地混淆,但是建议保留

obj['v'] = 0;
console.log(obj['v']);        // 在开启字符串字面量属性名混淆时'v'会被正确地混淆,但是建议保留

对于间接导出的场景,例如export MyClass和let a = MyClass; export {a};,如果不想混淆它们的属性名,那么需要使用 保留选项 来保留这些属性名。另外,对于直接导出的类或对象的属性的属性名,例如下面例子中的name和age, 如果不想混淆它们,那么也需要使用 保留选项 来保留这些属性名。

export class MyClass {
    person = {name: "123", age: 100};
}

没有在so库的d.ts文件中声明的API(例如示例中的foo),如果要在ArkTS/TS/JS文件中使用需手动保留API名称。

import testNapi from 'library.so'
testNapi.foo()

-keep-global-name [,identifiers,…]

指定要保留的顶层作用域的名称,支持使用名称类通配符。例如,

-keep-global-name
Person
printPersonName

哪些顶层作用域的名称应该被保留?

在Javascript中全局变量是globalThis的属性。如果在代码中使用globalThis去访问全局变量,那么该变量名应该被保留。

示例:

var a = 0;
console.log(globalThis.a);  // a 应该被保留

function foo(){}
globalThis.foo();           // foo 应该被保留

var c = 0;
console.log(c);             // c 可以被正确地混淆

function bar(){}
bar();                      // bar 可以被正确地混淆

class MyClass {}
let d = new MyClass();      // MyClass 可以被正确地混淆

-keep-file-name [,identifiers,…]

指定要保留的文件/文件夹的名称(不需要写文件后缀),支持使用名称类通配符。例如,

-keep-file-name
index
entry

哪些文件名应该被保留?

const module1 = require('./file1')   // ArkTS不支持CommonJS语法,这种路径引用应该被保留
const moduleName = './file2'
const module2 = import(moduleName)    // 动态引用方式无法识别moduleName是否是路径,应该被保留

-keep-comments [,identifiers,…]

保留声明文件中元素上方的JsDoc注释,支持使用名称类通配符。例如想保留声明文件中Human类上方的JsDoc注释,可进行以下配置:

-keep-comments
Human

注意

  1. 该选项在开启-remove-comments时生效
  2. 当声明文件中某个元素名称被混淆时,该元素上方的JsDoc注释无法通过-keep-comments保留。例如当在-keep-comments中配置了exportClass时,如果下面的类名被混淆,其JsDoc注释无法被保留:
/*
 * @class exportClass
 */
export class exportClass {}

-keep-dts filepath

保留指定路径的.d.ts文件中的名称。这里的文件路径可以是一个目录,这种情况下目录中所有.d.ts文件中的名称都会被保留。

如果在构建HAR时使用了这个选项,那么文件中的名称会被合并到最后的obfuscation.txt文件中。

-keep path

保留指定路径中的所有名称(例如变量名、类名、属性名等)不被混淆。这个路径可以是文件与文件夹,若是文件夹,则文件夹下的文件及子文件夹中文件都不混淆。

路径仅支持相对路径,./与…/为相对于混淆配置文件所在目录,支持使用路径类通配符。

-keep
./src/main/ets/fileName.ts   // fileName.ts中的名称不混淆
../folder                    // folder目录下文件及子文件夹中的名称都不混淆
../oh_modules/json5          // 引用的三方库json5里所有文件中的名称都不混淆

注:该功能不影响文件名混淆-enable-filename-obfuscation的功能

保留选项支持的通配符

名称类通配符

名称类通配符使用方式如下:

通配符含义示例
?匹配任意单个字符"AB?“能匹配"ABC"等,但不能匹配"AB”
*匹配任意数量的任意字符AB"能匹配"AB”、“aABb”、“cAB”、"ABc"等

使用示例

保留所有以a开头的属性名称:

-keep-property-name
a*

保留所有单个字符的属性名称:

-keep-property-name
?

保留所有属性名称:

-keep-property-name
*

路径类通配符

路径类通配符使用方式如下:

通配符含义示例
?匹配任意单个字符,除了路径分隔符/“…/a?“能匹配”…/ab"等,但不能匹配”…/a/"
*匹配任意数量的任意字符,除了路径分隔符/“…/a*/c"能匹配”…/ab/c",但不能匹配"…/ab/d/s/c"
**匹配任意数量的任意字符“…/a**/c"能匹配”…/ab/c",也能匹配"…/ab/d/s/c"
!表示非,只能写在某个路径最前端,用来排除用户配置的白名单中已有的某种情况“!../a/b/c.ets"表示除”…/a/b/c.ets"以外

使用示例

表示路径…/a/b/中所有文件夹(不包含子文件夹)中的c.ets文件不会被混淆:

-keep
../a/b/*/c.ets

表示路径…/a/b/中所有文件夹(包含子文件夹)中的c.ets文件不会被混淆:

-keep
../a/b/
!../a/b/c.ets

表示路径…/a/b/中,除了c.ets文件以外的其它文件都不会被混淆。其中,!不可单独使用,只能用来排除白名单中已有的情况:

-keep
../a/b/
!../a/b/c.ets

表示路径…/a/中的所有文件(不包含子文件夹)不会被混淆:

-keep
../a/*

表示路径…/a/下的所有文件夹(包含子文件夹)中的所有文件不会被混淆:

-keep
../a/**

表示模块内的所有文件不会被混淆:

-keep
./**

注意

(1)以上选项,不支持配置通配符*、?、!作其它含义使用。

例如:

class A {
  '*'= 1
}

-keep-property-name
*

此时表示匹配任意数量的任意字符,配置效果为所有属性名称都不混淆,而不是只有属性不被混淆。

(2)-keep选项中只允许使用/路径格式,不支持\或\。

注释

可以使用#在混淆规则文件中进行注释。每行以#开头的文本会被当做是注释,例如下面的例子:

# white list for MainAbility.ets
-keep-global-name
MyComponent
GlobalFunction

-keep-property-name # white list for dynamic property names
firstName
lastName
age

构建HAR时,注释不会被合并到最后的obfuscation.txt文件中。

混淆规则合并策略

一个工程中经常会有许多混淆规则文件,这些文件来自于:

  • 主工程的ruleOptions.files (这里主工程指的是正在构建的工程)
  • 本地依赖的library中的consumerFiles选项中指定的文件
  • 远程依赖的HAR包中的obfuscate.txt文件

当构建主工程的时候,这些文件中的混淆规则会按照下面的合并策略(伪代码)进行合并:

let `listRules` 表示上面提到的所有混淆规则文件的列表
let finalRule = {
    disableObfuscation: false,
    enablePropertyObfuscation: false,
    enableToplevelObfuscation: false,
    compact: false,
    removeLog: false,
    keepPropertyName: [],
    keepGlobalName: [],
    keepDts: [],
    printNamecache: string,
    applyNamecache: string
}
for each file in `listRules`:
    for each option in file:
        switch(option) {
            case -disable-obfuscation:
                finalRule.disableObfuscation = true;
                continue;
            case -enable-property-obfuscation:
                finalRule.enablePropertyObfuscation = true;
                continue;
            case -enable-toplevel-obfuscation:
                finalRule.enableToplevelObfuscation = true;
                continue;
            case -compact:
                finalRule.compact = true;
                continue;
            case -remove-log:
                finalRule.removeLog = true;
                continue;
            case -print-namecache:
                finalRule.printNamecache = #{指定的路径名};
                continue;
            case -apply-namecache:
                finalRule.applyNamecache = #{指定的路径名};
                continue;
            case -keep-property-name:
                finalRule.keepPropertyName.push(#{指定的名称});
                continue;
            case -keep-global-name:
                finalRule.keepGlobalName.push(#{指定的名称});
                continue;
            case -keep-dts:
                finalRule.keepDts.push(#{指定的路径});
                continue;
        }
    end-for
end-for

最后使用的混淆规则来自于对象finalRule。

如果构建的是HAR,那么最终的obfuscate.txt文件内容来自于主工程和本地依赖的library的consumerFiles选项,

以及依赖的HAR的obfuscate.txt文件的合并。合并策略和上面一样,除了以下的不同:

  • -keep-dts选项会被转换成-keep-global-name和-keep-property-name。
  • -print-namecache和apply-namecache选项会被忽略,不会出现在最后的obfuscate.txt文件中。

报错栈还原

经过混淆的应用程序中代码名称会发生更改,crash时打印的报错栈更难以理解,因为报错栈与源码不完全一致。开发人员可使用DevEco Studio命令工具Command Line Tools中的hstack插件来还原源码堆栈。

说明

  • 目前不支持在hvigor构建流程中插入自定义混淆插件
  • 混淆的HAR包被模块依赖,若模块开启混淆,则HAR包会被二次混淆
  • DevEco Studio右上角Product选项,将其中Build Mode选择release,可开启release编译模式

鸿蒙全栈开发全新学习指南

为了积极培养鸿蒙生态人才,让大家都能学习到鸿蒙开发最新的技术,针对一些在职人员、0基础小白、应届生/计算机专业、鸿蒙爱好者等人群,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线【包含了大厂APP实战项目开发】

本路线共分为四个阶段:

第一阶段:鸿蒙初中级开发必备技能

在这里插入图片描述

第二阶段:鸿蒙南北双向高工技能基础:gitee.com/MNxiaona/733GH

第三阶段:应用开发中高级就业技术

第四阶段:全网首发-工业级南向设备开发就业技术:gitee.com/MNxiaona/733GH

鸿蒙开发面试真题(含参考答案):gitee.com/MNxiaona/733GH

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:gitee.com/MNxiaona/733GH

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React_创建一个项目

目录 一、React&#xff08;js 版&#xff09; 二、React&#xff08;ts 版&#xff09; 使用react创建一个项目,前提是确保你已经安装了Node.js和npm。 如果没有安装Node.js和npm&#xff0c;查看这个文件&#xff1a; 安装node.js和npmhttps://blog.csdn.net/zxy1993106…

Arcgis地统计分析工具灰色不可用 解决方法

使用Arcmap&#xff0c;调用地统计分析工具&#xff08;Geostatistical Analyst&#xff09;下的探索数据&#xff08;Explore Data&#xff09;&#xff0c;发现工具呈灰色不可用。这是由于扩展模块中没有将该模块做勾选设置导致的。下面介绍一下如何解决地统计分析工具不可用…

学生成绩管理系统带8000字文档学生选课管理系统java项目javaweb项目ssm项目jsp项目java课程设计java毕业设计

文章目录 学生选课成绩管理系统一、项目演示二、项目介绍三、8500字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码带8500字文档&#xff08;9.9&#xffe5;带走&#xff09; 学生选课成绩管理系统 一、项目演示 选课成绩管理系统 二、项目介绍 语言: Java …

【从0实现React18】 (五) 初探react mount流程 完成核心递归流程

更新流程的目的&#xff1a; 生成wip fiberNode树标记副作用flags 更新流程的步骤&#xff1a; 递&#xff1a;beginWork归&#xff1a;completeWork 在 上一节 &#xff0c;我们探讨了 React 应用在首次渲染或后续更新时的整体更新流程。在 Reconciler 工作流程中&#xff…

硬盘空间告急?监控服务器容量,钉钉及时提醒!

在日常的服务器维护中&#xff0c;硬盘容量的监控是非常重要的。如果硬盘容量超过某个阈值&#xff0c;可能会导致服务器无法正常运行&#xff0c;影响业务的正常运作。为了避免这种情况&#xff0c;我们可以编写一个Shell脚本&#xff0c;定期检查硬盘容量&#xff0c;当超过设…

springboot + Vue前后端项目(第二十记)

项目实战第二十记 写在前面1. 高德地图官网2. 开发文档3. 集成高德地图3.1 在public文件夹下创建config.js3.2 index.html&#xff08;在项目启动文件中引入外部的js&#xff09;3.3 点标记&#xff08;用点标记当前位置&#xff09;3.4 信息窗体&#xff08;点击当前位置&…

如何预防和处理他人盗用IP地址?

IP地址的定义及作用 解释 IP 地址在互联网中的作用。它是唯一标识网络设备的数字地址&#xff0c;类似于物理世界中的邮政地址。 1、IP地址盗窃的定义 解释一下什么是IP地址盗用&#xff0c;即非法使用他人的IP地址或者伪造IP地址的行为&#xff0c;这种行为可能引发法律和安…

DLMS/COSEM协议—(Green-Book)Gateway protocol

DLMS/COSEM协议 — Gateway protocol 10.10 Gateway protocol &#xff08;网关协议&#xff09;10.10.1 概述10.10.2 网关协议 &#xff08;The gateway protocol&#xff09;10.10.3 HES在WAN/NN中作为发起者&#xff08;拉取操作&#xff09;10.10.4 LAN中的终端设备作为发起…

数据库物理结构设计-定义数据库模式结构(概念模式、用户外模式、内模式)、定义数据库、物理结构设计策略

一、引言 如何基于具体的DBMS产品&#xff0c;为数据库逻辑结构设计的结果&#xff0c;即关系数据库模式&#xff0c;制定适合应用要求的物理结构 1、在设计数据库物理结构前&#xff0c;数据库设计人员首先 要充分了解所用的DBMS产品的功能、性能和特点&#xff0c;包括提供…

【最新综述】基于伪标签的半监督语义分割

Semi-Supervised Semantic Segmentation Based on Pseudo-Labels: A Survey 摘要&#xff1a; 语义分割是计算机视觉领域的一个重要而热门的研究领域&#xff0c;其重点是根据图像中像素的语义对其进行分类。然而&#xff0c;有监督的深度学习需要大量数据来训练模型&#xff…

Asm动态生成类和get and set方法

asm在解析文件的时候是按照特定顺序进行分析的&#xff0c;首先是visit方法&#xff0c;做类相关的解析&#xff0c;然后是注解&#xff0c;然后是属性&#xff0c;最后才是方法&#xff0c;属性是在所有方法分析前面进行&#xff0c;也就是只有当class文件中的所有属性都遍历完…

【Android11】开机启动日志捕捉服务

一、前言 制作这个功能的原因是客户想要自动的记录日志中的报错和警告到设备的内存卡里面。虽然开发者模式中有一个“bug report” 会在/data/user_de/0/com.android.shell/files/bugreports/目录下生成一个zip包记录了日志。但是客户觉得这个日志很难获取到他们需要的信息&am…

无需劳师动众,让石油化工DCS集散控制系统轻松实现无线传输!

石油化工中,为了保证较高的可靠性和安全性,大量使用的是DCS集散控制系统。与FCS现场总线的“现场采集,转换为数字信号来集中传输”不同,DCS系统为了避免由于线缆断裂或者节点问题导致整个控制系统失灵,采用“分散传输,集中采集”的方式,即每个传感器通过4-20mA的模拟量通…

el-upload 上传图片及回显照片和预览图片,文件流和http线上链接格式操作

<div v-for"(info, index) in zsjzqwhxqList.helicopterTourInfoList" :key"info.id" >编辑上传图片// oss返回线上地址http链接格式&#xff1a;<el-form-itemlabel"巡视结果照片":label-width"formLabelWidth"><el…

【MySQL】 -- 用户管理

1. 权限 如果我们只能使用root用户&#xff0c;这样存在安全隐患。这时&#xff0c;就需要使用MySQL的用户管理。创建出非root用户&#xff0c;限制其权限。 权限这个概念拿出来就是用来限制非root用户的。这样从技术手段上保证了数据的安全性和完整性&#xff0c;防止有人删库…

LeetCode11. 盛最多水的容器题解

LeetCode11. 盛最多水的容器题解 题目链接&#xff1a; https://leetcode.cn/problems/container-with-most-water 示例 思路 暴力解法 定住一个柱子不动&#xff0c;然后用其他柱子与其围住面积&#xff0c;取最大值。 代码如下&#xff1a; public int maxArea1(int[]…

麒麟系统安装Redis

一、背景 如前文&#xff08;《麒麟系统安装MySQL》&#xff09;所述。 二、下载Redis源码 官方未提供麒麟系统的Redis软件&#xff0c;须下载源码编译。 下载地址&#xff1a;https://redis.io/downloads 6.2.14版本源码下载地址&#xff1a;https://download.redis.io/re…

ADI-DSP|在指定内存写入数据

一、LDF文件设置内存空间 user_data_test { TYPE(BW RAM) START(0x00380010) END(0x0039bfff) WIDTH(8) }//usr data dxe_user_data_bw BW{INPUT_SECTION_ALIGN(4)INPUT_SECTIONS( $OBJS_LIBS(user_data) )} > user_data_test 二、在C文件中设置数据 /************…

2.x86游戏实战-跨进程读取血量

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 接下来会写C/C代码&#xff0c;C/C代码不是很难&#xff0c;然后为了快速掌握逆向这个技能&#xff0c;我…

List常用操作比for循环更优雅的写法

private String name; //姓名 private Integer age; //年龄 private Integer departId; //所属部门id } List list new ArrayList<>(); 复制代码 简单遍历 使用lamada表达式之前&#xff0c;如果需要遍历list时&#xff0c;一般使用增强for循环&#xff0c;代码如…