При значении complexity = 10, меняйте ******. CODE С# using Newtonsoft.Json.Linq; using Org.BouncyCastle.Crypto.Digests; using System; using System.IO; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; class Program { static void Main() { int port = 9091; HttpListener listener = new HttpListener(); listener.Prefixes.Add($"http://localhost:{port}/"); listener.Start(); Console.WriteLine("Сервер запущен. Ожидание запросов..."); while (true) { HttpListenerContext context = listener.GetContext(); Task.Run(() => ProcessRequest(context)); } } static void ProcessRequest(HttpListenerContext context) { if (context.Request.HttpMethod == "POST") { try { string json; using (StreamReader reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding)) { json = reader.ReadToEnd(); } int result = ComputePow(json); string responseJson = $"{{ \"result\": {result} }}"; byte[] responseData = Encoding.UTF8.GetBytes(responseJson); context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.ContentType = "application/json"; context.Response.ContentLength64 = responseData.Length; context.Response.OutputStream.Write(responseData, 0, responseData.Length); context.Response.OutputStream.Close(); } catch (Exception ex) { Console.WriteLine("Ошибка обработки запроса: " + ex.Message); context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; context.Response.Close(); } } else { context.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed; context.Response.Close(); } } static int ComputePow(string json) { int result = -1; JObject jsonObject = JObject.Parse(json); JObject powObject = jsonObject["pow"] as JObject; int version = powObject["algorithm"]["version"].Value<int>(); int complexity = powObject["complexity"].Value<int>(); string timestamp = powObject["timestamp"].Value<string>(); string resource = powObject["algorithm"]["resourse"].Value<string>(); string extension = powObject["algorithm"]["extension"].Value<string>(); string randomString = powObject["random_string"].Value<string>(); string var7 = $"{version}:{complexity}:{timestamp}:{resource}:{extension}:{randomString}:"; string zeroQuantity = new string('0', complexity); for (int i = 1; i <= 1000000; i++) { string var10 = $"{var7}{i}"; byte[] bytes = Encoding.UTF8.GetBytes(var10); var keccakHash = new KeccakDigest(512); keccakHash.BlockUpdate(bytes, 0, bytes.Length); byte[] hashBytes = new byte[keccakHash.GetDigestSize()]; keccakHash.DoFinal(hashBytes, 0); string var12 = BitConverter.ToString(hashBytes).Replace("-", ""); bool check = var12.StartsWith(zeroQuantity); if (check) { return i; } } return -1; } } } CSHARP using Newtonsoft.Json.Linq; using Org.BouncyCastle.Crypto.Digests; using System; using System.IO; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; class Program { static void Main() { int port = 9091; HttpListener listener = new HttpListener(); listener.Prefixes.Add($"http://localhost:{port}/"); listener.Start(); Console.WriteLine("Сервер запущен. Ожидание запросов..."); while (true) { HttpListenerContext context = listener.GetContext(); Task.Run(() => ProcessRequest(context)); } } static void ProcessRequest(HttpListenerContext context) { if (context.Request.HttpMethod == "POST") { try { string json; using (StreamReader reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding)) { json = reader.ReadToEnd(); } int result = ComputePow(json); string responseJson = $"{{ \"result\": {result} }}"; byte[] responseData = Encoding.UTF8.GetBytes(responseJson); context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.ContentType = "application/json"; context.Response.ContentLength64 = responseData.Length; context.Response.OutputStream.Write(responseData, 0, responseData.Length); context.Response.OutputStream.Close(); } catch (Exception ex) { Console.WriteLine("Ошибка обработки запроса: " + ex.Message); context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; context.Response.Close(); } } else { context.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed; context.Response.Close(); } } static int ComputePow(string json) { int result = -1; JObject jsonObject = JObject.Parse(json); JObject powObject = jsonObject["pow"] as JObject; int version = powObject["algorithm"]["version"].Value<int>(); int complexity = powObject["complexity"].Value<int>(); string timestamp = powObject["timestamp"].Value<string>(); string resource = powObject["algorithm"]["resourse"].Value<string>(); string extension = powObject["algorithm"]["extension"].Value<string>(); string randomString = powObject["random_string"].Value<string>(); string var7 = $"{version}:{complexity}:{timestamp}:{resource}:{extension}:{randomString}:"; string zeroQuantity = new string('0', complexity); for (int i = 1; i <= 1000000; i++) { string var10 = $"{var7}{i}"; byte[] bytes = Encoding.UTF8.GetBytes(var10); var keccakHash = new KeccakDigest(512); keccakHash.BlockUpdate(bytes, 0, bytes.Length); byte[] hashBytes = new byte[keccakHash.GetDigestSize()]; keccakHash.DoFinal(hashBytes, 0); string var12 = BitConverter.ToString(hashBytes).Replace("-", ""); bool check = var12.StartsWith(zeroQuantity); if (check) { return i; } } return -1; } } } CODE GO package main import ( "bufio" "encoding/hex" "encoding/json" "fmt" "golang.org/x/crypto/sha3" "io/ioutil" "net" "net/http" "strings" ) func main() { port := 9091 listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) if err != nil { fmt.Printf("Ошибка запуска сервера: %s\n", err.Error()) return } fmt.Println("Сервер запущен. Ожидание запросов...") for { conn, err := listener.Accept() if err != nil { fmt.Printf("Ошибка при принятии соединения: %s\n", err.Error()) continue } go processRequest(conn) } } func processRequest(conn net.Conn) { defer conn.Close() request, err := http.ReadRequest(bufio.NewReader(conn)) if err != nil { fmt.Printf("Ошибка чтения запроса: %s\n", err.Error()) return } if request.Method == "POST" { body, err := ioutil.ReadAll(request.Body) if err != nil { fmt.Printf("Ошибка чтения тела запроса: %s\n", err.Error()) sendErrorResponse(conn, http.StatusInternalServerError) return } var jsonRequest map[string]interface{} err = json.Unmarshal(body, &jsonRequest) if err != nil { fmt.Printf("Ошибка разбора JSON: %s\n", err.Error()) sendErrorResponse(conn, http.StatusBadRequest) return } result := computePow(jsonRequest) response := map[string]interface{}{ "result": result, } responseData, err := json.Marshal(response) if err != nil { fmt.Printf("Ошибка формирования ответа: %s\n", err.Error()) sendErrorResponse(conn, http.StatusInternalServerError) return } sendResponse(conn, http.StatusOK, responseData, "application/json") } else { sendErrorResponse(conn, http.StatusMethodNotAllowed) } } func sendResponse(conn net.Conn, statusCode int, data []byte, contentType string) { response := fmt.Sprintf("HTTP/1.1 %d %s\r\n"+ "Content-Type: %s\r\n"+ "Content-Length: %d\r\n"+ "\r\n"+ "%s", statusCode, http.StatusText(statusCode), contentType, len(data), data) _, err := conn.Write([]byte(response)) if err != nil { fmt.Printf("Ошибка отправки ответа: %s\n", err.Error()) } } func sendErrorResponse(conn net.Conn, statusCode int) { response := fmt.Sprintf("HTTP/1.1 %d %s\r\n"+ "\r\n", statusCode, http.StatusText(statusCode)) _, err := conn.Write([]byte(response)) if err != nil { fmt.Printf("Ошибка отправки ответа: %s\n", err.Error()) } } func computePow(jsonRequest map[string]interface{}) int { powObject, ok := jsonRequest["pow"].(map[string]interface{}) if !ok { return -1 } version := int(powObject["algorithm"].(map[string]interface{})["version"].(float64)) complexity := int(powObject["complexity"].(float64)) timestamp := fmt.Sprintf("%d", int64(powObject["timestamp"].(float64))) resource := powObject["algorithm"].(map[string]interface{})["resourse"].(string) extension := powObject["algorithm"].(map[string]interface{})["extension"].(string) randomString := powObject["random_string"].(string) var7 := fmt.Sprintf("%d:%d:%s:%s:%s:%s:", version, complexity, timestamp, resource, extension, randomString) zeroQuantity := strings.Repeat("0", complexity) for i := 1; i <= 1000000; i++ { var10 := fmt.Sprintf("%s%d", var7, i) bytes := []byte(var10) keccakHash := sha3.NewLegacyKeccak512() keccakHash.Write(bytes) hashBytes := keccakHash.Sum(nil) var12 := hex.EncodeToString(hashBytes) check := strings.HasPrefix(var12, zeroQuantity) if check { return i } } return -1 } Код package main import ( "bufio" "encoding/hex" "encoding/json" "fmt" "golang.org/x/crypto/sha3" "io/ioutil" "net" "net/http" "strings" ) func main() { port := 9091 listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) if err != nil { fmt.Printf("Ошибка запуска сервера: %s\n", err.Error()) return } fmt.Println("Сервер запущен. Ожидание запросов...") for { conn, err := listener.Accept() if err != nil { fmt.Printf("Ошибка при принятии соединения: %s\n", err.Error()) continue } go processRequest(conn) } } func processRequest(conn net.Conn) { defer conn.Close() request, err := http.ReadRequest(bufio.NewReader(conn)) if err != nil { fmt.Printf("Ошибка чтения запроса: %s\n", err.Error()) return } if request.Method == "POST" { body, err := ioutil.ReadAll(request.Body) if err != nil { fmt.Printf("Ошибка чтения тела запроса: %s\n", err.Error()) sendErrorResponse(conn, http.StatusInternalServerError) return } var jsonRequest map[string]interface{} err = json.Unmarshal(body, &jsonRequest) if err != nil { fmt.Printf("Ошибка разбора JSON: %s\n", err.Error()) sendErrorResponse(conn, http.StatusBadRequest) return } result := computePow(jsonRequest) response := map[string]interface{}{ "result": result, } responseData, err := json.Marshal(response) if err != nil { fmt.Printf("Ошибка формирования ответа: %s\n", err.Error()) sendErrorResponse(conn, http.StatusInternalServerError) return } sendResponse(conn, http.StatusOK, responseData, "application/json") } else { sendErrorResponse(conn, http.StatusMethodNotAllowed) } } func sendResponse(conn net.Conn, statusCode int, data []byte, contentType string) { response := fmt.Sprintf("HTTP/1.1 %d %s\r\n"+ "Content-Type: %s\r\n"+ "Content-Length: %d\r\n"+ "\r\n"+ "%s", statusCode, http.StatusText(statusCode), contentType, len(data), data) _, err := conn.Write([]byte(response)) if err != nil { fmt.Printf("Ошибка отправки ответа: %s\n", err.Error()) } } func sendErrorResponse(conn net.Conn, statusCode int) { response := fmt.Sprintf("HTTP/1.1 %d %s\r\n"+ "\r\n", statusCode, http.StatusText(statusCode)) _, err := conn.Write([]byte(response)) if err != nil { fmt.Printf("Ошибка отправки ответа: %s\n", err.Error()) } } func computePow(jsonRequest map[string]interface{}) int { powObject, ok := jsonRequest["pow"].(map[string]interface{}) if !ok { return -1 } version := int(powObject["algorithm"].(map[string]interface{})["version"].(float64)) complexity := int(powObject["complexity"].(float64)) timestamp := fmt.Sprintf("%d", int64(powObject["timestamp"].(float64))) resource := powObject["algorithm"].(map[string]interface{})["resourse"].(string) extension := powObject["algorithm"].(map[string]interface{})["extension"].(string) randomString := powObject["random_string"].(string) var7 := fmt.Sprintf("%d:%d:%s:%s:%s:%s:", version, complexity, timestamp, resource, extension, randomString) zeroQuantity := strings.Repeat("0", complexity) for i := 1; i <= 1000000; i++ { var10 := fmt.Sprintf("%s%d", var7, i) bytes := []byte(var10) keccakHash := sha3.NewLegacyKeccak512() keccakHash.Write(bytes) hashBytes := keccakHash.Sum(nil) var12 := hex.EncodeToString(hashBytes) check := strings.HasPrefix(var12, zeroQuantity) if check { return i } } return -1 } Перформанс C# vs Golang c# go Нагрузка - 10 запросов в секунду. Как видим на скринах по потреблению CPU(ru banword) выигрывает Go.
bibidzhon, спасибо за код. Я вижу, что это реализация алгоритма Proof of Work (PoW) на языке C#. Как я понимаю, переменная `complexity` отвечает за сложность задачи PoW. Если её значение равно 10, то для нахождения решения нужно найти хэш, начинающийся с 10 нулей. Вы советуете менять ****** при данной сложности. Почему это необходимо?
bibidzhon, любые cpu-intensive задачи должны выполняться нативно, без всяких слюнявых промежуточных языков, иначе появляется оверхед
C_Sharp, он лучше знает, кого ему слушать, а кого нет. касаемо твоей аналогии - она мне не ясна. разумеется, при небольших объемах разница будет несущественной, но аппетиты имеют свойство расти
Тема поднята кнопкой. Добавил сервер на Go Обновил код для сервера на c# Добавил пункт с сравнением перформанса go и c# endpoint localhost:9091/pow