import { createHash , randomBytes } from "crypto" ; import { jspack } from "jspack" ; import { performance } from "perf_hooks" ; const upper = ( s ) => s . toUpperCase ( ) ; const colon = ( s ) => s . match ( /(.{2})/g ) . join ( ":" ) ; export function fingerprint ( file , hashname ) { const hash = createHash ( hashname ) . update ( file ) . digest ( "hex" ) ; return colon ( upper ( hash ) ) ; } export function isDtls ( buf ) { const firstByte = buf [ 0 ] ; return firstByte > 19 && firstByte < 64 ; } export function isMedia ( buf ) { const firstByte = buf [ 0 ] ; return firstByte > 127 && firstByte < 192 ; } export function isRtcp ( buf ) { return buf . length >= 2 && buf [ 1 ] >= 192 && buf [ 1 ] <= 208 ; } export function reverseSimulcastDirection ( dir ) { if ( dir === "recv" ) return "send" ; return "recv" ; } export const microTime = ( ) => BigInt ( `${ ( performance . timeOrigin + performance . now ( ) ) * 10000 }` . slice ( 0 , - 1 ) ) ; export const ntpTime = ( ) => { const now = performance . timeOrigin + performance . now ( ) - Date . UTC ( 1900 , 0 , 1 ) ; const div = now / 1000 ; let [ sec , msec ] = div . toString ( ) . slice ( 0 , 14 ) . split ( "." ) ; if ( ! msec ) msec = "0" ; const high = BigInt ( sec ) ; const v = BigInt ( msec + [ ... Array ( 6 - msec . length ) ] . fill ( 0 ) . join ( "" ) ) ; const low = ( v * ( 1n << 32n ) ) / 1000000n ; return ( high << 32n ) | low ; } ; export function random16 ( ) { return jspack . Unpack ( "!H" , randomBytes ( 2 ) ) [ 0 ] ; } export function random32 ( ) { return BigInt ( jspack . Unpack ( "!L" , randomBytes ( 4 ) ) [ 0 ] ) ; } export function uint16Add ( a , b ) { return ( a + b ) & 0xffff ; } export function uint32Add ( a , b ) { return ( a + b ) & 0xffffffffn ; }