Digest Auth 摘要认证

2023-05-16

Digest Auth 摘要认证

1.非常规方式

转载:https://blog.csdn.net/qq_25391785/article/details/86595529

    public static void postMethod(String url, String query) {
        try {

            CredentialsProvider credsProvider = new BasicCredentialsProvider();
            credsProvider.setCredentials(
                    new AuthScope("xx.xx.xx.xx", 80),//请求地址 + 端口号
                    new UsernamePasswordCredentials("xx", "xxxx"));// 用户名 + 密码 (用于验证)
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setDefaultCredentialsProvider(credsProvider)
                    .build();
            HttpPost postMethod = new HttpPost(url);//请求详细地址(如:http://192.168.1.105:9000/MotorVehicles)
            StringEntity s = new StringEntity(query);//向后台传的json数据
            s.setContentEncoding("utf-8");//编码
            s.setContentType("application/json");//发送json数据需要设置contentType
            postMethod.setEntity(s);
            HttpResponse response = httpclient.execute(postMethod); //执行POST方法

            System.out.println("resCode = " + response.getStatusLine().getStatusCode()); //获取响应码

            System.out.println("result = " + EntityUtils.toString(response.getEntity(), "utf-8")); //获取响应内容

        } catch (Exception e) {
            System.out.println("推送失败:"+e);
        }

    }

2.常规认证方式

在这里插入图片描述
1.发送一个请求

    GET /auth/basic/ HTTP/1.1
    HOST: target

2.服务器返回401响应头,要求输入用户凭据

    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: Digest realm="Digest Encrypt",nonce="nmeEHKLeBAA=aa6ac7ab3cae8f1b73b04e1e3048179777a174b3", opaque="0000000000000000",stale=false, algorithm=MD5, qop="auth"

3.输入凭据后再发送请求

    GET /auth/digest/ HTTP/1.1
    Accept: */*
    Authorization:  Digest username="LengWa", realm="Digest Encrypt",  qop="auth", algorithm="MD5", uri="/auth/digest/", nonce="nmeEHKLeBAA=aa6ac7ab3cae8f1b73b04e1e3048179777a174b3", nc=00000001, cnonce="6092d3a53e37bb44b3a6e0159974108b", opaque="0000000000000000", response="652b2f336aeb085d8dd9d887848c3314"

4.服务端验证通过后返回数据

代码工具类(本人的实际服务因第二次传的凭据不返回realm参数,遂在代码里将其写死):


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.asiainfo.req.DigestAuthReq;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Http Digest Request contains POST、GET、PUT
 * @author zhangdan
 * @date 2021-04-22
 */
@Slf4j
public class HttpRequestUtils {

    private static final Logger logger = LoggerFactory.getLogger(HttpRequestUtils.class);

    public static void main(String[] args) {

//        String param = "";
//        String username = "xxxx";
//        String password = "xxxx";


        postMethod("http://ip:80/api/howell/ver10/aiop_service/garbage_management/GarbageStations/Cameras/List","{\n" +
                "    \"PageIndex\":\"1\",\n" +
                "    \"PageSize\":\"99999\"\n" +
                "}");
        //System.out.println(s);
    }

    static int nc = 0;    //调用次数
    private static final String GET = "GET";
    private static final String POST = "POST";
    private static final String PUT = "PUT";
    private static final String DELETE = "DELETE";




    /**
     * 向指定URL发送POST方法的请求
     * @param url                                       发送请求的URL
     * @param param                                     请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @param username                                  验证所需的用户名
     * @param password                                  验证所需的密码
     * @param json                                      请求json字符串
     * @param type                                      返回xml和json格式数据,默认xml,传入json返回json数据
     * @return URL 所代表远程资源的响应结果
     */
    public  static String sendPost(DigestAuthReq digestAuthReq) {
        StringBuilder result = new StringBuilder();
            String json= digestAuthReq.getJsonStr();
            String url= digestAuthReq.getUrl();
            String param= digestAuthReq.getParam();
            String username=digestAuthReq.getUsername();
            String password=digestAuthReq.getPassword();
            String type= digestAuthReq.getType();
            logger.info("json============="+json);
            BufferedReader in = null;
            try {
                //String wwwAuth = sendGet(url, param);       //发起一次授权请求
                String wwwAuth=sendPost(url, param);
                if (wwwAuth.startsWith("WWW-Authenticate:")) {
                    wwwAuth = wwwAuth.replaceFirst("WWW-Authenticate:", "");
                } else {
                    return wwwAuth;
                }
                nc ++;
                String urlNameString = url + (StringUtils.isNotEmpty(param) ? "?" + param : "");
                URL realUrl = new URL(urlNameString);
                // 打开和URL之间的连接
                HttpURLConnection connection = (HttpURLConnection)realUrl.openConnection();

                // 设置是否向connection输出,因为这个是post请求,参数要放在
                // http正文内,因此需要设为true
                connection.setDoOutput(true);
                // Read from the connection. Defaultis true.
                connection.setDoInput(true);
                // 默认是 GET方式
                connection.setRequestMethod(POST);
                // Post 请求不能使用缓存
                connection.setUseCaches(false);

                // 设置通用的请求属性
                setRequestProperty(connection, wwwAuth,realUrl, username, password, POST, type);

                if (!StringUtils.isEmpty(json)) {
                    byte[] writebytes =json.getBytes();
                    connection.setRequestProperty("Content-Length",String.valueOf(writebytes.length));
                    OutputStream outwritestream = connection.getOutputStream();
                    outwritestream.write(json.getBytes());
                    outwritestream.flush();
                    outwritestream.close();
                }
                if (connection.getResponseCode() == 200 || connection.getResponseCode() == 201) {
                    in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String line;
                    while ((line = in.readLine()) != null) {
                        result.append(line);
                    }
                } else {
                    String errResult = formatResultInfo(connection, type);
                    logger.info(errResult);
                    return errResult;
                }

                nc = 0;
            } catch (Exception e) {
                nc = 0;
                throw new RuntimeException(e);
            } finally {
                try {
                    if (in != null) in.close();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }


        return result.toString();
    }


    /**
     * 向指定URL发送GET方法的请求
     * @param url                                       发送请求的URL
     * @param param                                     请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @param username                                  验证所需的用户名
     * @param password                                  验证所需的密码
     * @param type                                      返回xml和json格式数据,默认xml,传入json返回json数据
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param, String username, String password, String type) {

        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        try {
            String wwwAuth = sendGet(url, param);       //发起一次授权请求
            if (wwwAuth.startsWith("WWW-Authenticate:")) {
                wwwAuth = wwwAuth.replaceFirst("WWW-Authenticate:", "");
            } else {
                return wwwAuth;
            }
            nc ++;
            String urlNameString = url + (StringUtils.isNotEmpty(param) ? "?" + param : "");
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection)realUrl.openConnection();
            // 设置通用的请求属性
            setRequestProperty(connection, wwwAuth,realUrl, username, password, GET, type);
            // 建立实际的连接
            // connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            nc = 0;
        } catch (Exception e) {
            nc = 0;
            throw new RuntimeException(e);
        } finally {
            try {
                if (in != null) in.close();
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result.toString();
    }

    /**
     * 生成授权信息
     * @param authorization                             上一次调用返回401的WWW-Authenticate数据
     * @param username                                  用户名
     * @param password                                  密码
     * @return                                          授权后的数据, 应放在http头的Authorization里
     * @throws IOException                              异常
     */
    private static String getAuthorization(String authorization, String uri, String username, String password, String method) throws IOException {

        uri = StringUtils.isEmpty(uri) ? "/" : uri;
        String temp = authorization.replaceFirst("Digest", "").trim().replace("MD5","\"MD5\"").replace("realm=\"\"","realm=\"/howell/ver10/data\"");
        String json = withdrawJson(authorization);

        JSONObject jsonObject = JSON.parseObject(json);
        String cnonce = Digests.generateSalt2(8);
        String ncstr = ("00000000" + nc).substring(Integer.toString(nc).length());     //认证的次数,第一次是1,第二次是2...
        String algorithm = jsonObject.getString("algorithm");
        String qop = jsonObject.getString("qop");
        String nonce = jsonObject.getString("nonce");
        String realm = jsonObject.getString("realm");
        if(StringUtils.isEmpty(realm)){
            realm="/howell/ver10/data";
        }

        String response = Digests.http_da_calc_HA1(username, realm, password,
                nonce, ncstr, cnonce, qop,
                method, uri, algorithm);

        //组成响应authorization
        authorization = "Digest username=\"" + username + "\"," + temp;
        authorization += ",uri=\"" + uri
                + "\",nc=\"" + ncstr
                + "\",cnonce=\"" + cnonce
                + "\",response=\"" + response+"\"";
        return authorization;
    }

    /**
     * 将返回的Authrization信息转成json
     * @param authorization                                     authorization info
     * @return                                                  返回authrization json格式数据 如:String json = "{ \"realm\": \"Wowza\", \" domain\": \"/\", \" nonce\": \"MTU1NzgxMTU1NzQ4MDo2NzI3MWYxZTZkYjBiMjQ2ZGRjYTQ3ZjNiOTM2YjJjZA==\", \" algorithm\": \"MD5\", \" qop\": \"auth\" }";
     */
    private static String withdrawJson(String authorization) {
        String temp = authorization.replaceFirst("Digest", "").trim().replaceAll("\"","");
        String[] split = temp.split(",");
        Map<String, String> map = new HashMap<>();
        Arrays.asList(split).forEach(c -> {
            String c1 = c.replaceFirst("=",":");
            String[] split1 = c1.split(":");
            if(split1[0].trim().equals("realm")){
                map.put(split1[0].trim(), "/howell/ver10/data");
            }else{
                map.put(split1[0].trim(), split1[1].trim());
            }

        });
        return JSONObject.toJSONString(map);
    }

    /**
     * 向指定URL发送GET方法的请求
     * @param url                                                   发送请求的URL
     * @param param                                                 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL                                                  所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        try {

            String urlNameString = url + (StringUtils.isNotEmpty(param) ? "?" + param : "");
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

            connection.connect();

            //返回401时需再次用用户名和密码请求
            //此情况返回服务器的 WWW-Authenticate 信息
            if (((HttpURLConnection) connection).getResponseCode() == 401) {
                Map<String, List<String>> map = connection.getHeaderFields();
                return "WWW-Authenticate:" + map.get("WWW-Authenticate").get(0);
            }

            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) {
            throw new RuntimeException("get请求发送失败",e);
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                System.out.println(result.toString());
                if (in != null) in.close();
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        System.out.println(result.toString());
        logger.info(result.toString());
        return result.toString();

    }


    /**
     * 向指定URL发送GET方法的请求
     * @param url                                                   发送请求的URL
     * @param param                                                 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL                                                  所代表远程资源的响应结果
     */
    public static String sendPost(String url, String parameters ) {
        String result = "";
        BufferedReader in = null;
        try {
            String ip = "124.71.147.146";
            Integer port = 80;
            String username="wujiaochang";
            String password="3EhcqnbnZ4QFJ9sk";
            int resCode = 404;
            CredentialsProvider credsProvider = new BasicCredentialsProvider();
            credsProvider.setCredentials(new AuthScope(ip, port), // 请求地址 + 端口号
                    new UsernamePasswordCredentials(username, password));// 用户名 + 密码 (用于验证)
            HttpClient httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
            try {
                SSLContext sslContext = SSLContextBuilder.create().useProtocol(SSLConnectionSocketFactory.SSL).loadTrustMaterial((x, y) -> true).build();
                RequestConfig config = RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(5000).build();
                httpclient = HttpClientBuilder.create().setDefaultRequestConfig(config).setSSLContext(sslContext).setSSLHostnameVerifier((x, y) -> true).build();
            } catch (Exception e) {
                e.printStackTrace();
            }
            HttpPost postMethod = new HttpPost(url);// 请求详细地址(如:http://192.168.1.105:9000/MotorVehicles)
            //根据不通要求自己添加头
            //根据不通要求自己添加头
            postMethod.addHeader("Content-Type", "application/json");
            postMethod.addHeader("accept", "*/*");
            postMethod.addHeader("connection", "Keep-Alive");
            postMethod.addHeader("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

            StringEntity s = new StringEntity(JSON.toJSONString(parameters));// 向后台传的json数据
            s.setContentEncoding("utf-8");// 编码
            postMethod.setEntity(s);
            HttpResponse response = httpclient.execute(postMethod); // 执行POST方法
            resCode = response.getStatusLine().getStatusCode();
            System.out.println("resCode = " + resCode); // 获取响应码
            result = EntityUtils.toString(response.getEntity(), "utf-8");
            log.info("result = " + result); // 获取响应内容

            if (resCode == 401) {
                return  "" +response.getHeaders("WWW-Authenticate")[0];
            }
        }
        // 使用finally块来关闭输入流
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(result.toString());
        logger.info(result.toString());
        return result.toString();

    }
    /**
     * HTTP set request property
     *
     * @param connection                            HttpConnection
     * @param wwwAuth                               授权auth
     * @param realUrl                               实际url
     * @param username                              验证所需的用户名
     * @param password                              验证所需的密码
     * @param method                                请求方式
     * @param type                                  返回xml和json格式数据,默认xml,传入json返回json数据
     */
    private static void setRequestProperty(HttpURLConnection connection, String wwwAuth, URL realUrl, String username, String password, String method, String type)
            throws IOException {

        if (type != null && type.equals("json")) {
            // 返回json
            connection.setRequestProperty("X-Webbrowser-Authentication","Forbidden");
            connection.setRequestProperty("accept", "application/json;charset=UTF-8");
            connection.setRequestProperty("Content-Type","application/json;charset=UTF-8");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
        } else {
            // 返回xml
            if (!method.equals(GET)) {
                connection.setRequestProperty("X-Webbrowser-Authentication","Forbidden");
                connection.setRequestProperty("Content-Type","application/json;charset=UTF-8");
            }
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            // connection.setRequestProperty("Cache-Control", "no-cache");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

        }
        //授权信息
        String authentication = getAuthorization(wwwAuth, realUrl.getPath(), username, password, method);
        connection.setRequestProperty("Authorization", authentication);
    }

    /**
     * 格式化请求返回信息,支持json和xml格式
     * @param connection                                HttpConnection
     * @param type                                      指定返回数据格式,json、xml,默认xml
     * @return                                          返回数据
     */
    private static String formatResultInfo(HttpURLConnection connection, String type) throws IOException {
        String result = "";
        if (type != null && type.equals("json")) {
            result = String.format("{\"errCode\":%s, \"message\":%s}",connection.getResponseCode(),connection.getResponseMessage());
        } else {
            result = String.format(" <?xml version=\"1.0\" encoding=\"UTF-8\" ?> "
                    + " <wmsResponse>"
                    + " <errCode>%d</errCode>"
                    + " <message>%s</message>"
                    + " </wmsResponse>",connection.getResponseCode(),connection.getResponseMessage());
        }
        return result;
    }



}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Digest Auth 摘要认证 的相关文章

  • http请求digest auth认证

    1 post请求 public static String postMethod String url String query String host throws IOException String content 61 null 认
  • 以摘要认证(Digest Authentication)方式伪登录某摄像头

    本文部分摘自ASP NET Web API xff08 三 xff09 xff1a 安全验证之使用摘要认证 digest authentication 密码已知 分析发现 xff0c 该摄像头Web登录采用了Digest Authentic
  • Http auth认证的两种方式Basic方式和 Digest认证

    Http Basic Auth 方式 当访问一个Http Basic Auth 网站的时候需要提供用户名 xff0c 密码 xff0c 否则会返回401 without authoration Http Basic Authenticati
  • curl base auth验证

    文章目录 场景分析解决 场景 发送一个需要进行base auth 验证请求 分析 curl CURLOPT USERPWD 设置一个链接中的密码 xff0c 用户名参考链接 解决 curl CURLOPT USERPWD 下面是一个案列 c
  • HTTP AUTH 那些事

    谨以此文献给那些需要实现HTTP AUTH的 程序猿 们 关于HTTP AUTH的文档不多 RFC在 http www ietf org rfc rfc2617 txt wiki在 http en wikipedia org wiki Ba
  • php curl http digest

    php用curl访问有http digest验证的网址时 xff0c 不能直接加在URL上 xff0c 例如 xff1a http user pass 64 xxx xxx xxx xxx index php a 61 1 amp b 61
  • java httpClient Digest Auth 认证

    技术交流QQ群 933925017 java httpClient Digest Auth 认证 因为项目需要 请求海康摄像头 进行抓图以及云台控制等功能 海康有http协议 但是需要进行请求头认证 因为海康给的资料已经过时 所以找了很久
  • Springboot整合摘要式(Digest)身份认证

    百度下来关于springboot整合摘要式省份认证的帖子基本都是说原理的 xff0c 很少有直接的demo xff0c 前些天找到了一个博主写的demo xff0c 但是我只是截图了忘记了博主的地址很抱歉了 下面直接上代码截图 xff1a
  • php getdigest,http digest

    HTTP digest 摘要访问认证是一种协议规定的Web服务器用来同网页浏览器进行认证信息协商的方法 它在密码发出前 xff0c 先对其应用哈希函数 xff0c 这相对于HTTP基本认证发送明文而言 xff0c 更安全 从技术上讲 xff
  • java怎么跟isapi摘要认证

    Java中可以使用HttpClient库来实现HTTP摘要认证 xff0c 而ISAPI扩展需要配置IIS服务器来支持摘要认证 在Java中使用HttpClient库进行HTTP请求时 xff0c 可以通过以下步骤来实现摘要认证 xff1a
  • C# HttpClient Digest 摘要认证 Cookie设置

    C HttpClient Digest 摘要认证 Cookie设置 1 创建凭证信息集 2 创建HttpClientHandler 3 创建HttpClient 4 发生请求 span class token comment 创建凭证信息集
  • Digest Auth 摘要认证

    Digest Auth 摘要认证 1 非常规方式 转载 xff1a https blog csdn net qq 25391785 article details 86595529 public static void postMethod
  • AUTH:basic认证和digest认证

    Http authentication BASIC In the context of an HTTP transaction basic access authentication is a method for a web browse
  • Digest来验证

    Apache默认使用basic模块验证 xff0c 但它只是明文验证 Digest验证 xff0c 是用md5摘要值进行对比 httpRequest getAuthType 方法 xff0c 可以得到网页的验证方式request BASIC
  • HTTPClient调用https请求,通过基本认证用户名密码(Basic Auth)

    本文来源是Apache官网例子 xff1a httpcomponents client ClientAuthentication java at 4 5 x apache httpcomponents client GitHub 之前找过很
  • 【SpringSecurity教程】认证 2.Digest摘要认证

    前言 Digest xff08 摘要 xff09 认证是在请求接口之前要输入账号密码 xff0c 是在Basic认证传输账号密码的基础上加密 SpringBoot整合Digest pom xml span class token tag s
  • 摘要认证,使用HttpClient实现HTTP digest authentication

    文章目录 前言一 四个过程二 过程细节三 HttpClient 代码示例 前言 今天工作需要做了摘要认证 xff08 digest authentication xff09 xff0c 下面就工作中遇到的问题及过程做一个总结 一 四个过程
  • 我可以序列化 ruby​​ Digest::SHA1 实例对象吗?

    大家好 我正在 ruby sinatra 中重新实现现有的自定义文件上传服务 并使用 redis 作为后备存储 客户 计算 SHA1 哈希并启动上传 上传最多 64K 块直至完成 服务器 将块附加到文件 计算完整文件的 SHA1 哈希值以验
  • 如何计算文本的真实SHA1?

    As in 我的最后一个问题 https stackoverflow com q 48327289 287948 参见那里的详细信息 我正在使用 SELECT encode digest x text bytea sha1 hex FROM
  • 使用 Java 的 Apache Http 摘要身份验证

    我目前正在开发一个 Java 项目 但无法使 http 摘要身份验证正常工作 我尝试使用 Apache 网站 但没有帮助 我有一个需要 HTTP 摘要身份验证的网站 DefaultHttpClient httpclient new Defa

随机推荐

  • C知识点整合

    C语言总结 一 语法 1 常见的数据内置类型所占字节 xff08 64 位下 xff09 xff1a char 1 int 4 float 4 long 4 double 8 Longlong 8 2 变量 xff1a xff08 1 xf
  • 判断一棵二叉树是否为完全二叉树

    1 完全二叉树的特点 xff08 来自专业定义 xff09 看到上面完全二叉树的特点 xff0c 我可以将其特点按照自己的 理解归纳为以下几点 xff1a xff08 1 xff1a 若二叉树最下面一层有节点出现 xff0c 那么这个节点一
  • 深入理解JNI技术

    一 JNI是什么 xff1f JNI是Java Native Interface的缩写 xff0c 译为Java本地调用 JNI是一种技术 二 JNI技术的用途 xff1f Java程序中的函数调用Native程序中的函数 Native一般
  • HTTP基本认证(Basic Authentication)

    在浏览网页时候 xff0c 浏览器会弹出一个登录验证的对话框 xff0c 如下图 xff0c 这就是使用HTTP基本认证 1 客户端发送http request 给服务器 服务器验证该用户是否已经登录验证过了 xff0c 如果没有的话 xf
  • 将字符串以单词为单位逆序"I am a Student" 解法

    网上有个题目 xff0c 将字符串以单词为单位逆序 例如 34 I am a Student 34 要变成 34 Student a am I 34 解法大致为 xff1a 先将字符串整体逆序第一个字符和最后一个交换 xff0c 第二个与倒
  • 堆排序查找前N个最大数和二分查找算法

    先了解堆排序概念 堆排序利用了大根堆 xff08 或小根堆 xff09 堆顶记录的关键字最大 xff08 或最小 xff09 这一特征 xff0c 使得在当前无序区中选取最大 xff08 或最小 xff09 关键字的记录变得简单 xff08
  • 构建hash表和两种处理冲突方法

    hash表定义 hashing定义了一种将字符组成的字符串转换为固定长度 xff08 一般是更短长度 xff09 的数值或索引值的方法 xff0c 称为散列法 xff0c 也叫哈希法 由于通过更短的哈希值比用原始值进行数据库搜索更快 xff
  • 用hash_map统计出现次数最多的前N个URL

    海量数据统计频率最高词汇的常规办法之一是先通过一个hash函数处理数据然后取模N xff0c 拆分为N个小文件 xff0c 对每一个小文件进行词频统计和排序处理 xff0c 然后归并N个小文件取频率最大的M个数 下面程序是利用hash ma
  • C++与java语法的异同整理

    文章目录 Java与C 43 43 与基础语法异同java的认知 amp java与C 43 43 的异同C 43 43 中的虚函数和JAVA中的抽象方法区别C 43 43 虚函数与JAVA中抽象函数比较关于接口与抽象类 xff1a Jav
  • 微信公众平台-股票行情查询

    微信公众平台 股票行情查询 php实现的获取上证 xff0c 深证 A B股实时行情的接口 xff0c 只实现了文本消息回复 xff0c K线图可以在图文消息中加上接口url地址就可以显示 xff0c 具体的接口地址网上可以找 xff0c
  • PELCO-D与PELCO-P协议介绍

    一般控制协议都由硬件或软件商编制在程序里面 xff0c 我们只需要通过相关的控制设备来进行操作 但是作为一个从事监控行业的技术人员 xff0c 往往会遇到除了电脑和协议转换器以外根本没有任何控制设备的情况 xff0c 此时 xff0c 协议
  • ROS 问题(topic types do not match、topic datatype/md5sum not match、msg xxx have changed. rerun cmake)

    1 topic types 不匹配 使用 roslaunch 命令 roslaunch carla ros bridge carla ros bridge with example ego vehicle launch 启动官方 demo
  • Ubuntu中查看安装的Python版本以及不同版本之间切换

    查看系统中已安装的所有Python版本 使用 ls 命令来查看你的系统中都有那些 Python 的二进制文件可供使用 xiyou 64 span class token property xiyou virtual machine span
  • Ubuntu Python 多版本安装

    概述 由于 Python 3 有几次较为跳跃的更新 xff0c 导致大量使用 Python 3 作为开发工具的软件会对 Python 3 的版本进行严格限制 xff0c 如限制使用 Python 3 8 Python 3 9 版本 这要求开
  • 怒爬某 Hub 资源就为撸了一个鉴黄平台

    来源 xff1a 码匠笔记公号 黄色已经是我们所不容然而却防不胜防的 xff0c 尤其是对于做内容的工具和平台 xff0c 所以花了30分钟搭建了一个鉴黄平台 xff0c 分享给大家 数据准备 找了 N 多资源都不能解决问题 xff0c 于
  • ROSERROR : datatype/md5sum

    出错原因是 xff1a 自定义消息 xff0c 发送话题的消息类型和接受话题的消息类型不一样 但是我的代码真的是一样的 所以 xff0c 解决办法是 xff1a 清空工作空间的build devel文件夹 xff0c 重新编译运行 成功 x
  • 学习使用 ArUco 标记

    在本文中 xff0c 我们将研究使用 Python 和 OpenCV 检测和估计 ArUco 标记的方向 首先 xff0c 我们将从生成 ArUco 标记开始 你可以使用特定网站一个一个地创建单个标签 xff0c 也可以使用我的程序生成整个
  • TCP协议中的序列号

    TCP 协议工作在OSI的传输层 xff0c 是一种可靠的面向连接的数据流协议 xff0c TCP之所以可靠 xff0c 是因为它保证了传送数据包的顺序 顺序是用一个序列号来保证的 响应包内也包括一个序列号 xff0c 表示接收方准备好这个
  • c++开发过程中遇到的问题及解决方案

    xfeff xfeff 问题一 xff1a 1 gt JForm obj error LNK2019 无法解析的外部符号 34 public virtual thiscall JFC JForm JForm void 34 1JForm 6
  • Digest Auth 摘要认证

    Digest Auth 摘要认证 1 非常规方式 转载 xff1a https blog csdn net qq 25391785 article details 86595529 public static void postMethod