关于代码混淆,看这篇就够了

代码混淆一.基本概念java的bytecode很容易通过JAD等反编译工具还原出源代码。这样势必不满足安全的定义。如何一定程度上保护需要防止被反编译的源代码呢?混淆(obfuscate)技术。注意:用obfuscate防盗版是根本不可能,连汇编这种东西都能被**掉,而java代码基本上等同于开源的同义词。用obfuscate只是为了增加反编译的难度,保护源代码的知识产权。混淆包照常运行,没有任何问题。可以使用反编译工具如jd-gui查看混淆后的包,验证混淆效果。

二.混淆技术名称混淆 name obfuscode将有意义的类,字段、方法名称更改为无意义的字符串。生成的新名称越 短,字节代码越小。在名称混淆的字节代码中,包,类,字段和方法名称已重命名,并且永远不能恢复原始名称。

流混淆 Flow Obfuscation用于if, switch, while,for等关键字,对字节码进行细微的修改,模糊控制流,而不改变代码在运行时的行为。通常情况下,选择和循环等逻辑构造会被更改,因此它们不再具有直接等效的Java源代码。流模糊的字节码通常强制反编译器将一系列标签和非法的goto语句插入到它们生成的源代码中。源代码有时会因为反编译错误而变得更加模糊。

其他异常混淆 Exception Obfuscation字符串加密混淆 String Encryption引用混淆 Reference Obfuscation三.常用工具1.ipaguardproguard是一个免费的 混淆重签名,优化,混肴器。不需要ios app源码,直接对ipa文件进行混淆加密。可对IOS ipa 文件的代码,代码库,资源文件等进行混淆保护。 可以根据设置对函数名、变量名、类名等关键代码进行重命名和混淆处理,降低代码的可读性,增加ipa破解反编译难度。可以对图片,资源,配置等进行修改名称,修改md5。只要是ipa都可以,不限制OC,Swift,Flutter,React Native,H5类app

官网地址:IpaGuard官网--IOS 应用程序ipa文件混淆加密保护工具

2.yGuardyGuard是一款免费的Java混淆器(非开源),它有Java和.NET两个版本。yGuard 完全免费,基于 Ant 任务运行,提供高可配置的混淆规则。官网地址:www.yworks.com/products/yg…

3.allatori第二代Java混淆器。所谓第二代混淆器,不仅仅能进行字段混淆,还能实现流混淆。命名混淆,流混淆,调试信息混淆,字符串编码,以及水印技术。对于教育和非商业项目来说这个混淆器是免费的。支持war和jar格式,支持对需要混淆代码的应用程序添加有效日期。官网地址:www.allatori.com/…

4.总结推荐使用 proguard :开源, 使用简单 ,文档丰富完善。

四.工具对比工具    官网地址    官方文档    开源免费    名称混淆    流混淆    maven支持    功能proguard    www.guardsquare.com/proguard    www.guardsquare.com/manual/home    √    √    ✕    √    yGuard    www.yworks.com/products/yg…    yworks.github.io/yGuard/    √    √    ✕    √    allatori    allatori.com/        ✕(免费用于教育和非商业项目)    √    √    √    减小包大小;混淆代码;添加水印五.详细内容1.yGuard(yworks.github.io/yGuard/)易于设置:yGuard 是一个 Ant 任务!作为 Ant 任务,yGuard 可以无缝集成到您在 Ant、Maven 和 Gradle 等众多构建系统中的部署过程中高级收缩:yGuard 通过依赖分析提供精细的代码收缩功能。可配置/安全代码:yGuard 提供高度可配置的名称混淆,可保护您的知识产权免受逆向工程。开源:yGuard 是完全开源的!与昂贵的商业产品相反,yGuard 是并且永远都是免费的。Java 兼容性:要运行 yGuard 软件,您需要 JDK 1.7.x 或更高版本以及 Ant 1.5.x 或更高版本(它可能与任一软件的早期版本兼容,但尚未经过测试)。yGuard 与所有已发布的 Java 版本(最高 Java 17)兼容。但是,根据使用的版本,功能可能会略有不同。该文档包含不同版本支持的功能的详细说明。如果您打算将 yGuard 与 Java 以外的东西一起使用,还有一个关于3rd 方 JVM 支持的部分。ProGuard是一个开源的 Java 类文件收缩器、优化器、混淆器和预验证器。因此,ipaguard处理的应用程序和库更小、更快,并且在一定程度上可以抵御逆向工程。

收缩步骤检测并删除未使用的类、字段、方法和属性。优化器 步骤优化字节码并删除未使用的指令。混淆步骤使用简短无意义的名称重命名剩余的类、字段和方法。最后的预验证步骤将预验证信息添加到类中,这是 Java Micro Edition 和 Java 6 及更高版本所必需的。yGuard1.maven引用方式<build>        <plugins>            <plugin>                <!--结合ant run 来使用yguard -->                <artifactId>maven-antrun-plugin</artifactId>                <dependencies>                    <dependency>                        <groupId>com.yworks</groupId>                        <artifactId>yguard</artifactId>                        <version>3.1.0</version>                    </dependency>                </dependencies>                <executions>                    <execution>                        <phase>package</phase>                        <goals>                            <goal>run</goal>                        </goals>                        <configuration>                            <tasks>                                <property refid="maven.compile.classpath" name="mvn.classpath"/>                                <!-- <echo message="Using Maven Classpath: ${mvn.classpath}" /> -->                                <taskdef name="yguard"                    classname="com.yworks.yguard.YGuardTask"/>                                                                <yguard>                                    <!-- yguard配置 -->                                </yguard>                                                            </tasks>                        </configuration>                     </execution>                </executions>            </plugin>        </plugins>    </build>复制代码

2.yguard配置解析写在前面yguard共分为两大任务配置:rename  混淆名称 :主要用于修改类名,属性名,方法名以及参数名等。shrink  收缩代码 : 主要用于从多个入口点中删除所有无法访问的类、字段和方法。keep keep是rename和shrink的子元素,用于指定从父级rename或shrink任务中排除的元素。注意事项注意事项1 :如果项目需要shrink, shrink最好是配置在rename之前。即在进行代码混淆之前,先进行代码压缩。 因为压缩代码需要指定压缩的根代码。举个例子:比如制定main方法:  。如果先混淆,DplDbtransferApplication类名被修改的话(比如为A.class),该配置将会无效,所有代码都会被 shrink 删除,因为已经找不到DplDbtransferApplication这个类了(类名被修改)。其他配置请参考官方文档。配置说明基础配置

 <!-- yguard 是公用配置和rename以及shrink配置的容器标签 --> <yguard>    <!-- 必须至少指定一个inoutpair元素或一个非空inoutpairs元素才能运行yguard任务。此元素指定输入和输出 jar 文件的路径     in out 必须指定设置值,不指定报错    1.in 指定一个现有的jar/war文件,其中包含未收缩和未混淆的 .class文件。    2.out 指定一个 jar/war文件的路径,该文件将被创建并用于放置收缩和混淆过程的结果。    3.resources 如何处理资源文件,支持三种值:copy,auto,none。 默认配置copy。            1.copy 直接复制资源文件 默认情况下,只需将所有资源文件复制到输出 jar 中            2.auto 仅复制那些在压缩后仍包含一个或多个 .class 文件的目录中的资源文件。            3.none 丢弃所有资源文件。-->    <inoutpair     in="${project.build.directory}/${project.build.finalName}.${project.packaging}"     out="${project.build.directory}/${project.build.finalName}.${project.packaging}" />             <externalclasses>            </externalclasses>        <!-- 用于配置一些属性 ,保存类的调试信息:比如 LineNumberTable:行号表;LocalVariableTable:本地变量表等。  -->    <attribute name="SourceFile, LineNumberTable, LocalVariableTable">          <patternset>            <include name="com.ewa.pipe.**"/>          </patternset>        </attribute>        <!-- shrink 用于收缩代码配置。         1.logfile  shrink过程的日志文件        2.在shrink过程中,如果有错误代码,代码将会被替换为: throw new InternalError("Badly shrinked")。        比如:当某些类的private属性被删除,但是public方法中有引用该属性,而属性被删除了,即会输出该异常错误。    -->    <shrink logfile="${project.build.directory}/yshrink.log.xml" createStubs="true">        <!-- shrink中的keep和rename中的keep一致。 -->        <keep>                        <method name="void main(java.lang.String[])" class="${mainclass}" />        </keep>    </shrink>        <!-- 用于自定义某些配置和属性更改。        1.mainclass 用于设置主程序启动位置,该文件将不会被混淆。        2.logfile 混淆过程中的日志文件保存地址。名称以“.gz”结尾,yGuard 将自动创建文件的 gzip 压缩版本,默认为yguardlog.xml        3.conservemanifest 当为false时,重新生成 MANIFEST.MF的内容。默认为false。        4.replaceClassNameStrings  是否混淆代码中某些字符串跟类名相关的东西。默认为true        比如源码: System.out.print("com.ewa.pipe.dbtransfer.dpl.mapper.BlendMapper");混淆后: System.out.print("com.ewa.pipe.dbtransfer.dpl.A.B");        5.scramble 是否随机混淆代码,默认false。如果为true即每次打包生成的类名将随机替换。比如Test.class 第一次混淆为A.class,第二次就为B.class        6.annotationClass 某些不必要混淆的数据,比如如下配置为Test注解,当配置到类上时,类中的所有东西不会被混淆;当配置到属性时,属性名称不会被混淆。        -->    <rename         mainclass="com.ewa.pipe.dbtransfer.dpl.DplDbtransferApplication"        logfile="${project.build.directory}/yguard.log.xml"        conservemanifest = "false"        replaceClassNameStrings="true"        scramble = "false"        annotationClass="com.ewa.pipe.dbtransfer.dpl.Test"        >               <!--  -->            <keep>                        </keep>                <!-- 1.error-checking 用于检测错误,检测到错误就失败停止。 -->               <property name="error-checking" value="pedantic"/>                        <!-- 2.error-checking 可用于告诉重命名引擎在混淆期间使用不同的命名方案。目前可以将此属性设置为以下值之一(默认small,通常使用small就行了):            small:将产生非常短的名称,即生成的 jar 文件将尽可能小。            best:会产生很可能被反编译器和反汇编器误解的名称。使用这种命名方案,在大多数文件系统上甚至不可能成功解压缩或解压缩生成的 jar 文件(Windows、Standard Unix、Standard Linux、MacOS)。然而,这种方案占用了大量空间,并且生成的 jar 可能会变大(通常大约是两倍大小)。            mix:是其他两个值的混合,这会导致合理的小但仍然难以反编译 jar 文件。             -->             <!-- 其他属性( language-conformity    ,overload-enabled,obfuscation-prefix,digests,expose-attributes)请参考官方文档。 -->               <property name="naming-scheme" value="small"/>        </rename> </yguard>复制代码

keep配置说明

class元素

class用于在rename和shrink过程中排除某些类,字段和方法。其是keep的子元素。以下是配置说明(- 表示会被收缩,即被删除 ):

可见性(是否被收缩)    public    protected    friendly    privatenone    -    -    -    -public    *    -    -    -protected    *    *    -    -friendly    *    *    *    -private    *    *    *    *属性说明

name  指定要保留的类名。 在shrink中,只会保留类名称,类中的属性和方法都会被删除掉。classes 保持类的可见性 :其值是上述:none , public , protected , friendly , private 。默认为nonemethods 保留方法的可见性 , 值同classes的描述。默认为nonefields  保留属性的可见性 , 值同classes的描述。默认为noneextends  保留对继承了该类的可见性 。1.在shrink中凡是继承了该类的子类都不会被删除。 2.在rename中凡是继承了该类的子类都不会被修改名称。implements  保留对实现该接口的可见性 。1.在shrink中凡是实现该接口的类都不会被删除。 2.在rename中凡是实现该接口的类都不会被修改名称。注意事项

以上属性可以单独使用,一可以混合使用。其 extends/implements 可以和classes, methods,fields混合使用。参考列2说明。列1:

    <shrink logfile="${project.build.directory}/yshrink.log.xml">       <keep>            <!-- 保留NameTest类不被删除,但是内部的方法和会属性会被删除,不论私有还是共有。 -->            <class name="com.arm.code.mix.base.NameTest"/>            <!-- 保留所有公用的类,方法和属性。其关联的类,方法和属性会被保留,不会被删除  -->               <class classes="public" methods="public" fields="public"/>            <!-- 保留所有继承了BaseClass的类不被删除,但是内部的方法和会属性会被删除,不论私有还是共有。  -->            <class extends="com.arm.code.mix.base.BaseClass"/>       </keep>    </shrink>复制代码列2:

    <shrink logfile="${project.build.directory}/yshrink.log.xml">       <keep>            <!-- 保留NameTest类不被删除,并保留其private级别的方法和属性 -->            <class name="com.arm.code.mix.base.NameTest" methods="private" fields="private"/>            <!-- 保留所有继承了BaseClass的类不被删除,并保留其private级别的方法和属性  -->            <class extends="com.arm.code.mix.base.BaseClass" methods="private" fields="private"/>       </keep>    </shrink>复制代码列3:

一下举列几个模式集的列子,模式集可以参考ant。 <!--  include shrink:不需要被删除的类,保留的类。rename:不需要被混淆的类名 --><class>  <patternset>    <include name="com.mycompany.**.*Bean"/>    <exclude name="com.mycompany.secretpackage.*"/>    <exclude name="com.mycompany.myapp.SecretBean"/>    <!-- 由于 Ant'$'用作转义字符,因此如果您想将一个作为参数传递给任务,则必须使用两个连续的'$'s( )。'$$'-->    <exclude name="org.w3c.sax?.**.*$$*"/>   </patternset></class>复制代码method

method 用于在rename和shrink过程中排除方法。其是keep的子元素。以下是配置说明(- 表示会被收缩,即被删除 ):

<!-- 这将保留MyClass类的main和foo方法。此外,所有readObject和writeObject方法(用于序列化)都将保存在com.mycompany.myapp.data包的所有类中。    请注意,您必须指定返回参数的类型,即使它是 void,并且您必须为所有类使用完全限定名称,即使是java.lang package. --><method class="com.mycompany.myapp.MyClass"  name="void main(java.lang.String[])"/><method class="com.mycompany.myapp.MyClass"  name="int foo(double[][], java.lang.Object)"/><method name="void writeObject(java.io.ObjectOutputStream)">  <patternset>    <include name="com.mycompany.myapp.data.*"/>  </patternset></method><method name="void readObject(java.io.ObjectInputStream)">  <patternset>    <include name="com.mycompany.myapp.data.*"/>  </patternset></method>复制代码

field

field 您可以按名称指定应从收缩或名称混淆中要保留的字段

<!-- 保留MyClass类中的所有字段。    此外,所有serialVersionUID字段(用于序列化)都将保存在com.mycompany.myapp.data包的所有类中。 --><field class="com.mycompany.myapp.MyClass" name="field"/><field name="serialVersionUID">  <patternset>    <include name="com.mycompany.myapp.data.*"/>  </patternset></field>复制代码package  

package 用于从重命名过程中排除某些包的名称。它不能用于收缩(shrink)过程 。这对类、方法或字段名称没有影响。

    <package>      <patternset>        <!-- com.mycompany.myapp不被混淆。myapp下的包名还是会被混淆 -->        <include name="com.mycompany.myapp.*"/>        <!-- com.mycompany.myapp不被混淆。myapp下的包名也不会被混淆 -->        <include name="com.mycompany.myapp.**"/>      </patternset>    </package>复制代码3.几种情况下的使用方式springboot项目1.注意事项

yguard插件执行要放在 spring boot打包项目之前,因为反置的话,会造成jar中的springboot的启动相关类被混淆,而造成启动项目失败。2.项目使用失败的问题收集总结

本地打包之后启动项目失败:由于是本地idea将jdk设置成jdk17了,导致打包失败。 设置为jdk8后成功启动。项目使用mybaties plus,项目里只有一个接口:public interface TimePullLogMapper extends BaseMapper{} , 造成混淆后打包报错:spring至少一个bean实现。后面加上:  后正常。==service的接口和实现都要暴露,不然spring的注入和nacos的服务发现都会存在问题。3.配置模版

<keep>                                            <!--包名不混淆配置-->                                            <package>                                                <patternset>                                                    <include name="com.arm.oceansearch.**"/>                                                </patternset>                                            </package>                                            <!--mybaites 相关的mapper混淆后,会造成boot项目启动失败 -->                                            <class implements="com.arm.boot.core.base.BaseMapper"/>                                            <!--mybaites默认生成sql时是使用的实体类的类名,所以不能混淆-->                                            <class implements="com.arm.oceansearch.entity.BaseEntity"/>                                            <!-- 本包的controller混淆后,无法读取mapping映射,原因未知。-->                                            <class>                                                <patternset>                                                    <include name="com.arm.oceansearch.controller.*"/>                                                </patternset>                                            </class>                                            <!-- service的接口和实现都要暴露,不然spring的注入和nacos的服务发现都会存在问题。 -->                                            <class>                                                <patternset>                                                    <include name="com.arm.oceansearch.service.**"/>                                                </patternset>                                            </class>                                            <!--main方法配置-->                                            <method name="void main(java.lang.String[])"                                                    class="com.arm.oceansearch.OceanSearchApplication"/>                                        </keep>复制代码

简介ProGuard 是一个开源的 Java 类文件收缩器、优化器、混淆器和预验证器。因此,ProGuard 处理的应用程序和库更小、更快,并且在一定程度上可以抵御逆向工程。

收缩步骤检测并删除未使用的类、字段、方法和属性。优化器 步骤优化字节码并删除未使用的指令。混淆步骤使用简短无意义的名称重命名剩余的类、字段和方法。最后的预验证步骤将预验证信息添加到类中,这是 Java Micro Edition 和 Java 6 及更高版本所必需的。对反射的处理反射和内省对于任何代码的自动处理都存在特殊的问题。在 ProGuard 中,代码中动态创建或调用(即按名称)的类或类成员也必须指定为入口点。例如,Class.forName()构造可以在运行时引用任何类。通常不可能计算必须保留哪些类(使用它们的原始名称),因为类名可能是从配置文件中读取的,例如。因此,您必须在 ProGuard 配置中指定它们,同样简单-keep选项

Class.forName("SomeClass")SomeClass.classSomeClass.class.getField("someField")SomeClass.class.getDeclaredField("someField")SomeClass.class.getMethod("someMethod", null)SomeClass.class.getMethod("someMethod", new Class[] { A.class,... })SomeClass.class.getDeclaredMethod("someMethod", null)SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class,... })AtomicIntegerFieldUpdater.newUpdater(SomeClass.class, "someField")AtomicLongFieldUpdater.newUpdater(SomeClass.class, "someField")AtomicReferenceFieldUpdater.newUpdater(SomeClass.class, SomeType.class, "someField")支持可单独使用。首先,下载一个ProGuard 版本或者构建 ProGuard从源头。然后可以通过调用目录中的脚本直接从命令行执行 ProGuard bin:linux/mac:bin/proguard.sh -injars path/to/my-application.jar \ -outjars path/to/obfuscated-application.jar \ -libraryjars path/to/java/home/lib/rt.jarwindows:bin\proguard.bat -injars path/to/my-applicati^ -outjars path/to/obfuscated-application.jar ^ -libraryjars path/to/java/home/lib/rt.jarGradle 模式ant模式Maven模式:(没有正式提供 maven 集成,也无法提供支持,但有可用的解决方案,但 Guardsquare 不保证它们提供的功能。)来源实现:github.com/wvengen/pro…github.com/dingxin/pro…错误解析[proguard] Error: The input doesn't contain any classes. Did you specify the proper '-injars' options?处理:<inFilter>com/ewa/pipe/**</inFilter>, inFilter标签设置为包路径地址,把‘.’换成‘/’。 injar : 指定target中的一个目标地址:这里指定编译后的 classes文件夹。  inFilter 指定的是 classes的内部的文件夹(package)地址。<!-- 加载文件的过滤器,就是你的工程目录了-->                    <inFilter>com/arm/code/**</inFilter>                    <!-- 对什么东西进行加载,这里仅有classes成功,毕竟你也不可能对配置文件及JSP混淆吧-->                    <injar>classes</injar>复制代码以下是一个例子说明,如果你想更多的有用信息,请查看文档(www.guardsquare.com/manual/conf…)

<configuration>                    <!-- 是否将生成的PG文件安装部署-->                    <attach>false</attach>                    <!-- 是否混淆 -->                    <obfuscate>true</obfuscate>                    <!-- 指定生成文件分类 -->                    <!--<attachArtifactClassifier>pg</attachArtifactClassifier>-->                    <!-- 加载文件的过滤器,就是你的工程目录了-->                    <inFilter>com/arm/code/**</inFilter>                    <!-- 对什么东西进行加载,这里仅有classes成功,毕竟你也不可能对配置文件及JSP混淆吧-->                    <injar>classes</injar>                    <!-- 输出目录-->                    <outputDirectory>${project.build.directory}</outputDirectory>                    <outjar>${project.build.finalName}.${project.packaging}</outjar>                    <options>                        <!-- JDK目标版本1.7-->                        <option>-target 1.8</option>                        <!-- 不做收缩(删除注释、未被引用代码)-->                        <option>-dontshrink</option>                        <!-- 不做优化(变更代码实现逻辑)-->                        <option>-dontoptimize</option>                        <!-- 不忽略非公用类文件及成员-->                        <option>-dontskipnonpubliclibraryclasses</option>                        <option>-dontskipnonpubliclibraryclassmembers</option>                        <!-- 优化时允许访问并修改有修饰符的类和类的成员 -->                        <option>-allowaccessmodification</option>                        <!-- 确定统一的混淆类的成员名称来增加混淆,防止冲突-->                        <option>-useuniqueclassmembernames</option>                        <!-- 不混淆所有包名,Spring配置中有大量固定写法的包名-->                        <option>-keeppackagenames</option>                        <!-- 不混淆所有特殊的类-->                        <option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod</option>                        <!-- 不混淆所有的set/get方法,毕竟项目中使用的部分第三方框架(例如Shiro)会用到大量的set/get映射-->                        <option>-keepclassmembers public class * {void set*(***);*** get*();}</option>                        <!-- 不混淆的SpringBoot类及其中的方法 -->                        <option>-keep class com.arm.code.mix.base.SpringBoot{ &lt;methods&gt;; }</option>                        <!-- 不混淆job包下的所有类名,且类中的方法也不混淆-->                        <!--<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.job.** { &lt;methods&gt;; }</option> -->                        <!-- 不混淆filter包下的所有类名,这里主要是对Shiro的路踢人过滤器混淆,对类的属性和方法进行了混淆-->                        <!--<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.filter.** </option> -->                        <!-- 不混淆model包中的所有类以及类的属性及方法,实体包,混淆了会导致ORM框架及前端无法识别-->                        <!--<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.model.** {*;}</option>-->                         <!-- com.test.prog.util, util包不混淆的类的属性及方法,实体包  -->                        <!--<option>-keep class com.test.prog.util.finals.Const{ *; }</option>-->                        <!-- 不混淆凭证包下的所有类名,但对类中的属性、方法进行混淆,原因是Spring配置中用到了这个类名-->                        <!--<option>-keep class com.test.prog.util.SecCode</option>-->                        <!--<option>-keep class com.test.prog.util.exception.HihSoftHandlerException</option>-->                        <!-- 不混淆job包下的所有类名,且类中的方法也不混淆-->                        <!--<option>-keep class com.test.prog.controller.** { &lt;methods&gt;; }</option>-->                    </options>                     <!-- 添加依赖,这里你可以按你的需要修改,这里测试只需要一个JRE的Runtime包就行了 -->                    <libs>                        <lib>${java.home}/lib/rt.jar</lib>                        <lib>${java.home}/lib/jce.jar</lib>                        <!--<lib>${java.home}/lib/security/local_policy.jar</lib>-->                        <!--<lib>${java.home}/lib/security/US_export_policy.jar</lib>-->                        <lib>${java.home}/lib/ext/sunjce_provider.jar</lib>                    </libs>                </configuration>

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

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

相关文章

超长圆钢在线直线度检测 告别手工测量时代

圆钢的直线度指的是它的表面形状是否呈现出直线。直线度是圆钢的重要品质要求之一&#xff0c;与其物理性能密切相关。在工业制造中&#xff0c;如果圆钢的直线度不达标&#xff0c;就会影响其后续的加工和使用效果&#xff0c;严重时甚至会造成损失。 超长圆钢的检测&#xff…

预包装食品备案与食品经营许可证两者的关系

在食品行业中&#xff0c;预包装食品备案和食品经营许可证是两个重要的概念。它们之间存在一定的关系&#xff0c;但又不完全相同。本文将详细介绍两者的定义、区别和联系。 一、预包装食品备案 预包装食品备案&#xff0c;是指对预包装食品的生产者或进口商进行备案登记的一种…

SpringDoc基础配置和集成OAuth2登录认证教程

本期内容 学会通过注解和Java代码的方式添加SpringDoc配置。在swagger-ui提供的页面上提供OAuth2登录认证&#xff0c;在集成Security的情况下便捷获取access_token并在请求时按照OAuth2规范携带。 为什么集成OAuth2登录认证&#xff1f; 现在大部分教程是在swagger-ui页面添…

远程数据采集继电器RTU如何应用在智能电动汽车充电桩

远程数据采集继电器&#xff08;Remote Terminal Unit&#xff0c;RTU&#xff09;在智能电动汽车充电桩中的应用&#xff0c;可以为充电桩系统提供更高效、安全和可靠的远程监控与控制功能。下面将详细说明RTU在智能电动汽车充电桩中的应用。 远程监控功能&#xff1a; RTU可以…

一份WhatsApp矩阵账号营销模式全解,有你不知道的玩法吗?

将WhatsApp营销践行到底&#xff0c;是傲途针对海外Social营销一直在做的事。在WhatsApp全球营销范围越来越广泛、营销模式越来越深入的当下&#xff0c;我们也在实践中积累了一套比较系统而全面的差异化矩阵营销模式&#xff0c;帮助大中小不同类型企业获得了有价值的结果。 …

前后端黄金组合:Django+Vue+Element UI,助你构建完美平台!

这是一篇什么文章&#xff1f; 一篇你对测试开发工作感兴趣&#xff0c;想了解系统工作逻辑的文章。 一篇是你在开始动手搭建环境前需要了解各工具原理的文章。 这是一篇你真正开始前需要查阅的文章。 本文介绍了前后端工作原理&#xff0c;前后端搭建的流程、搭建过程中需…

使用 Amazon VPS 探索存储选项:实用指南

文章作者&#xff1a;Libai 在这个数字化时代&#xff0c;云计算已经成为了企业的必需品&#xff0c;它为我们带来了可扩展性、灵活性和成本效益。作为一家领先的云服务提供商&#xff0c;亚马逊网络服务&#xff08;Amazon Web Services&#xff09;提供了各种各样的服务&…

当绿色积分合法化遇上消费增值,会擦出什么样的火花!

亲爱的消费者朋友们&#xff0c;你们好&#xff01;今天我要向你们揭示一种全新的消费理念——消费增值&#xff0c;让每一次消费都变得更有价值&#xff01; 在传统的消费观念中&#xff0c;我们仅仅用金钱购买物品或享受服务&#xff0c;然后这些物品和服务便从我们的生活中消…

高压功率放大器有什么作用和用途

高压功率放大器是一种专门用于放大高电压和高功率信号的电子器件&#xff0c;其主要作用是将输入信号放大到足够的范围内&#xff0c;以便后续电路进行进一步处理。在工业、医疗、军事等领域中&#xff0c;高压功率放大器有着广泛的应用。 下面介绍几个高压功率放大器的应用场景…

数据结构与算法之美学习笔记:23 | 二叉树基础(上):什么样的二叉树适合用数组来存储?

目录 前言树&#xff08;Tree&#xff09;二叉树&#xff08;Binary Tree&#xff09;二叉树的遍历解答开篇 & 内容小结 前言 本节课程思维导图&#xff1a; 前面我们讲的都是线性表结构&#xff0c;栈、队列、链表等等。今天我们讲一种非线性表结构&#xff0c;树。问题&…

el-table实现表格内嵌套表格

文章目录 一、效果图二、使用场景三、所用组件元素&#xff08;Elementui&#xff09;四、代码部分 一、效果图 二、使用场景 &#x1f6c0;el-form 表单内嵌套el-table表格 &#x1f6c0;el-table 表格内又嵌套el-table表格 三、所用组件元素&#xff08;Elementui&#xff…

滚珠螺杆在航天工业领域中的重要性

滚珠螺杆是重要的航天工业配件之一&#xff0c;在航天工业领域中具有非常重要的地位和作用。 首先&#xff0c;滚珠螺杆作为一种高精度、高刚度的传动元件&#xff0c;能够提供准确的传动和定位精度&#xff0c;从而保证航天器的可靠性和性能。航天器在飞行过程中需要精确控制其…

分形简单版

我的代码&#xff1a; #include<bits/stdc.h> using namespace std; const int N1000; int n; char s[N][N]; void work(int x) {if(x1) {s[0][0]*;return;}work(x-1);for(int i0;i<(1<<x-2);i)for(int j(1<<x-2);j<(1<<x-1);j) s[i][j]s[i][j-(…

网络工程师网络配置经典例题(二)

目录 1、access、trunk 2、配置终结子接口 3、DHCP接口地址池、DNS 4、静态默认路由、接口IP 5、ACL、NAT 使内网用户可以访问外网 6、VLANIF 某公司拥有多个部门且位于不同网段&#xff0c;各部门均有访问Internet的需求。现要求用户通过二层交换机和路由器访问外部网络…

由两个独立的高增益运算放大器组成的运放芯片D258,可应用于音频信号处理系统上

D258是由两个独立的高增益运算放大器组成。可以是单电源工作&#xff0c;也可以是双电源工作,电源的电流消耗与电源电压大小无关。应用范围包括变频放大器、DC增益部件和所有常规运算放大电路。 主要特点&#xff1a; ● 可单电源或双电源 工作 ● 在一个封装内的两个经…

TikTok Shop印尼站关闭给所有跨境卖家的警示(附止损解决方案)

01关店事件回顾 10月3日&#xff0c;印尼TikTok卖家迎来了他们的至暗时刻&#xff1a;官方邮件通知明确告知所有人&#xff0c;TikTok Shop于10月4日印尼西部时间17点正式关闭。 至此&#xff0c;TikTok在印尼成为不再拥有“电商功能”的短视频内容平台&#xff0c;所有人都可…

sql注入 [极客大挑战 2019]HardSQL1

打开题目 输入1或者1"&#xff0c;页面均回显NO,Wrong username password&#xff01;&#xff01;&#xff01; 那我们输入1 试试万能密码 1 or 11 # 输入1 and 12 # 输入1 union select 1,2,3 # 输入1 ununionion seselectlect 1,2,3 # 输入1 # 输入1# 页面依旧回…

虾皮台湾站点如何选品

在互联网时代&#xff0c;电商平台成为了越来越多人购物的首选。虾皮作为台湾地区最大的电商平台之一&#xff0c;为商家提供了良好的销售渠道。然而&#xff0c;在虾皮上选择适合的商品对于商家来说并不容易。本文将介绍如何通过虾皮选品工具-知虾来查看台湾地区各大类目的热销…

day30_servlet

今日内容 零、复习昨日 一、接收请求 二、处理响应 三、综合案例 零、复习昨日 画图, 请求处理的完整流程(javaweb开发流程) 零、注解改造 WebServlet注解,相当于是在web.xml中配置的servlet映射 Servlet类 package com.qf.servlet;import javax.servlet.ServletException; im…

移动端获取ua头的值

目录&#xff1a; 1、检测地址2、测试结果 1、检测地址 http://www.ip138.com/useragent/ 2、测试结果 成功的拿到了ua头的值了&#xff0c;亲测可行&#xff01;&#xff01;&#xff01;
最新文章